QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4279|回复: 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实现人脸捕捉与人脸识别(照片对比)( P1 \/ S' b' c  A1 R3 L' T/ G# t
    % H, J: Y- S  @& o) t9 M# v
    1.安装包依赖, n: u( X! j6 @2 g
    与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。
    9 X3 u! v" D3 L* e$ m
    7 Y/ Y% _0 G! j在python 3以上版本tkinter是环境自带的,所以这里不需要安装) T- u7 K9 t  |8 ^
    . q* T" [1 i) Y, I8 L& v. X& k
    2.代码示例
    & @. p8 b8 e, a% J! w. K+ ~5 fimport os
    / J0 c8 ^. r/ ~! j4 [& A- \3 rimport cv21 d- f0 g* Z- E3 f5 J
    import numpy as np( L( Q/ X  {# ~" i# B! @: _
    import face_recognition
    . R7 s3 g7 W% O* `2 y4 aimport tkinter as tk  ' Y- ~2 W8 y9 b, P2 t- a
    import tkinter.filedialog
    4 d; I2 c6 |# N1 U0 z% `from PIL import Image,ImageTk 5 G" s9 D7 F/ i% j

    5 q( o2 O3 W2 a' @; ?0 `9 H4 DclassNames=[]
    1 \7 A! d( ~9 M- n" cimg_path='Picture'0 I$ S: k! J0 k1 x
    img_recognition_path='Recognition'
    , t6 c# ~0 k+ i% m) |existsEncodeingList=[]
    % D7 c& G( I, R* m* h#对人脸集合进行编码进行处理5 I  a# v( Y: j; [6 y7 V4 s
    def findEncodeings(images):
    . V- t+ B3 v  h! I    for img in images:
    ' N8 Z/ i& L+ q) U+ ~& S4 i        #灰度处理
    0 u2 x) [( n$ X# T- a        img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)
    * e7 P7 t8 d8 g9 _" w3 r        #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果7 H" W/ j1 ^0 b9 @* _: q  I2 `
            encode=face_recognition.face_encodings(img)[0]- q6 w3 Q, J- J. o
            existsEncodeingList.append(encode)% ^6 J, P3 D2 P! C5 z; t9 {# @0 a- X

    1 k) Q* E1 h/ c! c' X. ]2 E( W#获取当前存储的人脸编码集合
    % h9 f# V# F" Udef findExistsEncodeingList(img_path):1 T& {! T+ r( m1 Y5 n0 o2 S
        images=[]: T3 i5 V) B/ A0 O; i) }% s& c1 O
        #列出已经上传的所有图片
    % ?3 a* @  Y8 }9 g2 I% r0 L    imgList=os.listdir(img_path)- ^- }$ m2 Z" z1 {0 ^6 i# o0 \
        #处理存储的图片得到其人脸编码2 j* f3 t& y7 N2 T2 o+ S& [2 O4 `
        for pic in imgList:
    & r' F$ ^) H3 u        img=cv2.imread('{}/{}'.format(img_path,pic))
    1 X  J$ Z0 ?' b# P3 {        images.append(img)
    $ y$ |% k# A& m! l2 O+ n) o        classNames.append(os.path.splitext(pic)[0])2 t# b/ y) o3 z3 L7 y, b( F
        findEncodeings(images)' z) Z' V8 \3 u3 S) R4 k- l
    ' M  _* F9 T& @- m8 a
    #选择并对比图片( t2 J$ K+ F) |$ Y2 A
    def choosepic():
    ' _2 I6 ~4 ^' B    choosepath = tkinter.filedialog.askopenfilename()
    - v7 c- k: N$ b- e$ N    path.set(choosepath)' f* o0 s# R3 z0 h& J# G' k
        img_open = Image.open(entry.get()).resize((530,750))) W" t- F2 k) _/ C6 ~, K# T
        img = ImageTk.PhotoImage(img_open)! Y; H- T" `# I9 l# C
        lableShowImage.config(image=img)
    1 w7 L" f# P( C- F    lableShowImage.image = img+ T5 u( Q2 ~4 ]: w0 m: b7 m  `
        lableShowImage.place(x=30, y=70, width=530, height=750)
    2 ?) R/ M' Z& Z! R) s; R    faceRecognition(choosepath)% \6 k0 d5 ^7 `- ?
    : V# f6 J. J7 ]+ K7 y4 w4 `/ G+ I
    def faceRecognition(choosepath):2 _; n' U6 ^$ m! u9 h) R& L
        frame=cv2.imread(choosepath); L# P0 k, D3 |% X
        frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
    " `+ {1 }. p1 R/ q# _6 ?    #对摄像头读取的检测人脸( F$ ?( O0 K5 i# L& v# F  }
        facesLocate=face_recognition.face_locations(frameRGB)3 w4 W( n6 B! J  ?% ^7 r& i2 Q" r- x
        #进行特征编码
    8 b$ f; s6 d# X& o5 m3 |. p    faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)) J0 `: a: [* V* _  a
            #遍历检测的人脸和库中读取的图片进行对比,计算其相似度$ q  D: F# V! U* `
        name='unknow'
    ; V( m, n: f: z# Z  B  r    for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):; X5 m4 J+ y9 \0 F: _, W2 T
            #进行匹配
    2 K9 S  P% l" N5 L. ~$ X% u9 n        matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)
    # o* s- Y- ]3 q8 M4 ~' x( n) f! ]        #计算相似度
    7 _1 b. r: R4 _: [3 E8 x5 o) E        distance=face_recognition.face_distance(existsEncodeingList,face_encoding)* t/ U( R! [+ q7 o5 Q& _
            lab='unknow'
    . i) U/ P3 L0 Y7 I4 o* P$ S        for index, item in enumerate(distance):$ T# `2 ?; I9 s, O
               if item<0.5:2 ^+ A; b/ f# f8 v
                    if matchs[index]:/ S/ G" r, G# T' |+ O0 ]
                        #得到匹配到的图片名称与相似度值2 y$ d1 G' D& Z
                        lab='name:{}; Similarity:{}'.format(classNames[index],item)" q  [" \7 F4 V) h
                        name=classNames[index]
    3 |2 v& V  `% |7 c+ V, n                    break
    2 ~5 ^5 ~# f+ `; K8 i. c. \7 x        #初始化面部捕捉框显示绿色. g$ r& C; a( M- ?
            color1 =(0,255,0)! I1 p: ], u# j3 n
            if name =='unknow':) m; m. k& S( [) _4 f
                #未能识别的时候显示蓝色
    : K4 }# u) p# s/ ]* Z' z* l' I            color1 =(255,0,0)% J, i8 k! @1 E+ R2 U6 N1 g5 J
            #画面部捕捉框
    9 B* o; P7 L% J$ _3 R        cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)+ D6 D! a/ q* d
            #在捕捉框上添加匹配到的图片信息1 [* J+ G8 g& Y
            cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)+ X9 }+ ~' v% @4 g
            cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)
    ( e! }7 o( \/ o; @$ V7 v0 V: R    img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))
    + B% b" E; e7 q" R2 x4 \: D. r9 s    img = ImageTk.PhotoImage(img_Recognition)
    : S: v1 I& a/ C7 F' O    lableShowImage2.config(image=img)
    % o, G& k( x9 Q/ e1 a( r# I    lableShowImage2.image = img2 P/ o  D- B! o% v* @
        lableShowImage2.place(x=630, y=70, width=530, height=750)
    * T1 \: U0 _9 ^% A0 Z& w9 \  Y/ M: R3 R% r' `$ q
    if __name__ == '__main__':
    ) a5 }( }1 K' `5 W    findExistsEncodeingList(img_path)& y9 {% t2 R& i
        #生成tk界面 app即主窗口
    8 ?7 D1 C* ^# f7 L0 t9 q- t    app = tk.Tk()  
    8 y3 W" J/ ?: f; e1 b6 R    #修改窗口titile9 F( n& b6 J" \
        app.title("show pictue")  
      F9 ]# Q6 M. r& ^4 m4 c    #设置主窗口的大小和位置
      c4 {& v. V& U$ D    app.geometry("1200x900+200+50"); ?8 Z5 V# z& e8 c; l# O( K
        #Entry widget which allows displaying simple text., i8 @8 C+ `0 S5 G  ~6 w
        path = tk.StringVar()
    * ^. n7 K; j! e; u) ~" G    entry = tk.Entry(app, state='readonly', text=path,width = 100)
    2 }- z3 E- A5 f5 U! @/ I    entry.pack()
      d5 f+ ]4 Z$ L/ b8 u    #使用Label显示图片
      Y) h6 T4 j) f4 ?: V4 F    lableShowImage = tk.Label(app)2 H0 W( `/ u9 h5 w/ D8 f
        lableShowImage.pack()) u6 r# T* J% p
         #使用Label2显示处理后的图片
    9 z5 [$ V; W" E9 X$ i4 P5 W' J7 s    lableShowImage2 = tk.Label(app)
    & b7 K; w- m, Y( ~4 X    lableShowImage2.pack()% J& F1 p% U) A" d: ?/ A) k
        #选择图片的按钮
    2 G4 X2 I, P4 @+ v9 R( c- Q    buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)
    * }& _! m# I4 K4 t    buttonSelImage.pack()) b. A5 Q7 X' j/ w- D0 g
        app.mainloop()- U2 U$ d: T. z: u9 W

    0 ~' Q1 I& \) `* `. m3 M3.说明1 v+ ^# h, _2 {3 @, y; ^/ M% M
    首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。
    $ M; X( D- h9 U8 k; t3 |6 P3 M; J7 @0 V$ l9 h1 ~

    # i8 b/ l% `5 n: ~0 V& H& p
    : R. P' ^/ ~1 }( i7 t  p4 b 其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片. r- s/ R$ c; Q! x* O- X
    % [: r' {) L" @& W# ]3 J

    6 k' D+ l: z/ y/ L+ u! P9 V
    3 b. U4 B- [; o' |# O! E5 L9 i. j 但是效果会存在色彩的失真,效果如下:2 d- D1 z- S% L2 m
    0 o; N  d: u6 u4 \
    6 g  j+ S; }9 l* N1 T. i

    ! f' z8 ?' H9 u) V+ p也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。; ^# g5 [. x0 e  c* L% i8 Y
    ' [5 B3 d6 m! _9 g' ^5 x/ e! A
    这里简单提下PIL的九种不同图片模式:
    ) N  j7 X7 S, z8 a4 t5 ~2 o4 ]9 j( v% [( N( B9 `
    modes        描述
    9 P/ Z9 G; r9 U: W# O1        1位像素,黑和白,存成8位的像素0 P, _( C! e7 k/ [% o6 W
    L        8位像素,黑白
    ! Z  Z8 I0 N4 c( RP        8位像素,使用调色板映射到任何其他模式
    ; }$ l/ C- Y  K, sRGB        3× 8位像素,真彩& d; C; g- y' g6 o: @$ p
    RGBA        4×8位像素,真彩+透明通道. {" j+ u7 @; ]0 n& z8 T' e
    CMYK        4×8位像素,颜色隔离
    , L% t$ D0 m) p" c$ F0 VYCbCr        3×8位像素,彩色视频格式5 A- c  v! f8 ^" Q) h. `& z2 f9 B$ a
    I        32位整型像素9 l. ~3 [0 Y# c+ v* w$ Z7 o! d
    F        32位浮点型像素
    5 J+ ?- O. M  ?2 Z6 ^2 Q4.实现效果1 Q! {% G- \, g' W5 n; F
    % w2 ]; m2 |3 ^4 Z
    ) }7 [# Y5 x. O& S9 k: U

      h. M& X; a8 L0 o. [
    " B* I6 t- K/ U2 l 可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。
    & d6 K$ f0 }8 u4 f4 l; [1 N————————————————
    ' t  L5 [% \# }版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    ' B; n$ k! X9 ?8 D3 V- a原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288* n( A: B# u' Z7 s& X$ L  S
    : J! @7 z' }; {, S* B( X
    8 S# x1 s( ~( `4 s* h1 f7 v
    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-9 09:38 , Processed in 0.337125 second(s), 51 queries .

    回顶部