QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4171|回复: 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实现人脸捕捉与人脸识别(照片对比)0 l0 _4 p) p1 O4 \- n- R- k: s

    * Z( I+ g6 J) K, S+ l1.安装包依赖$ t; N& k4 Z2 o: i( _
    与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。+ p, \3 ^- ], \& o  Q; ]! l" c5 g

    6 X- F* Z" S$ t+ I4 ]5 n# B在python 3以上版本tkinter是环境自带的,所以这里不需要安装
    1 ~8 G2 }0 a/ e0 j) ?, h8 l  \) g* Q& B/ K. P, U
    2.代码示例
    ! U6 W; c: [: d  ~9 h9 `  Wimport os" e$ Z" d. I0 K9 I+ R# o
    import cv2
    4 j' Q- }# o, I7 N2 C' R7 L2 \import numpy as np' ?% ^6 s) a; M' Q
    import face_recognition* X; n( a' J/ S+ v  I
    import tkinter as tk  2 _! U0 [: q; E
    import tkinter.filedialog
    ! p. c, J) j# K# Jfrom PIL import Image,ImageTk + q8 M4 H- S+ n) w  `& ?1 d4 j( r
      B1 X, o: J$ S* N6 l+ w- ?! M
    classNames=[], t) U4 T' v0 X8 }( S, o9 ?
    img_path='Picture'4 ^: T) @  m, [$ |% M8 ^- E
    img_recognition_path='Recognition'  x8 r* B, t9 n8 h, J5 ]' X2 M; n
    existsEncodeingList=[]$ s5 |1 o8 F  P' H$ w! W9 y; X
    #对人脸集合进行编码进行处理' A3 n+ r# m' z1 f% o
    def findEncodeings(images):
    ' l+ G4 E$ o, B* s1 w, n    for img in images:' ]/ u6 V! U4 j
            #灰度处理
    & t7 F  u& v/ h1 z        img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)
      R. c4 N2 W; a2 S        #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果  t" H* j8 S: Q' \$ R9 s8 Q
            encode=face_recognition.face_encodings(img)[0]+ B) Z* u' M7 |8 S: m) S, ~7 O
            existsEncodeingList.append(encode)6 e# o- X! U, v  ]1 f
    % c+ P) Q% P: n
    #获取当前存储的人脸编码集合6 o. w  x8 v! \) V" y6 `. J
    def findExistsEncodeingList(img_path):
    3 w0 }; V: n/ c    images=[]
    4 L+ N. v1 R+ t' v. T    #列出已经上传的所有图片
    ( e* X( O1 U7 |) ?4 z    imgList=os.listdir(img_path)
    3 u) s4 x- e4 P* V' K' j    #处理存储的图片得到其人脸编码
    7 N: C8 @* p* y& l3 u) f) |" p    for pic in imgList:
    1 x. E1 _2 u6 G2 t1 h+ @9 ?        img=cv2.imread('{}/{}'.format(img_path,pic))
    , G3 z) c8 h1 |$ M* d6 Q, z        images.append(img)9 f9 g" l$ j1 {; z" ^8 L
            classNames.append(os.path.splitext(pic)[0])+ y5 r6 t2 X% ^1 u; f6 k+ V
        findEncodeings(images)
    $ p0 S& z: G9 x! y  O9 u" ~. v* Z! G$ g. S; t
    #选择并对比图片) d1 i3 N7 U3 N3 @8 F
    def choosepic():! c$ b- r9 q4 h/ r8 C9 u8 {  y
        choosepath = tkinter.filedialog.askopenfilename()
    : i8 a2 @1 B7 z. E    path.set(choosepath)8 P5 |# s9 u* g# b4 @
        img_open = Image.open(entry.get()).resize((530,750))9 Q$ d# z9 F  O2 z- F2 V) W
        img = ImageTk.PhotoImage(img_open)
    & Q2 D7 K4 }2 C  R1 L( c& X% |    lableShowImage.config(image=img)+ w  u/ T% k) r/ Y1 i) ^
        lableShowImage.image = img4 P) u8 V# B2 m3 L( Z
        lableShowImage.place(x=30, y=70, width=530, height=750)
    ; d4 O8 t, e3 Z7 Q- `    faceRecognition(choosepath)
    $ _0 ?6 |2 a% \3 u1 ^3 o& U4 j, E9 [7 b+ L% T
    def faceRecognition(choosepath):
    5 b; O* j& k% ^# u  I" }/ O4 i    frame=cv2.imread(choosepath)
    ( a' E3 z8 [# {2 z+ G! L    frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
    3 T9 D3 c) ~' a* g, l+ c    #对摄像头读取的检测人脸$ o9 x5 ~3 D4 g
        facesLocate=face_recognition.face_locations(frameRGB)
    5 i: F+ H( c  U7 o    #进行特征编码
    & T$ p* p. K5 W' i3 @3 w7 Y1 W    faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)% s6 D/ D3 M* @
            #遍历检测的人脸和库中读取的图片进行对比,计算其相似度
    - C6 p1 e( {/ u. g+ i, R1 n2 @    name='unknow'
    % u+ ~+ y, f. H* h" @    for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):- w( z  {6 r0 `) ]
            #进行匹配9 y/ q$ \. r- R" G
            matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)7 l/ ^' S2 @& {+ q& @2 H
            #计算相似度
    9 y: V8 P3 Y; C1 z, u        distance=face_recognition.face_distance(existsEncodeingList,face_encoding)
    ( }1 Q1 M3 c% ?+ t! `, ?" L        lab='unknow'
    5 i; C5 R8 P  }) z6 M4 I        for index, item in enumerate(distance):
    $ \, y" ~  ^: `- \3 u           if item<0.5:) D0 L, }+ |$ v' I
                    if matchs[index]:
    9 c0 Z- ~% g' N; }( L8 ^' m5 j                    #得到匹配到的图片名称与相似度值9 i- M0 I  X+ Q4 u& ]
                        lab='name:{}; Similarity:{}'.format(classNames[index],item)
    * ?$ x8 H7 g. F                    name=classNames[index]
    7 g" [' V5 t4 g/ Z* t  j( C/ n$ A                    break
    - x. [9 ^- ~  s- ]# S# `        #初始化面部捕捉框显示绿色1 T( c! k. r' Q6 ]9 D: ]
            color1 =(0,255,0)
    * Y$ `; Q8 f* R3 U$ v        if name =='unknow':
    ! a& k2 `7 \' g! X* c! x6 u            #未能识别的时候显示蓝色
    ( F' m- U- t* R            color1 =(255,0,0)
    9 V% \" p% g) [$ }! u* T        #画面部捕捉框
    7 q, f) U* w, F( T+ j/ _        cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)9 I) M4 [: @' C$ J2 S  n3 C
            #在捕捉框上添加匹配到的图片信息
    ; {1 \* C: ^( w        cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)8 i4 w( v: g7 P/ k0 H; H
            cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)$ u& }  l5 K+ M/ ?3 d( U7 v
        img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))
    ; ~" X7 D. f& u+ \    img = ImageTk.PhotoImage(img_Recognition)1 v* U( K, D( }. O# E. p
        lableShowImage2.config(image=img)
    : Q9 Q1 P2 C3 X1 E    lableShowImage2.image = img& i* }1 ]  N7 b2 q: L
        lableShowImage2.place(x=630, y=70, width=530, height=750)8 S4 w# n  r" o- G" k: K

    , P2 V8 h% ?% Dif __name__ == '__main__':' y* {! A8 V$ ?8 Q+ {! H5 c0 p
        findExistsEncodeingList(img_path)
    . m; H$ A$ g6 w2 {    #生成tk界面 app即主窗口( i- m6 V7 l3 M) a! S2 D+ V. N$ W8 f
        app = tk.Tk()  * E: e  V7 q9 ^) l1 `
        #修改窗口titile
    ' P) n3 X, |/ A    app.title("show pictue")  - @3 \) I- T( c" Y3 A
        #设置主窗口的大小和位置
    ! k2 k5 F( f$ ^$ D2 h" c9 s8 J    app.geometry("1200x900+200+50")
    ! G+ p6 L/ k- J0 P* _+ c( [% ~    #Entry widget which allows displaying simple text.4 C; N9 E5 \* j, {- R  p
        path = tk.StringVar()+ }3 G3 o- k6 C/ z) A% e' T# Y
        entry = tk.Entry(app, state='readonly', text=path,width = 100)) W. V! ]1 Q  ?- B
        entry.pack()5 X" I9 i6 c" l5 q2 t
        #使用Label显示图片( z$ Y) n1 D( @# T6 U+ p" J8 x$ U$ A
        lableShowImage = tk.Label(app)" b3 Q* f/ s1 w  e2 l/ Z: F
        lableShowImage.pack()
    4 D" p7 q8 Z! b9 p$ e) l" K1 ~& q     #使用Label2显示处理后的图片; w8 S) |, @" [+ _& L
        lableShowImage2 = tk.Label(app)
    $ z& ?: ~" P! \8 u5 t) @; V    lableShowImage2.pack()4 x/ v! ?/ `( f5 i: N
        #选择图片的按钮
    $ H' y1 I! ?0 A4 z  Z* {    buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)0 K5 @- j3 I$ a0 Q% j" p- P5 t
        buttonSelImage.pack(). q1 @/ L+ u" D/ J+ C# O+ [
        app.mainloop()! a: l3 c. W% r

    ) }# K# j/ f; X! _" ]( v3.说明% x/ U1 F1 p7 U, n# I" `: L
    首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。$ b$ l, o4 A& Z, u, ?/ }: b
    * M( i) Z( b9 f' f1 o( ?) b- M
    5 c6 d8 r0 x$ O% E  \7 y) v% i" r

    2 t* F! f# s8 c 其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片
    4 k; T. l; ?7 b% }, d2 [+ S/ U* L  P/ V% B. x" r: r$ g. }3 [  ?
    : j. A2 @) ^! K3 ]! u7 T8 V

    , q( N- u* T9 B  p 但是效果会存在色彩的失真,效果如下:
    $ ]7 Z# n+ ?1 w: ?  U0 j$ B8 Q0 q+ F$ F; W8 {) Y  i2 q

    8 |, v/ q8 e9 N' ]! R7 ?5 n0 Q$ c4 L+ D) k+ q+ w
    也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。
    : H8 U  y1 ?: @8 i" L
    , _; I7 g" Z% K, E' ^% m) {; F这里简单提下PIL的九种不同图片模式:8 j8 \0 |0 k9 `! }

    % s) l2 U' k7 B* n5 Bmodes        描述
    8 e- Z0 I5 F) t. M, B1        1位像素,黑和白,存成8位的像素2 y% v* Y: N3 {" B4 m' c
    L        8位像素,黑白
    . n1 a4 v, a" o' D/ l! W+ G8 kP        8位像素,使用调色板映射到任何其他模式
      {4 [8 {0 s' W  ?+ dRGB        3× 8位像素,真彩
    7 R; U5 E3 C+ Q$ C* B: ~RGBA        4×8位像素,真彩+透明通道4 }- \3 T  }# C* E# t$ \. T
    CMYK        4×8位像素,颜色隔离; Q9 s: |, F3 F1 `& D# F9 O
    YCbCr        3×8位像素,彩色视频格式2 u5 X& J9 f  I, R& r8 k/ t
    I        32位整型像素
    8 }- o1 M0 }# d/ d8 v: RF        32位浮点型像素
    3 @" ], W5 x' @9 h0 m" @4.实现效果* r% N% k  x* O: S  \
    4 {0 _4 ?, d, r8 [  b- q9 `' f
    $ T' s# o, K/ ?
    . O/ I& c, n* b0 M+ i3 ~, S1 o2 B

    , N# ?" |" _) B, C, ?6 d 可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。
    + J5 q, g" e4 R0 q; t7 f3 w————————————————- l6 e- A- ^  T  w7 x3 t! i
    版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    : |# E" d0 t3 ]7 c. S# N3 g原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288
    ( u6 q# i: c, j
    , K2 v# _6 j( g2 {! C; }( ?
    : A8 y8 {$ ]9 U, z8 p" A
    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-5-25 09:21 , Processed in 0.438809 second(s), 51 queries .

    回顶部