QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3788|回复: 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实现人脸捕捉与人脸识别(照片对比)
    5 T, G0 h6 O' N- l: w5 s# A: Q" O. n7 J6 Q5 a; Y8 i% x  r3 Y8 K
    1.安装包依赖: j6 D/ n$ B3 ~8 N: K7 h
    与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。
    9 F5 V/ \7 u# X3 O# ?; Y  `5 }& {/ H
    在python 3以上版本tkinter是环境自带的,所以这里不需要安装4 P% h" ]7 w# ~$ U, S
    $ Q0 n# k! {7 z% U# ^& Q: T
    2.代码示例' x& ?3 a' U4 J( ]
    import os# G' N" [( _2 F4 i( Z
    import cv2- r! x6 k, ^. }  [
    import numpy as np
    & @9 L' t" J0 I& O/ i- Z3 @import face_recognition& ~; |* p) ^4 _5 f/ g- Q
    import tkinter as tk  . w3 y6 j4 T0 T/ [4 ?+ m: }" J( t' I
    import tkinter.filedialog) S4 M4 u6 Y3 V1 X$ q  Y
    from PIL import Image,ImageTk
    . Y3 f% |9 \3 a. m; g/ |$ ^3 p2 Q5 v7 B7 O# Y0 j& B
    classNames=[]
    2 x3 H. }  H( q  f% Z( o, oimg_path='Picture'$ ^' H! D2 i8 R2 }7 M( T: F
    img_recognition_path='Recognition'# K, U8 Y/ |  y# W
    existsEncodeingList=[]
    + n- Q5 }6 A/ a' R#对人脸集合进行编码进行处理
    ) Y- i) T( M8 G% r) {/ T. Jdef findEncodeings(images):
    3 `+ y( M/ \7 C3 b( q- ?    for img in images:3 X" y! h3 |4 g0 C0 @& i% I, I$ w
            #灰度处理
    , I5 O4 _8 b3 Z: j        img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)
    2 [: a2 \9 n, C) }+ K        #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果
    . X) X; C+ w. x/ F/ i5 }        encode=face_recognition.face_encodings(img)[0]: a' p( r+ B; h4 b' v
            existsEncodeingList.append(encode)5 I* t) C8 l0 N1 c! r

    * b# K* H/ ~& R+ ]. {0 Q3 `5 f) ?#获取当前存储的人脸编码集合
    " e. O' w# U8 o& P4 [def findExistsEncodeingList(img_path):4 n& _/ @: N+ C" N
        images=[]
    4 T- S0 |- x, N; C) ^" w0 s    #列出已经上传的所有图片4 w% E7 k8 x3 k, C6 N9 y
        imgList=os.listdir(img_path)
    1 K" V' Q3 y5 T3 h: E    #处理存储的图片得到其人脸编码
    0 \/ B& }0 s0 l8 C7 w  Q    for pic in imgList:
    0 ~) t- @, T1 i* W5 |; ]        img=cv2.imread('{}/{}'.format(img_path,pic))2 @$ p- L9 u2 o
            images.append(img)" [4 ]4 ]) C" j0 [6 x  J2 D
            classNames.append(os.path.splitext(pic)[0])8 ~" V6 b2 f/ X8 U2 j2 P) @
        findEncodeings(images)
    + I3 [: \8 o# V/ |
    ; {) ]' q8 n) s  u5 H* U+ a2 n#选择并对比图片9 m* @2 f, A+ V0 h  ?
    def choosepic():
    + u: O. X/ I& ~9 k    choosepath = tkinter.filedialog.askopenfilename()
    3 v% p) c* Y5 S# k% C* |    path.set(choosepath)
    ) I4 }$ y" K2 I4 @8 O* B0 A    img_open = Image.open(entry.get()).resize((530,750)). o6 Y- u7 P, v
        img = ImageTk.PhotoImage(img_open)/ @9 c+ e( @9 V+ |/ G2 ?7 C, j
        lableShowImage.config(image=img)6 b# L$ |; [8 B* L2 h
        lableShowImage.image = img% U: c4 p- |1 l) Z& G
        lableShowImage.place(x=30, y=70, width=530, height=750)+ e2 D1 l4 P( t; g/ Y+ A
        faceRecognition(choosepath)
    ; J- I5 z( ~% @$ D# S& o* i; {+ `9 {- T- z  ^3 L% U
    def faceRecognition(choosepath):$ Q1 ^2 s8 a) C: o( X0 s
        frame=cv2.imread(choosepath)
    ) L. h% ^1 G/ S    frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
    4 w  a  K" k1 A, u7 ]( W+ s7 X8 m    #对摄像头读取的检测人脸
    0 P$ t. r' X, ^) ]% ^- [1 L) r. N    facesLocate=face_recognition.face_locations(frameRGB)  w1 r) c% [3 ?6 v+ O& X0 D
        #进行特征编码1 V: o( l  B( g9 S: X
        faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)
    4 U$ I7 r9 i: O6 g        #遍历检测的人脸和库中读取的图片进行对比,计算其相似度; y% s( l- q; _. x
        name='unknow'% l; t6 c" ^; F$ n
        for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):
    ! z/ X. @4 U' W5 @: l0 m/ O/ Q& b        #进行匹配
      i3 e) b3 m! s3 i        matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)% ~' l; W- Q: L, @
            #计算相似度# C) S2 V0 L& M+ v7 N, W% o
            distance=face_recognition.face_distance(existsEncodeingList,face_encoding)1 i2 h, w% E1 J7 w
            lab='unknow'  \' n! M2 H  Y6 B
            for index, item in enumerate(distance):8 T8 l, H8 Q# V7 k" e
               if item<0.5:
    $ W# S' F  C9 M9 m" @6 P- ]' P                if matchs[index]:4 y6 O5 k  b* l8 ?; `  a
                        #得到匹配到的图片名称与相似度值% T5 W+ G2 S( ]& q- z& B9 H% v
                        lab='name:{}; Similarity:{}'.format(classNames[index],item)
    + m' ]$ _) _* W9 }9 x' E. n                    name=classNames[index]
    * N% M/ T- o9 b3 z  l% n7 g                    break
    ( k! o% _6 Z; u/ g7 I* n        #初始化面部捕捉框显示绿色# e; W' ^5 u% L
            color1 =(0,255,0)9 g; v, d& x2 x! T0 C
            if name =='unknow':0 n! M7 r0 Q7 ?) E
                #未能识别的时候显示蓝色8 I6 ~( ?" Q: C" ?9 ~
                color1 =(255,0,0)
    % m. x* I+ e- Z( D4 N& a6 }5 r        #画面部捕捉框0 _# H# V( k& H
            cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)
    * X' R, |. t, ]' P3 e5 b2 i8 d        #在捕捉框上添加匹配到的图片信息& z; t; j3 A* `3 a. I! `
            cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)4 z2 ?% D. E: W2 @
            cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)
    3 A* t  E! a+ d' r5 j    img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))
    + ]" p& c' W' D- d+ v, h    img = ImageTk.PhotoImage(img_Recognition)" ^! }' O9 d, y: {
        lableShowImage2.config(image=img)$ B" S) b. U2 X4 W
        lableShowImage2.image = img) m. g/ U9 y( m
        lableShowImage2.place(x=630, y=70, width=530, height=750)
      A% y1 u  y0 H& s+ T) {" ~* q/ h6 Q( [, }+ V6 W  W. I0 r
    if __name__ == '__main__':, S) ^( s8 H! K1 i: b6 \
        findExistsEncodeingList(img_path)
    ) X, P+ ^4 Y0 `! q& P    #生成tk界面 app即主窗口
    ' N5 @' w' q/ g' C5 Q6 I7 X. g0 ?    app = tk.Tk()  
    9 H6 i0 i1 R3 N) [  A3 Y8 \    #修改窗口titile
    , Z- m0 _! [. Y3 n    app.title("show pictue")  $ Q" J2 z* [+ X& R) J; g, P2 G& X/ b
        #设置主窗口的大小和位置
    , s3 T' ~+ y& K$ L& R# f0 h    app.geometry("1200x900+200+50")+ q6 n# g6 p9 j# M5 J5 s9 B# q
        #Entry widget which allows displaying simple text.9 W9 g' O; A; v5 L2 b# w( _
        path = tk.StringVar()1 t6 C2 X% {9 O, G2 z1 T) s8 d
        entry = tk.Entry(app, state='readonly', text=path,width = 100)
    : u' ]# r( P* A$ `    entry.pack()
    7 O" m6 r1 k# |  P4 Y  I    #使用Label显示图片, d9 i) O7 V& f: m, Q* U0 @% Q6 ?
        lableShowImage = tk.Label(app)( Y" b% H$ H  M8 H4 @1 i
        lableShowImage.pack(). P+ T1 x5 o6 {
         #使用Label2显示处理后的图片
    $ s* a5 T3 p; M/ K9 ]- m/ D9 Z0 I    lableShowImage2 = tk.Label(app)
    8 l) L! I& f7 h2 ^! u8 g# j3 z    lableShowImage2.pack()
    0 `$ s* E: o& r2 D    #选择图片的按钮
    7 ]. M6 u& @2 {5 X: ]    buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)
      \4 l" m, D" z" ~    buttonSelImage.pack()
    / H2 c, H: L3 [7 i) c) w% Q8 [    app.mainloop()
    % s; J9 X4 f& U0 L4 d* R" f( R7 f0 C' l( I* J
    3.说明3 V0 L" \6 t2 T$ h3 S' n: A' R
    首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。4 C0 W7 F0 D: Z! [/ M$ z
    $ T0 `. I+ d( {8 x

    : c: _  O) ^1 W8 h3 r3 u9 E. d% s9 D0 {3 X) A& _- ]; F
    其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片
    : N* o: o+ ~1 E: R4 ?: S6 N
    1 |" f* Z! D& Q" Q+ |3 I' y' B. O. F6 N/ d1 g

    4 E4 R1 g. o% d2 L  X2 [0 X 但是效果会存在色彩的失真,效果如下:
    $ f$ [  k- }0 I+ \8 E
    4 B: K, F" c7 L! a) e' j0 N4 j9 t2 ?0 u/ O: N# \
    ! Y4 `5 L% ]+ L( T% ]& f
    也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。) L; a# w+ B8 m4 {
    # U0 y! }: r4 S1 @/ v8 Y7 k
    这里简单提下PIL的九种不同图片模式:
    ! b3 B" A/ `: T& ^% U; P+ l* n$ D$ r6 j* f
    modes        描述5 \* V, h7 j% [) i; h/ ?4 o2 G
    1        1位像素,黑和白,存成8位的像素
    . I. F8 V' w8 zL        8位像素,黑白
    + O& u# T) k% i& Q1 p1 n- b; _P        8位像素,使用调色板映射到任何其他模式
    ! e& p7 g- a. MRGB        3× 8位像素,真彩* Q- L, b2 o/ `) K. n
    RGBA        4×8位像素,真彩+透明通道
    8 k+ e/ J4 ~* K/ D1 f4 J4 gCMYK        4×8位像素,颜色隔离: W+ R# _$ a1 X1 O! h
    YCbCr        3×8位像素,彩色视频格式0 H7 |/ _% z+ e/ h
    I        32位整型像素
    - ~+ R! G  `7 {4 k% U5 |$ O- RF        32位浮点型像素
    " ]# ?* h2 L: Q$ @4.实现效果. y; I& O1 x* B' T+ N! H3 L

    2 ^; O) u$ }, x  y. o
    * n" N. v0 \% F) S$ X
    & Y0 n% g6 ]4 i: J5 Q9 J5 ~' S. z$ c" c
    可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。5 l0 E7 u5 \, g; e
    ————————————————
    8 ^; V9 \5 F$ e  h版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    & x( _8 u1 F& ^; x% _$ L原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288# Z) C0 [8 t7 H" y2 s5 v# X
    6 d( U; T  I2 H. t6 s$ c

      s9 j5 d# b# I6 ]! }, h
    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, 2025-11-22 23:46 , Processed in 0.276833 second(s), 50 queries .

    回顶部