QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4188|回复: 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实现人脸捕捉与人脸识别(照片对比)$ C. {; l  G  {
    & s- ?' v3 f6 h3 N6 `
    1.安装包依赖+ E; \6 m* K. O  [5 M5 D
    与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。
      [5 J  c% ?- ^' w  J! P& k9 ]; k9 M, F
    在python 3以上版本tkinter是环境自带的,所以这里不需要安装
    * j6 v( v! y8 g1 ~  E: q- A& F% T- R+ m
    2.代码示例1 I( z0 A" A6 @. D, M, W
    import os  q' s9 Y- b& I1 y3 y; C
    import cv2
    : ]2 E: q- z" V/ \import numpy as np
    , ~0 i# O9 G) x) |$ l. Z2 ~import face_recognition  E5 t. }- [, u; U# ?7 F
    import tkinter as tk  ( x2 d9 A+ h  F  y0 G+ E# G  k
    import tkinter.filedialog$ Z; X0 D4 L' Y( h. v+ b+ T, h9 j1 N
    from PIL import Image,ImageTk
    ) P7 j& `0 k% Q
    - D1 C  I; x  K4 C$ WclassNames=[]9 ]3 S! N' L; {
    img_path='Picture'3 e" _6 r7 o) I( N. o( P: ^
    img_recognition_path='Recognition'& ]/ O3 U1 R' ^" J! H
    existsEncodeingList=[]
    ! ~% x9 r! K1 B- j' U/ L3 k# m#对人脸集合进行编码进行处理
    $ T8 @( V- L$ g6 h1 gdef findEncodeings(images):
    8 |* c! h. Z5 g    for img in images:
    # E, D2 ~" _$ L6 c6 O# B4 m        #灰度处理
    / ^6 ?; [+ k+ f/ j2 [2 ~# \        img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)
    $ ?+ M0 s. m; a( E, u        #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果2 r- ^9 @7 G; [. b0 E; X
            encode=face_recognition.face_encodings(img)[0]$ i0 C( ^* `" n' E3 H( y
            existsEncodeingList.append(encode)
    8 T1 l2 a  Z+ |( r. p2 @& Q: U' F
    * ?8 \3 _: ~+ A$ N9 u0 \#获取当前存储的人脸编码集合
    6 g6 N% n% ?5 L1 U( X0 [8 Udef findExistsEncodeingList(img_path):
    , u0 ]+ r. s* b8 W: ]0 o    images=[]
    3 A+ j2 d' @6 v# h* b6 V, d6 \    #列出已经上传的所有图片
    / a! D& R& g: |, y    imgList=os.listdir(img_path)3 a* V+ l0 h2 _$ ]
        #处理存储的图片得到其人脸编码
    / t0 S) ]/ P. \. @5 g1 B' E    for pic in imgList:4 K; S( Q7 }- D2 c* N: ~( k5 F
            img=cv2.imread('{}/{}'.format(img_path,pic))
    4 b( L- N! c$ D( I8 e1 I- c% I7 j1 ?        images.append(img); a9 ~4 ?0 x. T1 |2 c
            classNames.append(os.path.splitext(pic)[0])
    ' E7 |8 y2 V- d* O# P  a    findEncodeings(images)! e: t  c- H+ s7 e' t! a, J8 x% Y& p
    3 ^; T  _: I* Y- y' W, t" ?
    #选择并对比图片
    : t# d! v% G( E: p2 @" x7 Fdef choosepic():
    : z" U! t5 j$ r* c7 D& W8 X    choosepath = tkinter.filedialog.askopenfilename()
    ! Y6 c0 I3 I. a$ V    path.set(choosepath)
    . z- W! d- v. A7 Q% J9 C$ K* U    img_open = Image.open(entry.get()).resize((530,750)): y5 S: }5 }% m# Q8 f3 i7 e) l
        img = ImageTk.PhotoImage(img_open)& Z( ]. i/ k& E9 ]
        lableShowImage.config(image=img)" h* o( Q* H9 v, o- F8 j9 v
        lableShowImage.image = img3 [* A; P4 f/ W8 `1 l( L. x. w
        lableShowImage.place(x=30, y=70, width=530, height=750)7 b+ m/ D$ Y" l1 A4 J$ P
        faceRecognition(choosepath)
      ]5 Z2 `5 f" y: @% S# P. ^, }3 c9 S- t4 w( M" m% f
    def faceRecognition(choosepath):  j. X" R* g: r9 c  u$ f- [0 P
        frame=cv2.imread(choosepath)
    2 w) d3 ^- B+ e) l2 w9 M4 M! {    frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
    # [2 U8 i8 Y$ v+ L- x; K( a    #对摄像头读取的检测人脸) v) {* W1 z% w/ p" D* G
        facesLocate=face_recognition.face_locations(frameRGB)( ]. V! L. o- e
        #进行特征编码9 v% \( c, c' w" P" W* F
        faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)
    : T' B+ ^0 F5 _$ N        #遍历检测的人脸和库中读取的图片进行对比,计算其相似度6 J  D! t, _, @3 s: X4 _& L4 B' `
        name='unknow', g/ h8 F6 }. x# g, _& c# ^" g
        for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):
    9 f7 J% k; f2 Y4 y, H$ P9 ^        #进行匹配: H+ S0 E/ `5 n+ h0 f
            matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)2 P6 V  p" e0 z( N, D
            #计算相似度
    " R" g" K6 w9 C" z- g4 Z        distance=face_recognition.face_distance(existsEncodeingList,face_encoding)
    : C2 X/ Y/ ?8 x* P# {( O: H        lab='unknow'& N, [$ T* `1 ~  ?% N2 g
            for index, item in enumerate(distance):/ }2 L4 D6 B9 |) {7 N
               if item<0.5:
    * x+ m6 m0 P" Q8 ^                if matchs[index]:0 w$ X' c- z8 ~; M$ s; Y7 O$ \
                        #得到匹配到的图片名称与相似度值
    ( @9 X: V' z$ b6 m                    lab='name:{}; Similarity:{}'.format(classNames[index],item)! X8 Z/ \# S: q2 \0 O% c
                        name=classNames[index]- E9 r/ c9 w, o, _" r; @
                        break
    6 m' ?- s( p( b: Y: j( w        #初始化面部捕捉框显示绿色# D# ~2 ~, i/ Y6 ?% {$ Z
            color1 =(0,255,0)' F& s7 o' l! G( X
            if name =='unknow':' d  }+ s2 a$ v! O% h) m
                #未能识别的时候显示蓝色
    " E+ Q& |' G9 S; a! p            color1 =(255,0,0), x8 _: G, r/ y, H$ T  J' y4 M
            #画面部捕捉框8 m3 v; V7 y1 X: `
            cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3): r/ }8 }  ^$ L; P8 n$ X2 H0 d8 B
            #在捕捉框上添加匹配到的图片信息
    7 ?' {, f' G6 D        cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)
    & Y2 s  t9 f7 c5 u! X2 F3 E, T        cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)3 U# h5 W7 G5 u) H0 m4 o) t
        img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))2 A, d& h6 E  A' \
        img = ImageTk.PhotoImage(img_Recognition)0 G4 c+ b2 O0 Y: _
        lableShowImage2.config(image=img)
    2 h5 h2 [6 _5 d5 y) a& a    lableShowImage2.image = img
    , Y' Z7 p5 ^3 c& M. J) \4 K    lableShowImage2.place(x=630, y=70, width=530, height=750)' W0 t! U+ y7 f/ X
    & n( Q4 c: p! i$ F) g+ X. F# n" m
    if __name__ == '__main__':- u& ?  B/ J. ~
        findExistsEncodeingList(img_path)3 S# \& k5 z- A4 |& t
        #生成tk界面 app即主窗口3 \& l0 _4 R6 C6 Y) C% M: q* K7 z3 B
        app = tk.Tk()  
    . k& K) j) A9 |' a; m$ R# i+ Y% }6 v    #修改窗口titile  V5 m2 d9 S. X) O. y. ^9 e% @8 t7 }
        app.title("show pictue")  7 V1 G/ r% }4 R* p) M
        #设置主窗口的大小和位置
    / ~+ D1 i, ~' M' q0 i( `- r; D    app.geometry("1200x900+200+50")) l3 K) }  t: G) {! }( f% v4 \. I5 b
        #Entry widget which allows displaying simple text.) B8 u# \4 O% I
        path = tk.StringVar()
    6 V# t* c* S, i* R8 [5 u    entry = tk.Entry(app, state='readonly', text=path,width = 100)
    ) P6 @- `  b) A/ Y) Q    entry.pack()* h8 d/ d  M% r3 d
        #使用Label显示图片9 G+ e* b( F4 o/ \) x+ N
        lableShowImage = tk.Label(app)
    " ^  g" P' m5 S  h    lableShowImage.pack()
    ! R& ]. _5 d  A  H6 Z% W( H     #使用Label2显示处理后的图片7 I1 k' k  f  `: A1 Q- o
        lableShowImage2 = tk.Label(app)
    . t$ K* A' S" `    lableShowImage2.pack()) v! @/ I2 A3 `9 U, z
        #选择图片的按钮
    ' w" a& h' `) }3 `7 }! [" q    buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)" M3 K. e3 F& m8 i
        buttonSelImage.pack()  H$ Q0 M8 T4 T
        app.mainloop()
    " n7 l4 E' Q/ `. I* ]/ I
    # h* w- H1 d- ^9 E/ c) F3.说明3 A# y0 `1 g' O4 {  z
    首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。
      O6 [3 u4 g& Y* _6 d
    ! X4 P3 P# C/ u0 R* h- n! X$ L1 u+ X  N7 e

    , u, w4 {8 R( r6 Z! b0 T 其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片
    # S# W( l$ D6 H  [8 m+ \9 r, J# \% k

    * z, j0 k& e3 n, I/ J, Z5 W, t! J
    * ~% ~! ^" w. p  J 但是效果会存在色彩的失真,效果如下:, ^8 d; ^; A$ A8 |
    ; z1 [6 ^. q+ ]0 D4 w% b
    ; z" g$ p$ Z8 I/ k( q! E* A2 X

    1 T, q8 m4 u1 R也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。2 I. v- f) p2 o! ?# b+ A
    ( X# y4 [' |! z. A( @8 V2 p
    这里简单提下PIL的九种不同图片模式:2 `" A: u/ F) @+ d& z: [

    & |- ]- x- x) N  hmodes        描述$ E1 q8 v9 S5 U9 C) @
    1        1位像素,黑和白,存成8位的像素
    3 Q% V! @3 J$ x, r# R1 s* S0 PL        8位像素,黑白; j; s/ [" ]7 \& y. C0 J2 [
    P        8位像素,使用调色板映射到任何其他模式
    * b& [7 h( v% I) R$ s/ TRGB        3× 8位像素,真彩
    3 K3 o6 i$ j( G, ~0 m5 @RGBA        4×8位像素,真彩+透明通道/ V$ S# e+ ^2 A& e. F
    CMYK        4×8位像素,颜色隔离
    , x; T4 {# D9 {9 N& SYCbCr        3×8位像素,彩色视频格式& b- g  {2 @% |' e9 @4 c
    I        32位整型像素6 K* r, o: {2 o* N. J& d
    F        32位浮点型像素
    1 m; u% |, z5 m7 m  S7 U4.实现效果2 J3 f6 {) i9 a6 E, o6 C: v# @7 F0 Q

      ]5 C; j) H) Q  }$ `& o: u1 V. s! N8 X4 G: m( M; q& }

    " j& J1 I3 r! F% H# K; O( f8 a/ J0 T
    可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。
    ! a- l0 w4 D9 ?5 K————————————————  J# w! e  t* m' S
    版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。9 P; T- N, J: U6 L0 u
    原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288
      u; P) t* O! P: j+ I3 r7 G0 z7 f) \6 J

    $ C* n1 B2 G9 _9 o1 s
    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-7-9 16:00 , Processed in 0.325835 second(s), 51 queries .

    回顶部