QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4277|回复: 0
打印 上一主题 下一主题

[其他资源] Python 基于OpenCV+face_recognition实现人脸捕捉与人脸识别(照片对比)

[复制链接]
字体大小: 正常 放大
杨利霞        

5273

主题

82

听众

17万

积分

  • TA的每日心情
    开心
    2021-8-11 17:59
  • 签到天数: 17 天

    [LV.4]偶尔看看III

    网络挑战赛参赛者

    网络挑战赛参赛者

    自我介绍
    本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。

    群组: 2018美赛大象算法课程

    群组: 2018美赛护航培训课程

    群组: 2019年 数学中国站长建

    群组: 2019年数据分析师课程

    群组: 2018年大象老师国赛优

    跳转到指定楼层
    1#
    发表于 2022-9-14 17:07 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta
    Python 基于OpenCV+face_recognition实现人脸捕捉与人脸识别(照片对比)
    ( c9 |1 S4 T) p1 T8 g0 ]7 J# Y% x- g  D- o  J
    1.安装包依赖
    8 ?( W- Q! u$ b# N/ _% {) ~6 ]: L与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。
    * H! D0 K! n* u3 N- O& e. d* \
    : P! H6 d0 |* h  T在python 3以上版本tkinter是环境自带的,所以这里不需要安装
    # Z; w# h/ y4 p( {, l' T# w0 I
      d! E6 R/ `" R0 h" ^  J! [/ ]2.代码示例
    & C' \6 W  N. y2 Y6 o$ z* Mimport os4 k0 r# s3 @! y* q# l4 C/ {
    import cv2
    1 }% ]: {1 I3 Wimport numpy as np
    ( x& G  A: z$ j1 n! J  Simport face_recognition
    0 c, A8 r& J; @6 F9 c3 o( iimport tkinter as tk  $ f2 H: D! S& P5 y
    import tkinter.filedialog# Q: ^+ Y' f9 d9 J
    from PIL import Image,ImageTk , F. I1 Z, k3 G

    / Z, _( s' T& P; `- ?) T8 HclassNames=[]
    7 J6 ?; Q( u0 ^- ^* jimg_path='Picture'
    # m. S: Y( V% M* o' E& y' fimg_recognition_path='Recognition'" _7 P. v* ^* |% V# E2 D
    existsEncodeingList=[]% s: B6 @% S2 E9 H
    #对人脸集合进行编码进行处理  U3 P" \7 `" r5 W0 W; @4 ]
    def findEncodeings(images):
    & a- V7 q2 ^' I# v: @+ u    for img in images:
    : @: l2 K! S; a% n        #灰度处理) A& ?' N6 ]$ ]; s
            img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)1 H$ k$ X, V6 R" H0 a7 N4 k4 m' L, S
            #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果% u+ Y+ E. u7 N) J6 J- p+ E! \. ~! H/ L
            encode=face_recognition.face_encodings(img)[0]: Y( `2 h# E, `& ?( c5 p( Y
            existsEncodeingList.append(encode)3 L9 j! L, e& ~

    / _. `- i! ~) V2 t#获取当前存储的人脸编码集合; Q  n$ d" t1 O1 y! q4 C) W2 ?
    def findExistsEncodeingList(img_path):% V# E5 P) `# I
        images=[]8 m, C( ?. c  [+ \5 h
        #列出已经上传的所有图片
    ; p' `" b! S3 {6 g  w    imgList=os.listdir(img_path)
    9 ~! n& M. H# I7 C' S& w" K    #处理存储的图片得到其人脸编码
    : F( g7 V, q( W4 R1 j; ~1 p    for pic in imgList:& Y+ h5 X9 A1 T# }: X) q( }, x- y
            img=cv2.imread('{}/{}'.format(img_path,pic))
    $ Y9 f  N6 Q& T; {- r# C/ e4 [        images.append(img)0 u! B2 |- q- O" R" {( u9 ~/ N" j
            classNames.append(os.path.splitext(pic)[0])
    ( `, L( n& A' W- u% N2 M: j    findEncodeings(images)
    5 a- d$ e8 {4 a# f' m3 P( a# v1 j" r9 m8 D4 q, d
    #选择并对比图片7 O  k7 B# w* s, _2 Q7 T0 \- W
    def choosepic():% [$ h# c( c6 X3 Y+ ?( I
        choosepath = tkinter.filedialog.askopenfilename()
    " {1 O3 L% B. v    path.set(choosepath)( R$ r, _' N& V% B/ b/ d
        img_open = Image.open(entry.get()).resize((530,750))3 X; L2 a) |4 ~! G% I
        img = ImageTk.PhotoImage(img_open)
    , w! E/ x' J4 e2 ^- G1 g    lableShowImage.config(image=img)
    ) Z7 H$ ^) R8 L    lableShowImage.image = img
    / o: K* e) ?5 S& b% i. F6 c    lableShowImage.place(x=30, y=70, width=530, height=750)' D# F2 {; G1 ]. E
        faceRecognition(choosepath)* X+ x! V  T' p/ D( C

    1 t: i! M7 n% Z* Wdef faceRecognition(choosepath):
    4 m& L% v* o0 u5 ^% A: |    frame=cv2.imread(choosepath)4 s- e. l  x" q( T. {% }5 M% j
        frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
    6 D+ T# i9 Q, e5 ^+ I$ T: q1 R. q    #对摄像头读取的检测人脸
    5 ^4 K- S( v- |5 f    facesLocate=face_recognition.face_locations(frameRGB)
    8 }2 i9 r! C7 {/ t3 {/ \, T/ Y+ ~! k. J0 N    #进行特征编码
    6 B/ J( b# n- r# ~1 e/ k$ w# D    faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)+ f; _$ b- V. C- u# \
            #遍历检测的人脸和库中读取的图片进行对比,计算其相似度
    1 ?8 V+ c6 [( L* o1 c4 f    name='unknow'
    & `! v, \8 C2 h& j8 \$ ~    for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):
    9 e. q8 q: C7 ~" H        #进行匹配0 ~5 ?$ Z; W$ E5 L, a5 ^8 U
            matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)
    . H8 @  M: }! \6 w0 I        #计算相似度
    7 i! a# z7 o6 K/ ]" @2 ?        distance=face_recognition.face_distance(existsEncodeingList,face_encoding)4 h  j2 D5 J& j' y1 ^
            lab='unknow'
    % f) X6 j0 e& v6 u* `        for index, item in enumerate(distance):3 m+ m% w0 T; t; J
               if item<0.5:
    0 k# F% I* ?: A/ n+ L6 Q  E) l                if matchs[index]:
    ( n% C) I. p1 l) N& f7 Y  S" Z                    #得到匹配到的图片名称与相似度值2 O" G! c0 c; G% R# ^, ~8 ~
                        lab='name:{}; Similarity:{}'.format(classNames[index],item)
    0 J+ `* B& t# r% {                    name=classNames[index]
    3 o% Z' g& v* T                    break4 @0 ~+ l" l5 ?  m5 z% a3 a
            #初始化面部捕捉框显示绿色
    3 I' ?8 x7 H9 }3 d+ _' F        color1 =(0,255,0)8 c! _2 c3 p& I; M
            if name =='unknow':! B2 R0 F* T3 a+ L
                #未能识别的时候显示蓝色
    7 p4 u2 \/ K6 H$ o6 L            color1 =(255,0,0)
    & a! G1 \& Y# j) t. m# ~        #画面部捕捉框
    $ i$ y( R% }' A3 z        cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)$ i1 H: c; u0 `* n- j
            #在捕捉框上添加匹配到的图片信息5 m' _, V8 i' L) A* V, g2 k2 w2 S$ m
            cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)
    . Q& K0 L% {. E        cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)* U  O4 i, x/ B$ u4 Q! F, z3 L
        img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))
    # e+ m3 n, b( j    img = ImageTk.PhotoImage(img_Recognition)2 s0 q0 z& |, D1 o1 p, G
        lableShowImage2.config(image=img)
    * b- J# U8 v' W8 ~  ~+ c) _# }2 q8 e3 I    lableShowImage2.image = img
    + V7 Z3 h; ?) u" r- B5 B4 a0 g. {- M    lableShowImage2.place(x=630, y=70, width=530, height=750)# l/ d0 n8 V4 T8 l

    " d1 r* b" j% I' ]) Cif __name__ == '__main__':
    ; E8 t8 O' Q$ Y0 P5 F4 i    findExistsEncodeingList(img_path)
    . T, z, \! h& I# u. Z    #生成tk界面 app即主窗口
    ! ^% L& N; c" S' h6 @( F7 _    app = tk.Tk()  
    $ T' I* a* _5 L4 |, I# T. C4 P    #修改窗口titile3 W8 Y2 M: i' D  p$ j+ j, ]2 f1 P$ q
        app.title("show pictue")  
      T# X: _6 q+ D5 c    #设置主窗口的大小和位置
    3 N2 A( V7 R" R    app.geometry("1200x900+200+50")3 \) Z: L2 j; [! A# i
        #Entry widget which allows displaying simple text.
    5 D' V% V8 T* o( U+ C0 o    path = tk.StringVar()+ l3 B5 V% U  `! g; e
        entry = tk.Entry(app, state='readonly', text=path,width = 100)6 ?" i: d! x8 G
        entry.pack()9 F1 s9 s$ C) L$ A( J1 s0 L
        #使用Label显示图片
    & M9 ~* I& J6 v! K$ I8 u    lableShowImage = tk.Label(app)
    & j8 c/ D* d4 B7 a+ g, e# l    lableShowImage.pack()
    * [: O$ ]0 k) N, ^     #使用Label2显示处理后的图片
    / S" p  S2 i9 h4 f4 ]    lableShowImage2 = tk.Label(app)% U% z. t; J$ }# ?: g
        lableShowImage2.pack()
    : o; x0 ]! d+ |9 m, k. }/ Q    #选择图片的按钮
    0 O& O; V8 i) v1 Y    buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)
    / v' H6 K$ v8 ?    buttonSelImage.pack()
    % m  P- ?# f% T5 S    app.mainloop()
    ( ~" J0 s2 `4 Y  M+ k+ ]" P4 A. u8 p% h1 `' V+ t. ]! ?
    3.说明4 |5 H' e) \  w9 H+ p$ l
    首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。8 O* X% G0 k; D0 Q

    9 Z1 D8 v. J$ [( U
    : X. W1 b% D. X2 N% j; F) g( t8 k& {: J6 y5 i7 e- x; g
    其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片
      u0 D8 z4 I8 z) @) x5 W: X( A1 g; v  o9 O* c# x

    7 G' Q* {8 m% b2 K8 k
    ; ]/ m0 e( G9 P* v0 K. }5 g; s! Z  U 但是效果会存在色彩的失真,效果如下:4 p- C% H& `; M1 y/ p' k( Z
    , ^, f5 g! @6 `8 o9 q. m
    : w2 h+ V3 N) l, k

    - L1 O  O0 \2 ?, g也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。3 d( o- S9 w9 _7 y; z

    1 n4 I" w$ R/ ]  J3 L, n% s) }这里简单提下PIL的九种不同图片模式:" U& _! R0 y* M! S" J% j1 a" l  r, o

    7 e2 }4 B( ]! M2 Nmodes        描述
    ) p# O; H% X, C4 Z( v" S$ i1        1位像素,黑和白,存成8位的像素
      E5 Z- P( x% M! }L        8位像素,黑白; p2 c! z" A( J
    P        8位像素,使用调色板映射到任何其他模式
    3 Y; @& T5 R6 g% q& m& `3 k+ r" w6 VRGB        3× 8位像素,真彩
    ; {4 s* Y& Y1 E& j7 URGBA        4×8位像素,真彩+透明通道
    + S7 f; W, o7 i. H, u8 e# n) MCMYK        4×8位像素,颜色隔离
    7 w/ y' l4 S  c/ bYCbCr        3×8位像素,彩色视频格式8 }8 T8 N: `+ V
    I        32位整型像素
    * h: [7 t& S1 ?/ d9 O1 ?2 EF        32位浮点型像素
    9 I1 c& x# A8 _8 O; o: i2 ]" _5 U# S4.实现效果
    $ `9 Q  J5 a1 N( v- r7 A$ x& N
    + e, L! ^% E. P% V
    ; F1 B9 d! G# w1 A' z
    * l% C5 ?% l8 l" a4 J; n3 Y  H+ Z5 C
    可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。
    , u1 ~! C. a! y6 _5 t————————————————
    5 I) t- }0 t* c" @- f3 q* L版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。( L6 C% Q  s, X& G
    原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288
    . a' T) x( V  I% A
    / E& v0 R/ p6 r$ x, H0 H* x* P- n- R8 L; I# w$ I3 [
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

    关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

    手机版|Archiver| |繁體中文 手机客户端  

    蒙公网安备 15010502000194号

    Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

    GMT+8, 2026-10-8 09:42 , Processed in 0.561371 second(s), 51 queries .

    回顶部