QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4206|回复: 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实现人脸捕捉与人脸识别(照片对比)
    % i- c- |* A- W1 ~0 f* V5 o
    * J- E! ?) x7 W) W4 L$ G2 S1.安装包依赖
    : Q' |  a5 |/ X0 C与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。. o: \/ R6 d/ n$ P

    ! w2 y: |: T: [2 v6 V* `在python 3以上版本tkinter是环境自带的,所以这里不需要安装
      \$ D5 A9 Q9 y3 z& Y
    2 M7 A/ a' v6 V* f2 y& f3 x. ]# }2.代码示例
    0 B8 w; N+ ]' V- I" z- _import os! s! Z9 A7 p& ]) Z: ?, v- v6 F
    import cv27 ]+ y4 H. }9 U  H- M
    import numpy as np
    8 o6 Z' P% w' t. @& limport face_recognition% p& T2 R) l0 k! s  }6 I
    import tkinter as tk  
    ; \2 c9 i2 {5 z6 b; q' uimport tkinter.filedialog
      G/ h4 a  S  I+ E' B' E& S+ [from PIL import Image,ImageTk 2 W3 M& b, u1 W! m
    $ k; _* F+ X0 g0 s
    classNames=[]' V* y! d2 v' Q3 q
    img_path='Picture'0 D- ?: V! K/ a* l
    img_recognition_path='Recognition'
    ' V0 W( N/ {, n) j& Y, |existsEncodeingList=[]
    8 ]/ y- h; P1 e6 m% |; {2 r! O, V#对人脸集合进行编码进行处理
    6 V' x  u; e  w% O# w. j( _4 }# ndef findEncodeings(images):
    1 p' ^. A0 W/ ^5 k. T; d    for img in images:' R! L+ w, |" s& E: t3 ]) r6 u( K& y
            #灰度处理
      q. q- b" y. `        img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)
    4 k! i  N% L" v( O9 g; U) l        #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果' m; Z: W7 w  U- }2 P& a/ V- G9 Z
            encode=face_recognition.face_encodings(img)[0]) i0 N! ]: a# n- n! }2 i3 B
            existsEncodeingList.append(encode)( W- l  G0 }7 Q( W, K
    : e* p, i. r( }! S' d( y7 u( b% z
    #获取当前存储的人脸编码集合
    + u/ M, Q, N; G2 T" @4 _def findExistsEncodeingList(img_path):
    , z" k$ `! \; T+ @) t    images=[]
    / C: B+ X+ r% w6 @( p    #列出已经上传的所有图片% _/ X, |! ]8 ~- J4 p1 b
        imgList=os.listdir(img_path)
    5 u) A! G- {% [+ F: R4 c- w$ Q    #处理存储的图片得到其人脸编码' j+ u, _8 J0 ?. F! _
        for pic in imgList:
    9 J6 Y  J1 j  k6 d% x        img=cv2.imread('{}/{}'.format(img_path,pic))9 L1 b! p/ Y7 o" D
            images.append(img)0 V4 y7 {2 {- h
            classNames.append(os.path.splitext(pic)[0])
    : Z) I2 G1 `: b, E& Z$ X5 z- F    findEncodeings(images)2 o9 V. ]: N$ Y9 X* t

    ' M0 z, ^* Y( K+ N& r( ?- i#选择并对比图片- r+ h, @# s" h
    def choosepic():
    4 t% G& P- w$ z" O    choosepath = tkinter.filedialog.askopenfilename()$ c: _! N6 I( r$ z
        path.set(choosepath)
    4 d# f3 @6 l8 M; K! T    img_open = Image.open(entry.get()).resize((530,750))1 ^" B( J1 Q/ H. I) X
        img = ImageTk.PhotoImage(img_open)/ ]$ O- h: V$ f
        lableShowImage.config(image=img)9 `* _1 j7 a* r1 F8 \) y; Y
        lableShowImage.image = img  q2 ?4 A+ ?( X2 s
        lableShowImage.place(x=30, y=70, width=530, height=750)" `* z7 Q0 w/ w! k/ q; Z8 Z
        faceRecognition(choosepath)* u3 U9 g& s. Z6 v& |
    6 x: j5 ^% j- q6 w! r" R
    def faceRecognition(choosepath):- K! _" t- {. l6 P
        frame=cv2.imread(choosepath)
    9 I" S( T4 f3 ~; j9 o    frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
    $ K: b, e/ R1 b& x# n    #对摄像头读取的检测人脸( J. \6 c% s+ U1 _4 A6 j6 m5 e
        facesLocate=face_recognition.face_locations(frameRGB)8 \+ J3 n' O7 z3 g  ]$ c
        #进行特征编码, N+ u; `- p+ j# t# R
        faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)
    ! g2 L6 q) c8 F  E& A; L3 @% L        #遍历检测的人脸和库中读取的图片进行对比,计算其相似度
    / t4 a1 F5 E3 B  E/ }4 O    name='unknow'
    6 A- M8 D( [. I( r+ N) }0 s" R    for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):
    # p% `# c3 X& ~        #进行匹配$ s9 I& `3 x# X1 \6 B3 i; B' ]
            matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)
    5 `! W* f& \" h( g. ]  f; V. |        #计算相似度* P9 C6 @" i* x- a) Y- Q
            distance=face_recognition.face_distance(existsEncodeingList,face_encoding)1 E% V: p6 b: E+ I
            lab='unknow'
    1 R0 S4 J6 H; a        for index, item in enumerate(distance):7 L7 [0 J: T* \
               if item<0.5:
    9 ?! {0 E( U0 @" z! n                if matchs[index]:
    7 |# k6 w7 G5 a! N                    #得到匹配到的图片名称与相似度值$ J# U" v2 N+ F! R8 x" }. ^% X6 {
                        lab='name:{}; Similarity:{}'.format(classNames[index],item)
    4 r/ k" z$ s4 A8 f% h# `; p                    name=classNames[index]
    - P7 j. ~# s' N* R8 x                    break
    2 F9 T/ Q4 z! X) K- t: m% P        #初始化面部捕捉框显示绿色
    ) a1 Y4 X# s. Q8 F$ x  h        color1 =(0,255,0)
    3 ^. j9 U  j8 _4 }. O        if name =='unknow':
      [  a) p2 F8 {( _+ K5 v: N            #未能识别的时候显示蓝色
    : x- R1 [$ k) H1 n7 |            color1 =(255,0,0)
    5 \8 }: h8 G# S. i' C( x$ K9 X" |        #画面部捕捉框5 W7 q2 N1 T$ I- U; \
            cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)* V8 \  W1 E4 @8 B6 X; q  V5 z
            #在捕捉框上添加匹配到的图片信息
    + G' w2 ~  _5 p, m& k. J  s        cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)4 i3 K, T9 L5 T8 K* j
            cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)
    % M+ s6 [7 f* ]0 F' ^* s" K. I1 ~; S    img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))! n. Z1 H! o8 ?7 B- W7 l
        img = ImageTk.PhotoImage(img_Recognition)
    $ U9 u' Q, u) ]7 o% V    lableShowImage2.config(image=img)
    9 I8 Q' X# R! _$ V  v' r    lableShowImage2.image = img# J5 E3 X1 n5 b0 P$ `
        lableShowImage2.place(x=630, y=70, width=530, height=750)
    * o0 r: f/ x* j+ a) k: Q! u7 R5 O  X7 A' l4 v, ?6 C. k
    if __name__ == '__main__':
      J, b1 z4 k9 T4 m    findExistsEncodeingList(img_path)+ Z, J& z; p6 c$ F
        #生成tk界面 app即主窗口: a- h4 a1 ^# h1 r7 n
        app = tk.Tk()  
    ( p' m* G% ]  n5 _  ~" B    #修改窗口titile
    9 K- a  c$ D& z4 F9 c' |    app.title("show pictue")  
    0 s+ @! p1 E! D3 v7 C    #设置主窗口的大小和位置
    ) \8 x- ?7 b# W  g    app.geometry("1200x900+200+50"), }" A+ s$ A4 G
        #Entry widget which allows displaying simple text.7 r: V4 r& g! `5 ^- a" G* R% S9 g5 Q( q
        path = tk.StringVar()
      \4 r$ R3 b& x1 h/ |) d    entry = tk.Entry(app, state='readonly', text=path,width = 100)
    7 y% X1 ~) D' |1 s7 H& r# O    entry.pack()/ b# q, k2 M( x$ v
        #使用Label显示图片
    * u) M0 Y0 ^3 I4 p8 B/ \! t$ X( W    lableShowImage = tk.Label(app)
    & l) v2 N# C+ ~    lableShowImage.pack()
    9 T* R6 s; }3 v3 \6 |6 G. Y     #使用Label2显示处理后的图片
    - c& i' U5 w1 P( S( \6 q    lableShowImage2 = tk.Label(app)
    & N. ^% F; l0 l8 q) S6 @1 a7 x    lableShowImage2.pack()
    " G! {- W; ^2 I5 j    #选择图片的按钮& ^; E1 t' n- s3 s" ^% t
        buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)$ \# D/ {4 K3 k5 z7 ?9 y; h
        buttonSelImage.pack()/ N7 n$ R% \3 A
        app.mainloop()9 s& G  b0 l7 h8 T# e4 m6 }: K
    & [% g# K3 t2 A& g) J) ^
    3.说明: c" W; K5 C+ ^% t. b( z
    首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。
    , m; y& I) i/ k" r3 r1 `& ]2 s+ y% a
    * i. w4 |( a+ K7 {+ u

    1 N% B) }# B, r1 B$ ]) n- ^, y 其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片1 a& ?5 U5 @7 N9 V; y) I

    : {8 y& _9 R9 S" S, `. R' w" F- |6 H6 g! _

    9 G; l6 e/ B' M; w 但是效果会存在色彩的失真,效果如下:. m7 Z! l# o! ^
    % w* X! E: _$ e6 L4 N8 q, B! Y% O

    0 M$ _( o0 i6 s6 G/ [2 a% @9 Q# a) U
    也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。3 r; u4 J. ]' R% G! i6 H5 P9 W

    ; j  A' q: `- A( K% n这里简单提下PIL的九种不同图片模式:+ G8 m- p# Q# t% W1 x4 x
    # b7 Z4 N/ f4 h" U" W
    modes        描述' h. F, J; }0 |- Q& x" J; t7 i
    1        1位像素,黑和白,存成8位的像素7 v+ O. l- B# |8 R3 s1 t) V
    L        8位像素,黑白4 R5 W1 I9 ~  r8 P; y
    P        8位像素,使用调色板映射到任何其他模式8 H' }; e0 r. M* e5 h8 X1 w
    RGB        3× 8位像素,真彩; c, X" z. y7 m7 v$ y" b
    RGBA        4×8位像素,真彩+透明通道
    # C! c+ r3 B7 }  T  FCMYK        4×8位像素,颜色隔离/ `" @# U7 R% ^" m7 [0 [/ I4 \
    YCbCr        3×8位像素,彩色视频格式6 {- `# y" ^! ?" \; }2 V9 p, @( B
    I        32位整型像素( _/ Q' L; l: e( A6 |& A' y
    F        32位浮点型像素
    ; e0 s) z% q: k' }4 q# L4.实现效果
    , x# X1 E8 h. [4 ~, c: p
    7 Y6 B4 I8 e; g, Q7 n7 [4 a
    1 A- [$ G# l' b0 e1 k. F( [+ W

    / l6 |% D- D& I 可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。
    ) [) V- {. i& e8 a, S————————————————* ~7 A) a$ G- x% l. T
    版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。! {8 E0 t1 z1 X7 \. D! Q& f/ g
    原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288
    9 j+ w) h  n/ `5 F, }. u& ]9 |, @" c+ P1 K/ U
    $ g& N+ g- U% m/ ?* i, n
    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-8-24 04:04 , Processed in 0.493748 second(s), 51 queries .

    回顶部