QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4187|回复: 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实现人脸捕捉与人脸识别(照片对比)
    8 r7 n  j% G: s- c% C+ P8 D+ A& D
    & i; @% c# I# N& ?% {$ |  @1.安装包依赖! _( D( c# V4 A4 u& F/ W. Y) }
    与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。2 ]* {' v1 L" F5 O% \

    8 v/ x. R) D) v在python 3以上版本tkinter是环境自带的,所以这里不需要安装
    2 F0 a  m( d5 j1 s3 P
    # S% Q4 T' c2 j6 b. D" }7 z2.代码示例$ M; P( n4 j$ F0 q# x
    import os: d) I% W6 l  v. _' K/ s" N
    import cv2
    6 {5 X: ~; O! u6 \, d; S/ j8 ^import numpy as np
    - H9 W/ o  A% E/ X" Y# timport face_recognition5 p# }1 }" e' f6 G6 c% o; r
    import tkinter as tk  
    ) @3 b/ {5 h& y( oimport tkinter.filedialog
    3 Y6 r6 r9 u" _( D9 o  xfrom PIL import Image,ImageTk * V: ^  X/ p7 p2 @
    % A# ~9 m2 q* C* k
    classNames=[]
    1 n) _) o1 V6 y3 Vimg_path='Picture'
    ( q6 Y# |9 P8 e" ~- r5 Wimg_recognition_path='Recognition'! y# K5 R* X* l
    existsEncodeingList=[]
    - g! a5 x2 i5 t3 j! R  h; c#对人脸集合进行编码进行处理( v# P$ e9 G2 _% z& T$ k- @/ d
    def findEncodeings(images):
    1 r( a7 _/ [- h6 r    for img in images:1 L8 S3 K) k, j4 H( p
            #灰度处理
    7 O& f3 w0 R* b* ~- s$ u9 k        img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)) C% S- s, f9 ~" o, U" V6 O
            #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果
    ! {5 k1 l9 H( Q9 u        encode=face_recognition.face_encodings(img)[0]
    . a. X" ?& X+ ~' Y. J. a. T        existsEncodeingList.append(encode)
    0 ?" ^8 m& J5 M
    , x8 x2 R. R9 Q) ]3 D3 q! d" s4 }#获取当前存储的人脸编码集合
    - ?: T6 W1 Z4 ~  U$ S! r0 ~def findExistsEncodeingList(img_path):% s% f5 m7 |4 Z* g* G
        images=[]
    5 m# Z: S0 A) ?/ C    #列出已经上传的所有图片
    $ ]/ l+ s  }( O" e/ W0 _  g    imgList=os.listdir(img_path)8 Y+ g. G- k* i" c4 i* F5 O0 m
        #处理存储的图片得到其人脸编码7 |! ^+ d  k4 V1 j* \+ _6 o5 ?
        for pic in imgList:
    0 Z4 r  m+ i8 y: O" `' \) D  E+ O        img=cv2.imread('{}/{}'.format(img_path,pic))  G5 B1 s! E& C: K6 A  @, P# ^2 f9 F
            images.append(img)
    * o5 l3 [: Y" z  E9 s! L1 n        classNames.append(os.path.splitext(pic)[0])
    ' \6 Q' U! Z2 u/ |; B1 m: \    findEncodeings(images)
    2 u% X5 D. A8 t0 y. P' B+ M% U. t* J- S, u
    #选择并对比图片8 m/ b0 g0 S( R  G( F( E* `: w
    def choosepic():
    5 u4 {* J; p$ g: q6 i9 m! O    choosepath = tkinter.filedialog.askopenfilename()
    4 W# ~4 G' @+ X9 g0 E4 \    path.set(choosepath)2 e& g) o' l5 {5 \  L8 {  [; b
        img_open = Image.open(entry.get()).resize((530,750))6 E& _4 E& C) t' B- R1 _+ ?4 \+ v
        img = ImageTk.PhotoImage(img_open)
      w: T! N: z) m1 m    lableShowImage.config(image=img)
    + _$ @8 B; z! [* w# g. l    lableShowImage.image = img
    3 _1 [3 u* r0 _: J! T, B6 F    lableShowImage.place(x=30, y=70, width=530, height=750)
    3 Y4 {4 u: B3 [- n5 `( i    faceRecognition(choosepath)4 F9 c+ o4 p% l7 z
    8 ?) [  @6 h( I+ r7 z1 s4 ^) y. R
    def faceRecognition(choosepath):+ ^) [  `8 [9 I
        frame=cv2.imread(choosepath)
    : ?) Y& Y) d: Q. B# i5 H    frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)% ?" b  O% v& I: g- b+ q+ ?4 x% o
        #对摄像头读取的检测人脸
    - D) e# D! M2 P7 w    facesLocate=face_recognition.face_locations(frameRGB)5 |0 z, g( a- f3 l, f
        #进行特征编码
    5 j% R- Q; H$ }2 h3 |' t, L    faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)6 _. H9 n; M  \# r! L9 {
            #遍历检测的人脸和库中读取的图片进行对比,计算其相似度- n& r6 _, p! `, ~' v: I6 ~) S
        name='unknow'
    . {! J+ E% Q6 b4 x1 v$ h    for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):- Y6 T6 X+ u+ Z3 t
            #进行匹配6 M5 H5 F6 w: G" K2 H
            matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)4 h6 q5 _; Q7 U- q5 t
            #计算相似度2 [& A1 A4 t5 @; s$ S  ]/ a- q
            distance=face_recognition.face_distance(existsEncodeingList,face_encoding)
    7 L, @) D& g8 d, E        lab='unknow'
    . J8 d$ Q, ~) x& u9 C        for index, item in enumerate(distance):! m3 u2 C6 Y- s! m) ^$ Z  w; C$ j
               if item<0.5:+ _# I4 q, b, B6 K$ D- L+ u. b: C
                    if matchs[index]:# T9 o1 ]% M" |- p5 \* y. F
                        #得到匹配到的图片名称与相似度值. b( w7 e: _5 u+ `* @+ a7 O8 l
                        lab='name:{}; Similarity:{}'.format(classNames[index],item)4 z' b; v/ ~" P- l
                        name=classNames[index]
    ) i! T, G# v% l* i4 d                    break
    0 Z2 [; L; ^7 X) ~        #初始化面部捕捉框显示绿色
    9 E; x% Y8 }# P        color1 =(0,255,0)0 X9 b2 g$ f# z: S- s
            if name =='unknow':
    2 t# W- m8 t  O' \, {6 N: E            #未能识别的时候显示蓝色
    4 @, o- O3 j# \1 I" V            color1 =(255,0,0)5 Z; j4 l6 s' N2 A% o$ b9 C+ D6 ?
            #画面部捕捉框2 M: @  K2 U" u3 D
            cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3): @$ j7 C0 F4 B6 i/ W0 g/ K; `
            #在捕捉框上添加匹配到的图片信息
    1 G6 n( V" T' U4 m' x        cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)0 w: H5 ], {9 q- t
            cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)
    3 t: o* Q, x; Z" n    img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))- ]/ z6 u! H! z% S) l
        img = ImageTk.PhotoImage(img_Recognition)# j0 A7 M5 z! b6 @* Y
        lableShowImage2.config(image=img)
    - E* N3 [8 p2 \) x* f8 l    lableShowImage2.image = img' v8 n: O9 \& {4 z0 R, l: K
        lableShowImage2.place(x=630, y=70, width=530, height=750)
    4 k, |1 o! F9 c- R- w! r
    , U2 V4 ^+ A( l6 Z7 i6 x4 nif __name__ == '__main__':
    5 Z; B) S* c, l$ |8 a) Y    findExistsEncodeingList(img_path)
    ( ^5 x( @* a# G* C6 E    #生成tk界面 app即主窗口
    ) h& A& v3 ~, W+ K    app = tk.Tk()  
    1 I+ f& A% a* Z    #修改窗口titile6 U6 }, [7 B, A' A
        app.title("show pictue")  ' {/ P+ n2 j; J, S1 [
        #设置主窗口的大小和位置
    4 O6 g) ~* k9 g* D6 Z    app.geometry("1200x900+200+50")8 {5 g, a( ?& J) C$ F
        #Entry widget which allows displaying simple text.
    + e' |7 R: y6 {; b9 q    path = tk.StringVar()
    4 Q" [' Q' Q) E' Z5 q5 X, D5 w4 \' H* D    entry = tk.Entry(app, state='readonly', text=path,width = 100)2 Z8 X4 R* x$ f
        entry.pack()
    1 I& Q* a5 P0 l  c3 y( X    #使用Label显示图片
    % p* k* R- l1 q3 j    lableShowImage = tk.Label(app)
    5 p* p) _* {' h% ~* X1 N    lableShowImage.pack()
    + ~! L1 ?2 H& O7 I3 i     #使用Label2显示处理后的图片
    0 L) B9 u0 o9 R) |    lableShowImage2 = tk.Label(app)3 |1 g2 J& N1 C" b
        lableShowImage2.pack()1 w8 t* `% g) n
        #选择图片的按钮
    # \9 W0 O9 L5 h    buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)
    / ?2 ]  L- w& k3 B6 L    buttonSelImage.pack()
    9 W" P8 R( c/ T5 k! J/ D+ n    app.mainloop()
    : {( U+ Y" ?" \" J2 L
    + N& x/ }' P) y5 M# s. @1 ^1 W3.说明% U( @* x9 k+ x
    首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。
    6 E) j4 @  b+ y9 w( H* R& ?# T: k+ e/ I; ]) ]

    ) u3 x* O( q1 {. x
    6 P  v7 ?/ O. c 其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片5 x7 U+ V9 X6 F
    1 C* @0 M. m# E$ U) ?  K

    " p8 W' r: ?9 c5 j7 l9 e& j7 J5 J
    但是效果会存在色彩的失真,效果如下:
    ; @8 ?5 s( G4 B2 B) m
    ( f1 Q2 i0 d! H5 E: q% I; }$ v& M" X4 }) g% I. \7 d+ ^$ Z+ T3 |* W
    8 g% F' E, G+ _1 t; [
    也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。
    & f$ `6 Y9 [- h9 E: s! G7 Y6 q
    3 r- D+ C6 c' R, b- e这里简单提下PIL的九种不同图片模式:" s  H5 T# X" N4 x
    + Y/ f  O- l4 Q/ L/ y9 J
    modes        描述1 o1 v6 \" h; k9 N: y3 K
    1        1位像素,黑和白,存成8位的像素* N0 _$ G- {( h* S4 T' Q5 O* q
    L        8位像素,黑白. w" s- M) M4 i5 x( U: h
    P        8位像素,使用调色板映射到任何其他模式, V" H9 R- m7 I
    RGB        3× 8位像素,真彩
    , S4 F( m6 h4 u! D, C' MRGBA        4×8位像素,真彩+透明通道
    2 b7 k) ?) U: |( C( W% z; VCMYK        4×8位像素,颜色隔离
    & r( \% o* r6 c9 @YCbCr        3×8位像素,彩色视频格式- `# c6 c' p9 q. `/ r9 H# R
    I        32位整型像素( x( W4 B1 @( f
    F        32位浮点型像素- w) v- V" G: H5 J$ J
    4.实现效果$ t7 Q: M( a+ {. K
    9 Y2 @1 S0 a2 ~

    + B! @# u3 S3 z# c
    5 d! b: m' m7 g& j* E$ C! X' N  c* m
    可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。
    # C2 g5 _' w8 L, F! t2 k————————————————
    + [) K* \2 j) _% {: t0 B版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。3 y5 y8 r7 M3 E& J" k
    原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288. f( g8 e  c% K3 [7 O' c5 w9 `

    . d& a# b( M$ s& E- b6 e1 c; h" n5 O( Z9 s; N# w$ Q. x1 X, L4 K
    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 14:10 , Processed in 0.614085 second(s), 52 queries .

    回顶部