QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4172|回复: 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实现人脸捕捉与人脸识别(照片对比), h3 c5 u" t) Q

    * V0 m! q  t: |" a/ D1.安装包依赖% y6 b5 r+ F" F5 J' `3 {9 [% B
    与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。$ N7 u" }2 l! `! w) x: i" x7 ^

    - ]6 Z* V1 k4 i7 J8 x& B* n0 |在python 3以上版本tkinter是环境自带的,所以这里不需要安装: u+ x) k1 ~$ ~0 P* ?5 Y- J

    ( I3 W8 j$ Y0 e  I2.代码示例
    + ^9 W1 Y1 i8 r) K- x' yimport os
    ; S6 M+ v# v9 [import cv2
    * g& I8 J# Y3 eimport numpy as np
    4 H" b& ]3 ~" H; eimport face_recognition
    * A& i. B& ?& a$ Vimport tkinter as tk  
      x) K) S/ w0 f" r2 r/ aimport tkinter.filedialog5 q4 L( `. |4 `$ u2 C7 p
    from PIL import Image,ImageTk ) f. R$ |/ E! r* |1 m5 c
    0 H: ]% ?# ?& W& S/ L& i8 D
    classNames=[]
    ' J% D3 J$ R0 U( g& S1 D2 _( Y3 iimg_path='Picture'
    3 Q4 b: ~/ X+ Y* u3 [img_recognition_path='Recognition'
    $ N" n/ _5 i2 I' ]7 V( iexistsEncodeingList=[]
    8 [7 x3 D6 G* b& S6 N( Y# ]9 }#对人脸集合进行编码进行处理
    $ G; u) v, |  }. ^0 k" O) Ydef findEncodeings(images):
    2 @& b+ N6 J! e" ]# j6 V    for img in images:2 O9 {) C0 v) o" z  T2 F+ ?5 U' J
            #灰度处理
    . G' _0 s2 G: H# F4 i' R        img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)2 `* Q# W. }) U+ h7 t% Z2 q
            #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果
    , E; u9 o9 o1 n        encode=face_recognition.face_encodings(img)[0]
    , o/ C+ v8 V; ]+ w        existsEncodeingList.append(encode)
    ( y) q! q) C: x% N6 t- M4 p0 b* A+ P/ n, G  ^
    #获取当前存储的人脸编码集合0 s! N, m$ ~0 i( k2 ~: B
    def findExistsEncodeingList(img_path):% F% `$ f8 \, @6 A9 \
        images=[]& O  C/ p3 V! F1 c
        #列出已经上传的所有图片: l+ U, h! W0 s1 i" f
        imgList=os.listdir(img_path)8 J, e  Q) J$ ~. S0 Y' T
        #处理存储的图片得到其人脸编码
    2 {- Z. a$ F& K$ T7 Q" J, H5 R    for pic in imgList:) J* G8 c- ?$ y/ I6 m( m
            img=cv2.imread('{}/{}'.format(img_path,pic))0 S! p5 T0 p; `7 X: S9 S
            images.append(img)
    # |/ z2 ~" c/ f        classNames.append(os.path.splitext(pic)[0])
    8 ]! ?. s* ]1 m    findEncodeings(images)
    ( f0 O# F, p* x5 J* t
    2 _& ~9 P3 q; A  f) u5 n2 x#选择并对比图片
    3 t3 ?9 K9 U& q8 edef choosepic():+ i8 v0 ?6 g. c6 v. A: \
        choosepath = tkinter.filedialog.askopenfilename()/ P4 N6 m0 J5 Q/ _6 a7 d
        path.set(choosepath), x. T, y; }6 P! [3 e; G$ Z
        img_open = Image.open(entry.get()).resize((530,750))
    . m# l  r* R' G; ~1 L    img = ImageTk.PhotoImage(img_open)
    ( J1 T$ n; d" z2 {4 c4 Q- f    lableShowImage.config(image=img)! m3 N6 w9 G8 e' h; ^
        lableShowImage.image = img
    ! N% K+ F0 \( V) q+ k9 y$ X    lableShowImage.place(x=30, y=70, width=530, height=750)! B. w' ^: h5 |, H& d
        faceRecognition(choosepath)
    5 S, J" V- j8 j$ o/ \' D! J% F- \" O' f: l) o) H. P
    def faceRecognition(choosepath):; b1 o1 {$ H9 w7 w8 h' O
        frame=cv2.imread(choosepath)
    : ^1 u" O0 r. r% z$ x6 K6 S' k5 u    frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
    $ k  Y0 [) G& K    #对摄像头读取的检测人脸
    ; [; O; ~/ _; T0 e6 U1 V) Z$ @    facesLocate=face_recognition.face_locations(frameRGB)6 u; R6 d' ?1 e3 e- R- Z- V& ^
        #进行特征编码
    " n6 s8 K* x% O% e    faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)2 s, l9 P, B( ^0 O0 V
            #遍历检测的人脸和库中读取的图片进行对比,计算其相似度1 Z" k4 |( |1 \: _8 d
        name='unknow') Q* v, e7 _3 [# t
        for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):) R4 ]* @8 `; Y4 p0 z6 q9 k
            #进行匹配5 R$ Q+ W  A2 ~: c; y
            matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)
    5 W3 D' _: M9 J        #计算相似度
    ) b- s4 G+ U! x. c9 p$ v! J- p5 d        distance=face_recognition.face_distance(existsEncodeingList,face_encoding)
    $ v8 n  Z3 x/ g- @) s) p        lab='unknow'3 q% N5 F! k" C; B2 X' l* v
            for index, item in enumerate(distance):" F" [7 M& z9 B; y. Q2 }( }& m
               if item<0.5:) m, X# ^; @1 N9 P
                    if matchs[index]:1 T1 \$ e6 g- H. }3 H4 `5 g4 w2 _
                        #得到匹配到的图片名称与相似度值5 Y; y8 i0 ?2 s) g$ ?9 C
                        lab='name:{}; Similarity:{}'.format(classNames[index],item)
    ! |. Y5 Z+ _3 G! a                    name=classNames[index]
    : C* [! v6 j% P. M( a                    break
    ' y) j* F% n/ m6 _. k. U        #初始化面部捕捉框显示绿色
    " r+ c4 J, _  v- K        color1 =(0,255,0)& ^: X. v% m6 ?* D- q( l
            if name =='unknow':* u8 d; ^; r+ e4 i
                #未能识别的时候显示蓝色! i6 _. C# k8 W; Q( c
                color1 =(255,0,0)
    / J6 f3 U- d1 G8 h6 U( ?        #画面部捕捉框  h" W- o( Z, q4 w, F! G2 N
            cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)
    1 A' A6 [3 }3 F9 b- b        #在捕捉框上添加匹配到的图片信息  O# \3 w+ ~% }  t5 F% z- c  y
            cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)4 I) Z0 d3 J* A: {2 q) |9 W$ A
            cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)
    ' I1 c; e. H& U. H2 p; ~7 I$ C    img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))
    7 {, g3 I" R4 w5 @8 L    img = ImageTk.PhotoImage(img_Recognition)
    3 o6 n9 \" z4 W) a0 W2 U; {9 x  n    lableShowImage2.config(image=img)
    % o4 R0 C( Z1 e: a' d    lableShowImage2.image = img: Z7 i1 t1 x! n& h) b7 u
        lableShowImage2.place(x=630, y=70, width=530, height=750)
    * `6 a3 d, O9 ^: |0 p5 e( @+ m4 R1 l& J; K1 E- F
    if __name__ == '__main__':0 k" ?! t- i1 @
        findExistsEncodeingList(img_path)- \/ W5 p" t/ P% W
        #生成tk界面 app即主窗口
    * L8 Q7 I- H4 V" z' u! B- p& g9 N    app = tk.Tk()  1 p4 Q5 q, k6 W& q: i8 l/ g7 f
        #修改窗口titile8 R! \9 m4 W/ q
        app.title("show pictue")  
    " F8 r" m0 K! ~7 s    #设置主窗口的大小和位置/ H0 t5 \, b6 W3 n3 R
        app.geometry("1200x900+200+50")
    ; N: V. v2 n2 D    #Entry widget which allows displaying simple text.+ j; z& P& S! k1 X
        path = tk.StringVar()  k( n3 M& J  a0 n+ D% F
        entry = tk.Entry(app, state='readonly', text=path,width = 100)8 X5 d8 K' P4 \* g' l4 ?
        entry.pack()8 s! _6 @& m2 D* ~# O/ N2 T
        #使用Label显示图片6 k: ?! @5 j2 p/ {' P! F: T
        lableShowImage = tk.Label(app)7 t5 J, t3 X) z3 r
        lableShowImage.pack()! Q) u2 t! r* S. `- {
         #使用Label2显示处理后的图片+ a5 Q5 B8 b# j& `( z8 n
        lableShowImage2 = tk.Label(app)
    1 T* B) W6 j; {! K! |- f' N    lableShowImage2.pack()  l3 N. g8 r, E; Y/ T; O. I
        #选择图片的按钮4 Y% ^5 ?6 I: S! v3 Q! O( I
        buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)9 f0 n4 H4 x5 b8 Q/ c" K& o
        buttonSelImage.pack()# d5 ~+ i; v, ^" [
        app.mainloop()5 ~9 `: ?. z; E

    . x: I3 @3 ^, [0 w+ m1 q3.说明) t: p- w% o; Y7 G- k. R& M2 Y
    首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。$ Z: n' [; N  t& _9 E

    7 S( R) [# B/ Z) o* I9 |; x* D7 @* b8 Y* O, y* m
    $ r$ ]: Z7 P  b: @2 _# h3 {; J9 B
    其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片7 T' s& N( R# x) j% V( J
    & d3 X7 l) h: E. o& V

    8 \! p2 x$ l/ H3 v: H& U
    / t, V/ J3 l  T& l+ ]. B1 N$ L 但是效果会存在色彩的失真,效果如下:
    # V2 L; q/ X  y' m( x* d9 X+ B5 X+ t; e" L6 _" B( J3 {

    & ]- P# E8 A/ \) j2 i: |/ {, ^- v9 @3 Q0 I# U) Y
    也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。
    ' V' H( I% u7 i
    , f  [2 t/ H" y# D8 K这里简单提下PIL的九种不同图片模式:
    - m, ^9 g/ @1 P, l- v, |) c+ g) G3 X, w* Y9 Y* I  ?- i& \1 B
    modes        描述  Y! O5 B9 ^2 j  N0 A$ v
    1        1位像素,黑和白,存成8位的像素
    % p: T7 |0 j" ]0 D  Q6 eL        8位像素,黑白) ~1 _% z" ]  v& w+ M' q
    P        8位像素,使用调色板映射到任何其他模式
    : F! D) d2 b4 x/ bRGB        3× 8位像素,真彩
    $ K5 z" z9 M% P3 G. P, f; zRGBA        4×8位像素,真彩+透明通道0 m+ ]" H$ y- v3 z& G) }. {2 A
    CMYK        4×8位像素,颜色隔离
    / S$ k2 C! M/ n$ J5 n, B3 K0 YYCbCr        3×8位像素,彩色视频格式. z0 v& ]$ s" x& [# B
    I        32位整型像素
    $ m0 u( Y3 f$ uF        32位浮点型像素- b- }( o8 r  _* W2 d4 h2 _4 b
    4.实现效果
    1 a+ c) ~; G' h7 E* [, k& ?* ?6 l
    0 u9 C$ H% A" y' w& K' r
    4 l6 r; Y  \  b: C* |" e* q
    ) K1 X6 g- G- {2 W; f6 c2 g3 h: r& W7 {" l! |8 |6 @
    可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。
    & X, t$ P6 y  |4 c4 D- h$ U————————————————
    9 U* t, I; m! i2 ?% W* ?8 \1 }版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    : R  e$ d# c  b2 _原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288
    $ S6 L) k5 i+ P' O* ^0 n1 A1 |: o4 e% D4 d+ d7 R1 A' O- M5 K
    / @( C0 f0 V2 e5 e; O
    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-5-27 01:47 , Processed in 0.450401 second(s), 51 queries .

    回顶部