QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4147|回复: 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实现人脸捕捉与人脸识别(照片对比)# W2 j  u$ ?% }. O( T

    1 I+ \% x2 z4 |4 E6 ~1.安装包依赖# {) k/ V0 F1 p1 |7 Q  v
    与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。
    ! K6 C: J& G! u3 R1 {
    0 T1 s7 ], d9 D) s# l! t5 [3 H在python 3以上版本tkinter是环境自带的,所以这里不需要安装' x" F7 M, ~/ |8 Z; K8 T  {  [& ~
    % p4 w) `& v7 [1 x
    2.代码示例
    4 y. @) R8 Z! C$ X+ wimport os
    4 ]2 K' e% H6 {: T1 fimport cv23 \7 r6 y: h3 w. V
    import numpy as np
    ; E/ k0 M2 p! X( u& l$ \1 H9 s/ S0 \7 iimport face_recognition
      q, ]' H  H" s- a( y! c5 k) |import tkinter as tk  ' O* t1 j6 Q9 O) @4 w3 t
    import tkinter.filedialog+ k! |4 P, \: J+ L8 I7 e3 C
    from PIL import Image,ImageTk 8 s: m4 K. L9 @: ]3 y
    ! O; j4 f( b0 r' P( N. u( M( |) \
    classNames=[]: {1 @% c2 H' H& X6 G
    img_path='Picture'2 B+ [( O% Q# e9 u/ @
    img_recognition_path='Recognition'- E9 |) l  H# x: Y+ {, i, O
    existsEncodeingList=[]. P8 q0 O8 U3 o6 o$ V
    #对人脸集合进行编码进行处理0 m. w2 w7 I5 }0 K
    def findEncodeings(images):
    7 E" E# F: y+ |% t( w1 {3 f    for img in images:& X% g  i" x& @
            #灰度处理
    ( O: n% g: a% T, U) Y        img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)! H4 c2 d0 C2 p
            #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果
    ! B% o! \) g, k        encode=face_recognition.face_encodings(img)[0]1 H, P+ J8 U1 p: V9 Z6 r
            existsEncodeingList.append(encode)
    * I- y2 b1 S) G' a+ K
    % ?' _6 M  `( k#获取当前存储的人脸编码集合% y4 X! c$ a& h& h7 q2 F% X
    def findExistsEncodeingList(img_path):
    ) D/ b, g: e6 {4 p    images=[]
    / B/ t+ I/ Y4 p1 `    #列出已经上传的所有图片
    2 l+ R0 A5 x  f: t- l    imgList=os.listdir(img_path)) ~/ j  J8 O+ `* w
        #处理存储的图片得到其人脸编码; H3 O! ]: i& {* c
        for pic in imgList:; U9 s7 j4 K( I8 R" \0 _
            img=cv2.imread('{}/{}'.format(img_path,pic))
    9 r: x8 Y$ h0 ~- s; v7 d9 u        images.append(img)
    3 }) J3 @: T9 s- Z. p" D        classNames.append(os.path.splitext(pic)[0])
    9 l  N7 N: u* A  V! A* K    findEncodeings(images)  B8 }; `" B3 z

    / x" D* h8 [4 l& L3 @, d8 C#选择并对比图片, b7 ~* a0 G# M. M+ N; _
    def choosepic():
    1 O" p& }" n+ O! ^5 C$ U    choosepath = tkinter.filedialog.askopenfilename()
    0 g, I; z/ n7 h7 I: G" H& f    path.set(choosepath)0 I' U0 P# n7 w
        img_open = Image.open(entry.get()).resize((530,750))
      t! ~; k( m/ b7 \: t1 d  G! W; X) }    img = ImageTk.PhotoImage(img_open)4 S* s8 b! r9 `" ?
        lableShowImage.config(image=img)
    7 L& F3 Q! C0 i; l7 h+ V1 `4 E    lableShowImage.image = img7 ~+ z( s4 W7 ]: D2 q
        lableShowImage.place(x=30, y=70, width=530, height=750)
    7 Q9 a* {3 Z! n9 ~    faceRecognition(choosepath)
    ) ]" Y7 r3 W4 e" i3 r! _0 ^3 H. i' i: T9 Z
    def faceRecognition(choosepath):
    7 X0 G5 m4 `2 M: @  y    frame=cv2.imread(choosepath)
    1 T' ^3 P% {2 z7 B* r    frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)4 G3 }% }! Y  N* q6 k- p4 d! p
        #对摄像头读取的检测人脸! {7 c" J2 S) W7 j# S
        facesLocate=face_recognition.face_locations(frameRGB)* |! D* g5 T1 A# T+ i6 w( b  H$ ^
        #进行特征编码
    0 Q( F, r; e+ B" ~, Y    faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)
    2 _0 y/ l0 m0 G0 g0 P6 _- x* m, S        #遍历检测的人脸和库中读取的图片进行对比,计算其相似度
    4 _4 d; ^" F$ g    name='unknow'
    + S4 ~0 a2 l+ r% j$ I6 \/ a8 N    for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):" |! J7 |2 G" E) d
            #进行匹配
    ; Y6 A4 |( a0 Z$ e! K4 y8 T        matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)6 L  o1 I3 e. G" s
            #计算相似度' I) M1 P5 }4 I
            distance=face_recognition.face_distance(existsEncodeingList,face_encoding)! q6 ?3 {" q" l7 p
            lab='unknow'- P  F# U6 z, P0 o
            for index, item in enumerate(distance):8 }$ c! O7 f* w' L0 y
               if item<0.5:
    " S* q' i' q" U                if matchs[index]:
    " `3 n5 c* M4 W& D; A" r                    #得到匹配到的图片名称与相似度值' X. _* k$ x. J- z' q
                        lab='name:{}; Similarity:{}'.format(classNames[index],item)" e9 h* s) P. l0 x; E
                        name=classNames[index]
    . _% z; N  G7 `; P% T  R5 g                    break* u0 r& _/ t! E& F: ?# ]/ s
            #初始化面部捕捉框显示绿色
    ' W% i1 r. g; m# |3 V, I" W6 {6 R        color1 =(0,255,0)
    6 {7 U' E! U, x: W. V        if name =='unknow':$ ]" [' d0 s4 R) D3 o
                #未能识别的时候显示蓝色
    - _1 I0 v, K/ k8 Q5 _' E- R: w6 l3 Z            color1 =(255,0,0)
    * R$ n; Q2 v  q/ u; ~        #画面部捕捉框: R" y3 E# b. P
            cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)
    * C3 l4 K1 d0 g1 ~: a4 h. \, u        #在捕捉框上添加匹配到的图片信息
      S3 Y" n5 s7 A$ N        cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)
    % Y2 `/ }" P8 K5 Z2 h0 Y3 J" c        cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)% i; e7 h( \0 k2 _" _' N, r
        img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))" f. J$ n1 C: |. L7 `
        img = ImageTk.PhotoImage(img_Recognition)
      V! G4 E) {/ L7 A# d* s    lableShowImage2.config(image=img)
    ( P1 X% Y) b- y7 W( M  v) K    lableShowImage2.image = img4 o- ^+ ~- q( t% f
        lableShowImage2.place(x=630, y=70, width=530, height=750)3 @6 @0 t* ^! j

    1 s6 C' D+ {3 p$ D& f* Wif __name__ == '__main__':
    9 [$ R2 m8 W- l5 D1 M    findExistsEncodeingList(img_path)2 b9 H* g. b, G% o* w* x  ^- B
        #生成tk界面 app即主窗口' z# s  i5 c. N* `* p. ~/ @( |
        app = tk.Tk()  # S& G' h% F" r" L2 h
        #修改窗口titile
    " C$ Y( G9 B' j, p7 {- V, @    app.title("show pictue")  
    2 K3 h6 p+ J" u5 K  F/ t    #设置主窗口的大小和位置
    2 a; O6 m: \; J: H; k# ?1 d" e    app.geometry("1200x900+200+50")6 y/ b9 c' B  I) X* e
        #Entry widget which allows displaying simple text.0 z7 }: t% o" b* V" e
        path = tk.StringVar()3 W* T) M2 U, e+ x$ x
        entry = tk.Entry(app, state='readonly', text=path,width = 100)' o6 a3 C2 N7 ]* z  C+ \
        entry.pack()
    & a% ]1 K2 R5 H/ h$ h    #使用Label显示图片4 f! {* U9 e: n
        lableShowImage = tk.Label(app)
    # X% g, Q' `! Y. U7 r& o$ d    lableShowImage.pack()- m* ^4 h( |  B! l/ I  C9 m8 j+ c
         #使用Label2显示处理后的图片
    / [5 P( t/ h9 f    lableShowImage2 = tk.Label(app)
    + g8 b6 N# m4 F" s. z    lableShowImage2.pack()
    " ]$ }2 ^- f# o' i    #选择图片的按钮
    0 U& }/ o# D, z4 @    buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)# ]- r" I, f" S" w0 [! T
        buttonSelImage.pack()# S) U9 \6 l- m& F9 D
        app.mainloop()6 a* y2 |2 }5 O7 O* s9 `3 a

    7 R2 _7 O/ _+ a2 i5 p, e/ w- Z3.说明+ g* ]$ E8 J+ \9 w6 d  Y1 E. Z8 C# _
    首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。. [# J6 W# ], C7 q! f

    ( K/ _  e4 I7 i0 f0 Q1 f# m/ i$ g4 g$ N$ r- q
    ! X, s! t! {6 f; @
    其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片
    ! B+ I2 T3 s  q: j9 ~
      S, ?- ?) g2 @3 I, h5 Y4 [& b. X+ T7 Z9 G8 F

    2 F) S# F, V2 a& ]- t1 b9 ? 但是效果会存在色彩的失真,效果如下:* s0 n# w: I1 l( S

    5 M. n% S7 W; f* |7 O+ v
    4 t0 A, q* j, i) R- P  P0 M
    ; J' i( K! [$ o3 |也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。. Z) Y8 c$ s# d) f

    8 T  k+ S& Q! ~# Z9 ?" K+ Z% i9 S( ]这里简单提下PIL的九种不同图片模式:6 l! u7 g) ?! C' S6 B" q5 e& C3 t' Q

    ; q1 ]9 C$ U) Z: ^: `0 [modes        描述0 g! B. N0 y3 R7 q9 {1 u
    1        1位像素,黑和白,存成8位的像素9 }' [' x0 i3 R: ^7 i
    L        8位像素,黑白
    ; T! ^$ }; k6 W  ]4 HP        8位像素,使用调色板映射到任何其他模式
    & F* \4 K# b( w; m8 f! |1 |RGB        3× 8位像素,真彩
    ; w. p+ u; \/ M$ o- t" u* z( kRGBA        4×8位像素,真彩+透明通道, }8 b, Y6 G( b: J
    CMYK        4×8位像素,颜色隔离
    ! Z7 \" f3 i$ P1 n0 iYCbCr        3×8位像素,彩色视频格式: e: P$ U/ K6 C; I2 A
    I        32位整型像素
    ( O; Z# N) P( y* lF        32位浮点型像素6 v4 F; p' z5 N9 S% s( ^
    4.实现效果
    3 f; {  ^( k8 }4 j2 o! h) F6 k: G6 A; d# C# [* M! i& T- Q

    0 Y6 O7 K) |' I. N& ]2 s. x
    + A% B: `* O4 [# q- k4 Y
    ! P% f# ^! N- f. f8 N' _ 可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。) k9 J. [# s8 Q6 N* Y4 R" W
    ————————————————
    5 e, X4 d7 N. l2 {! a版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    $ |; C" N" V" J* h8 l原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288- O* e/ D4 n$ q9 \) T  p# c2 N
    ' r; d9 M( }. U, g* X& N& T3 v+ g3 D
    2 V6 ^  o9 u- a, b1 L1 J* F
    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-4-13 12:47 , Processed in 0.401137 second(s), 51 queries .

    回顶部