QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4142|回复: 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实现人脸捕捉与人脸识别(照片对比)/ p. I3 j# q# q3 A2 i

    : s( c3 M& y5 f9 R3 l+ Y$ u1.安装包依赖
    5 m: B( D5 x, j+ D7 k与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。! S( f+ a1 @* b
    # W1 w6 H* c6 p9 E# [# i
    在python 3以上版本tkinter是环境自带的,所以这里不需要安装" M  ]7 Y& z6 A+ \

    2 a' ~2 J" P' _' [2.代码示例
    % j; y+ }0 h4 X" m* Iimport os: \; T6 X- A+ F# h% p
    import cv2' b  K+ Z! I) _/ j5 Y2 Q5 H, G6 s
    import numpy as np# g& G4 b* z8 M) x( B; _! s. Q
    import face_recognition/ q% |$ |; |! G; k& I+ M9 B( u
    import tkinter as tk  - N$ i6 m/ o4 K
    import tkinter.filedialog
    & G7 Z' M/ X5 H% a5 n( Gfrom PIL import Image,ImageTk : p+ |  B5 a! {* [8 V5 r
    ; ?/ J2 w- a, i' f
    classNames=[]
    2 D# h4 E  z) A+ J+ m; Z* c7 nimg_path='Picture'
    " |  Z( u4 B' {, U3 G' Eimg_recognition_path='Recognition'& D! N) d' E0 \8 [+ }! ?
    existsEncodeingList=[]
    " n) b' v+ E% ?6 H  c9 c# G#对人脸集合进行编码进行处理2 i# \2 X, @# ^& c: y
    def findEncodeings(images):
    - q5 \) N8 N& Q8 [+ O: [! {    for img in images:
    * B* ?4 S8 u) A" p/ [. j        #灰度处理
    ; s$ C" I* Z* ]5 t        img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)
    & o9 h2 R% b' z, f5 R$ R$ E        #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果/ Q6 k& S4 @5 |3 K* T: s* h
            encode=face_recognition.face_encodings(img)[0]
    1 C6 n) {" z6 Q# e        existsEncodeingList.append(encode)+ ^6 y$ I$ j/ Q6 V- A

    % \- N9 c0 K$ y2 u0 U#获取当前存储的人脸编码集合
    9 L" J9 a' A( w2 K9 pdef findExistsEncodeingList(img_path):/ J. d8 w  A/ a
        images=[]3 _7 M/ D( Q9 F  b: [+ i7 B  u
        #列出已经上传的所有图片( w, V! s1 ~) r8 g+ ]
        imgList=os.listdir(img_path)
    ) R" H4 g2 M% |% j5 [  l) S& O6 @    #处理存储的图片得到其人脸编码
    ; B9 G3 s0 a' w. ^) M7 r    for pic in imgList:4 }" M+ T  Q2 \2 h! j
            img=cv2.imread('{}/{}'.format(img_path,pic))
    # X! L' t8 f6 N( L7 [. l0 H        images.append(img)
    & h( C0 k. o. m' j" p; j& l+ N9 T        classNames.append(os.path.splitext(pic)[0])
    ! o- e0 Y9 a1 n5 j% B, L    findEncodeings(images)3 r* E: n# G( K5 Z3 q/ d0 S6 ~( y
    $ b) X+ l! ^( {4 A( P
    #选择并对比图片
    * h; F5 ~8 ]2 h& f( x0 V' N4 ~def choosepic():
    - `1 K) Z  }. `! U( U! W6 a    choosepath = tkinter.filedialog.askopenfilename()) M. B$ |; f2 a6 q4 E  }/ `# \
        path.set(choosepath)2 K/ Z; T) u* j7 R2 J/ G
        img_open = Image.open(entry.get()).resize((530,750))
    4 _: [, r/ k. a2 C6 d    img = ImageTk.PhotoImage(img_open)
    - b" Z' \. P' k% {# @/ o' l3 ?    lableShowImage.config(image=img)% Y: I+ q% O9 z2 G9 D
        lableShowImage.image = img6 _" F& ^4 B8 U  k3 k* }
        lableShowImage.place(x=30, y=70, width=530, height=750)
      J( d, t% m8 g' k    faceRecognition(choosepath)
    6 C  M* }1 g( r' n& b2 w
    1 i0 u1 U# A! h% v  i2 y  ^def faceRecognition(choosepath):
    - r1 x: H( e" b" r. r    frame=cv2.imread(choosepath)) d5 l! C: x0 i% |1 a! _
        frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)- `" q$ P% ?- n8 O6 F! p
        #对摄像头读取的检测人脸9 W" a$ p8 A% ^9 f
        facesLocate=face_recognition.face_locations(frameRGB)" ]: P- h5 f- D% ^- ]2 ]  ~$ ~; m
        #进行特征编码5 a1 k) L  ~7 `2 B
        faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)8 J" E0 R  b3 x
            #遍历检测的人脸和库中读取的图片进行对比,计算其相似度
    * b- H" ^% b. ~1 @    name='unknow'
    : B. H3 M7 C& l5 X    for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):4 A0 n- f  l3 B$ }- u8 k) h, U! W
            #进行匹配
    , K/ T, f5 ?' M6 t  o& a7 |2 R& |; L        matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)
    ( q* h' c2 L+ e' U3 j        #计算相似度
    # J# j$ o3 J, P* M* B        distance=face_recognition.face_distance(existsEncodeingList,face_encoding)+ ~& B! n/ E% C3 h9 h8 ]2 I" h
            lab='unknow'
    ; H8 b) M4 _! W1 u        for index, item in enumerate(distance):
    9 f4 F0 [6 M* F5 s3 C1 v           if item<0.5:
    * n6 _% C' W/ m; R, I' o4 _6 A$ P                if matchs[index]:
    ) P" u! ^5 d, s! T, k  A  t. y                    #得到匹配到的图片名称与相似度值7 c9 {7 d3 b0 u5 }. O
                        lab='name:{}; Similarity:{}'.format(classNames[index],item)' i  d* k# u- f. U# W% }
                        name=classNames[index]
    : [6 P" ~' d" w                    break
    / u7 e4 @3 A7 L" G        #初始化面部捕捉框显示绿色1 W, z) P' z/ t9 e# P
            color1 =(0,255,0)1 s/ y6 h  t# k* x
            if name =='unknow':
    1 R. p8 [& t+ s9 `            #未能识别的时候显示蓝色% b% s" B: W6 ~$ W+ @
                color1 =(255,0,0)
    ! h6 g; y+ x' z5 d6 |7 Y# l* |        #画面部捕捉框$ Z1 |% X- y1 `; G4 O
            cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)$ A" S) ~) V, y* R, ~, p' ^
            #在捕捉框上添加匹配到的图片信息
    : F# C/ W, W* C        cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)
    % ]8 M+ w7 n2 I  I9 z) f: t# A) l        cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)8 Z; o& i. q) o, Q/ ~# n# [, w
        img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))
    7 V4 [, B* b7 ~9 U, u# ~    img = ImageTk.PhotoImage(img_Recognition)
    + d7 `  J' m! Q    lableShowImage2.config(image=img)  m. C7 i) C4 y& }: F+ m
        lableShowImage2.image = img
    * _3 J4 p( \5 d( P    lableShowImage2.place(x=630, y=70, width=530, height=750)
    - L9 o7 P. L8 n  F
    ; L& r9 \5 f$ v! _4 H9 Yif __name__ == '__main__':8 R, d7 g" ^) Q. i! w5 \, F+ }8 i
        findExistsEncodeingList(img_path)6 R) R( h$ t/ z3 U4 L3 w
        #生成tk界面 app即主窗口
    / K7 }6 c+ [2 ]; A  ]    app = tk.Tk()  
      A9 o  X0 C7 O, a    #修改窗口titile
    ) ?) I, I- d8 |; R- l; N    app.title("show pictue")  
    / j" c5 C9 B4 N/ [    #设置主窗口的大小和位置
    3 F0 Y/ a' J* o8 [% B. |5 i& c% x" l    app.geometry("1200x900+200+50")
    6 c, F8 Z, J9 v* y. E" `6 S2 g    #Entry widget which allows displaying simple text.
    9 H, k6 }$ m" N" V' b3 x. `    path = tk.StringVar()  Z) h& q& M3 b; H, A* _$ ~
        entry = tk.Entry(app, state='readonly', text=path,width = 100)
    2 V! G. Q4 d, q2 ~! N# y" P    entry.pack()0 c' |+ h! p. H" A
        #使用Label显示图片5 a* ~) ]# {" ?- S4 o
        lableShowImage = tk.Label(app)
    , M) h4 m# [' P: H: v* R    lableShowImage.pack()) K4 n0 d  i( L$ J4 D: c( x
         #使用Label2显示处理后的图片# d/ `9 V1 s/ a/ s8 b4 l
        lableShowImage2 = tk.Label(app)- h, g% }7 `3 g' `
        lableShowImage2.pack()+ b/ k* d2 x+ l2 {+ C8 _7 ]
        #选择图片的按钮, i# |: j0 H9 y) {; j* p' i
        buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)
    7 B3 H% \$ H& |    buttonSelImage.pack()
    ) G& `4 \( ~: E3 A4 }4 S    app.mainloop(); ^. s  _+ a; I5 A5 _3 @) Z% k6 e
    / z2 Q  w$ S, r: g5 h( \7 i% N- m
    3.说明
    9 N' L3 ]5 i; D$ J: @, V) L首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。' l% s/ N. L0 `

    # R. a7 U5 `2 N3 |5 F9 U
    : d9 n5 Z5 ~, X" c1 C. Y4 o# M: \- F6 r5 J- c: h- m
    其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片' u0 s6 g  u8 N3 T; a+ U
    2 h9 W) W+ P/ h; m  p* v% K# @1 `

    ' l8 f. z: \9 L! l) j3 q* n
    ! O8 p! ~# i9 ^3 y. z) I 但是效果会存在色彩的失真,效果如下:
    - F6 E2 N( A) l: l# }6 f; x' a6 D( g+ J; B0 c& p/ A& H
    - L) T+ E' e! O6 h0 S( _* _

    # m: c3 }& A( p也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。- ]6 k* }6 v& a* q, q

    6 V' ~! T) T; y7 k4 \4 Y2 p, ~这里简单提下PIL的九种不同图片模式:$ Y5 k8 B, P( I6 s& D! K. \

    8 t% E% P. w& M5 {modes        描述
    + X* u9 k0 a1 i, [8 w$ f! M4 ]& f1        1位像素,黑和白,存成8位的像素' B. D& _4 K$ R7 l
    L        8位像素,黑白
    & A* j5 s2 k+ {7 l. s  HP        8位像素,使用调色板映射到任何其他模式
      _8 r0 T' Y* U. n: d& LRGB        3× 8位像素,真彩/ }% e- h% x  V
    RGBA        4×8位像素,真彩+透明通道
    2 _4 f8 |5 B7 Y) Z! S$ ~8 o, d1 GCMYK        4×8位像素,颜色隔离+ C* T; o0 J6 P4 T
    YCbCr        3×8位像素,彩色视频格式/ \  f" O. _  U2 ^+ H- v9 N
    I        32位整型像素
    9 H/ ]) q# W' ^' j2 A* W5 l$ @3 ?F        32位浮点型像素; _8 n+ k9 u& d% q
    4.实现效果
    ( ~) g6 I7 \; O8 f; q# K! X0 d# [& {" x2 k! s7 K* A

    2 g6 Z) T- u6 I; [5 U% [, V1 G6 y  V; o0 A3 Q

    3 a8 O1 k' ^5 D7 d! h+ }5 c' w 可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。- G& P- [& t* l% _) v
    ————————————————
    + Q- m7 Q& T: L; F/ `版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    . S5 U7 Z/ H" W原文链接:https://blog.csdn.net/qq_17486399/article/details/1266292884 n5 A" J) H) \

    ! ~, ]7 M) `& W! I6 k0 d% Y% n+ m" r9 }/ o
    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-4-9 23:12 , Processed in 2.143933 second(s), 50 queries .

    回顶部