QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4214|回复: 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" A6 F* K7 c6 P) w6 Y6 M+ K
    , J9 t- y& P" n6 B, x7 {
    1.安装包依赖
    2 C7 a* v2 r) I  J3 {6 G与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。
    4 d" c8 J# @# B8 |' h: U4 h% k1 @
    在python 3以上版本tkinter是环境自带的,所以这里不需要安装, U: |$ D: {; o, X' }& n+ x
    + L7 N6 Z0 h0 l! i3 [' ?' b4 s5 ?
    2.代码示例
    ! x: k# ~6 V. ]% c8 Simport os/ r- h7 G1 D: v  O2 {/ Z! u
    import cv26 Z' X; E9 q8 }% J' h9 H
    import numpy as np
    / C5 t3 u* b. ]4 nimport face_recognition
    ( {& v3 q& F  c, o& r' Gimport tkinter as tk  
    3 t7 q6 |0 I4 V2 simport tkinter.filedialog8 f2 G7 I; @  t+ y, t( d4 x! D
    from PIL import Image,ImageTk
    9 `. P! Q! _9 @% y* h- I' S+ n4 h- B) l1 C/ A" K
    classNames=[]
    7 D" N4 [* c/ C, L/ d# ~0 gimg_path='Picture'
    ; G: ^) G2 [9 q7 r" ?img_recognition_path='Recognition'( r3 C0 i$ N; K4 \
    existsEncodeingList=[], c& |/ v' C/ B! Z4 _( r
    #对人脸集合进行编码进行处理9 b' s6 y4 y( p5 m9 c: e% J. @
    def findEncodeings(images):
    ) T. n- m& W  I9 b: R: X    for img in images:
    # G  c& P$ v, }  N' L        #灰度处理
    - E% M! A" [+ J; T6 b' N        img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)+ U4 T0 S* t) f6 z
            #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果& {4 W( v6 L7 H
            encode=face_recognition.face_encodings(img)[0], y9 A# h4 O' D4 i- e0 j& @! G
            existsEncodeingList.append(encode)& T$ m! R* j9 g% J% b

    # `# j9 w; ^" o3 ]#获取当前存储的人脸编码集合  z4 U' A& G0 b9 D- h
    def findExistsEncodeingList(img_path):
    1 f$ x. B3 k- T+ a* ^" q7 ?    images=[]
    . ?5 W- X5 M% T) @, _4 k    #列出已经上传的所有图片* G6 |, B5 Z. u! N
        imgList=os.listdir(img_path)
    $ m9 g5 d+ l8 V7 S" P" I    #处理存储的图片得到其人脸编码
    7 h3 F0 u  d' D' i) }& E) R: T    for pic in imgList:
    : R4 F9 a, P  _+ w( S$ @9 ~        img=cv2.imread('{}/{}'.format(img_path,pic))
    7 H) A, D3 t, l+ Q7 \: m        images.append(img)
    / V$ g, M# H: U% X2 ~9 ]. P5 U/ y( E        classNames.append(os.path.splitext(pic)[0])
    # F- E: m: ~4 Y$ e& i    findEncodeings(images)
    9 V+ Q: M- B- I, Q; X+ w0 D) I. Q/ k8 N& i* Q
    #选择并对比图片
    # }- W0 U; _1 D6 sdef choosepic():
    4 w' l6 R7 E5 R0 }, ^" o    choosepath = tkinter.filedialog.askopenfilename()9 i; u9 W' g- E$ K  v" X5 ?% t1 b+ z( {% C
        path.set(choosepath). j  Y+ u/ {- k3 O" O" G
        img_open = Image.open(entry.get()).resize((530,750))) c1 p$ H6 C+ Q
        img = ImageTk.PhotoImage(img_open)" W8 L3 U) I! e2 k: p
        lableShowImage.config(image=img)1 z7 q0 {1 V; a' u* D5 k( k
        lableShowImage.image = img
    5 X5 t' J1 n4 _    lableShowImage.place(x=30, y=70, width=530, height=750)
    ' m% w2 B' U2 ?1 |" G8 k    faceRecognition(choosepath)$ y! t, V# I1 y1 |6 a# M

    6 Z+ K% \: K. {2 V4 _8 p' gdef faceRecognition(choosepath):6 Y( q0 z( \4 M% @* L) J8 X- |# N
        frame=cv2.imread(choosepath)4 f3 G. I+ C# n& n+ \2 _2 [
        frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)$ _7 H* G6 }: {' Z
        #对摄像头读取的检测人脸& d( r" n  S; E) l$ m" _
        facesLocate=face_recognition.face_locations(frameRGB)) o0 g% a, X% j. K6 w  r- ^
        #进行特征编码, S! Y: t* o) J6 y7 z8 c8 ^6 [
        faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)9 d. m2 ^9 S2 p. k. Q
            #遍历检测的人脸和库中读取的图片进行对比,计算其相似度' ^& X- n( U8 ?, F/ j/ @  h& N1 E
        name='unknow'9 D. f! K! f& a8 J3 U
        for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):
    4 O  v% }. m+ s. }6 P        #进行匹配
    " o: |* m' I7 u; `7 a        matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding). |  K+ K5 l- i; s# _9 E
            #计算相似度% t( L. F/ u' h: D8 _8 V
            distance=face_recognition.face_distance(existsEncodeingList,face_encoding)
    ; Q3 E0 y& ~; T+ U( a% }3 _- s# L        lab='unknow'! |) F! |& H  {  a, J
            for index, item in enumerate(distance):
    8 `' a  t3 _8 O( R2 }  z. f( S           if item<0.5:
    : X+ S8 a- n3 R* A4 s                if matchs[index]:7 i5 F" x* d$ L
                        #得到匹配到的图片名称与相似度值3 s' h: l7 I. V
                        lab='name:{}; Similarity:{}'.format(classNames[index],item)7 I2 n% E+ O2 L
                        name=classNames[index]+ \8 u* L# L* |6 k  p/ D/ ~1 x; e$ C
                        break
    ; }9 U/ I' {7 ]9 B1 H% |( H        #初始化面部捕捉框显示绿色0 T! L9 z! ^- L2 W
            color1 =(0,255,0)  m' e: h; w4 ^9 W# Z
            if name =='unknow':
    . A; F0 c% `9 F' C- s" s            #未能识别的时候显示蓝色
    ! g' n; J4 L* y8 s/ M            color1 =(255,0,0)
    + `$ L  ?6 e! x! y( m, @        #画面部捕捉框, c0 _: f  Q$ B# R
            cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)! n7 r* G: o/ i  V
            #在捕捉框上添加匹配到的图片信息. @0 y  V) ~. i) g# c6 Q+ j
            cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)* X# j, X7 z  ?# X1 h6 f% E0 V
            cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)
    & m6 [% e' o- W    img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))5 A; Z8 V$ x" U+ R$ ?3 @
        img = ImageTk.PhotoImage(img_Recognition)# @! |: V+ e. ^2 C& F$ B! h# w2 S
        lableShowImage2.config(image=img)
    6 B, N  u1 L& v  z9 j    lableShowImage2.image = img" t- F  S" J6 p- N
        lableShowImage2.place(x=630, y=70, width=530, height=750)
    3 \% d( o4 \- |' ]- U% p: H9 ~8 `! U" P- w; C, ^3 M7 S1 W
    if __name__ == '__main__':
    - L! K! U/ Z! Q: y2 J8 R    findExistsEncodeingList(img_path)6 P+ d1 y' q+ G$ P. f
        #生成tk界面 app即主窗口7 z$ o3 z& h3 b- ~/ ^# `
        app = tk.Tk()  
    4 G) D0 X2 s5 N2 A" j7 Y) S    #修改窗口titile! ^) J6 `- ?+ o9 ~& y
        app.title("show pictue")  9 w/ [7 Q3 z6 c2 \9 V1 |
        #设置主窗口的大小和位置
    $ a% a0 e; P- u! }' d    app.geometry("1200x900+200+50")8 U" l6 U" P4 `# D$ c$ N
        #Entry widget which allows displaying simple text.
    : g# z6 o5 I) n$ @% C' Y2 Y  H5 y: |    path = tk.StringVar()
    ( \1 x; R. w2 T    entry = tk.Entry(app, state='readonly', text=path,width = 100)
    1 g- q8 `) ]% q1 z$ ~" q2 ~    entry.pack()
    ( a/ C) I6 ~# K7 t5 ?' a    #使用Label显示图片
    ( s" K) r% O, u$ \! w    lableShowImage = tk.Label(app)8 a2 O9 L& Y( b; W6 S3 W
        lableShowImage.pack()
    / d; W7 Q! U* }, m& A2 g1 _     #使用Label2显示处理后的图片3 u2 d- W2 h! Q" Q
        lableShowImage2 = tk.Label(app): l4 e, ~: ]2 J6 ]2 f4 M* m0 m
        lableShowImage2.pack()
    9 I. l1 c& L/ h! L2 G    #选择图片的按钮
    5 N3 j$ X$ N1 I/ A7 _    buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)8 Z4 J- y) \3 h
        buttonSelImage.pack()& h6 h+ o6 g+ v
        app.mainloop()$ I7 G- t$ F( V3 I8 T, c) y5 B6 k1 I

    7 C, L5 X; t6 U; \3 n; q3.说明' O4 P$ q- P) r- v0 `4 s: I8 X
    首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。
    , g* C7 Q" ?# p4 z8 j
    5 G3 g- V# p! \* H8 W5 G8 e+ B+ W# e: T6 Z3 d

    ! y- E0 B/ Y1 o  a0 ~6 ~" y! y 其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片
    $ A+ v  A1 j+ G7 V% i9 V' A5 B7 y! l5 u2 v; T5 M# z% ~3 x3 j

    9 L& a' r8 ?: Q5 T1 v8 ]; q
    % e  S; v: a3 L6 v1 z$ } 但是效果会存在色彩的失真,效果如下:/ ~) q8 ~% X# O" q7 @6 s

    ; f; Q  ]4 K: d
    : E" A0 ]. S% f- d& y! C
    9 M) M* {4 ^& y# p5 }  i也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。* K) W3 [2 g, V* T/ O# v' _

    5 U8 P: R( A2 a这里简单提下PIL的九种不同图片模式:, U/ d9 M( q5 q

    " V( \& X3 X6 p; F) e$ `( j% Wmodes        描述
    : V( Y( E. C! u1        1位像素,黑和白,存成8位的像素
    1 t+ B3 [" y% s& V4 L  @( tL        8位像素,黑白0 ?4 s, D  m) M: [
    P        8位像素,使用调色板映射到任何其他模式
    * s* `- y) ~' @8 Z  pRGB        3× 8位像素,真彩. M4 ]* [8 U, w5 ~5 f, |
    RGBA        4×8位像素,真彩+透明通道
    9 Q1 X0 k# U4 [& W: M. a/ {CMYK        4×8位像素,颜色隔离
    5 d3 |9 c# a1 z4 R: D  Q7 |YCbCr        3×8位像素,彩色视频格式
    & L  u4 N% q. _; _! z8 oI        32位整型像素
    * A! ~0 Y; U; x5 g+ x- Q) FF        32位浮点型像素
    3 \6 I4 Z) h; G2 b* K8 n4.实现效果' `$ I/ C" i( ^/ l" l- M
    ' Y) T9 V+ T- A2 E( {! U4 P1 }  q
    6 P; t3 }, o% Q) t, @, {

    ( J7 ~5 L9 U- r3 M/ e6 @( W/ L6 O) S! T' G- f2 p* [. Z
    可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。. \& p  u" }5 u: m$ }8 I5 |
    ————————————————
    2 N$ C% i0 V8 K" `0 H3 q版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    & A2 F* G# m/ v8 w原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288$ g% w6 r3 F, u+ z4 j5 B9 J2 G0 Q

    ( P- g# k) ]$ n1 ]# u
    1 X1 ?3 J, H8 ]- ^
    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-9-2 16:03 , Processed in 0.475147 second(s), 51 queries .

    回顶部