QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4189|回复: 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实现人脸捕捉与人脸识别(照片对比)* X- }6 R1 E6 h! D) ~+ Z. B
    8 P/ f- L8 h* w4 _+ @' }" q
    1.安装包依赖. m/ e/ J: ~+ T; ^% @) X- l6 b
    与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。
    ( q, ]% q' H2 f( U2 }; o; p" q' _( s( @* o9 ]) o9 G
    在python 3以上版本tkinter是环境自带的,所以这里不需要安装
    $ z0 H+ j2 p+ @8 \) u6 _$ _# f+ Z. G4 R# u# A. ?/ [5 Y) e
    2.代码示例
    ) {% r& P3 {( e5 E, ^import os0 k8 U# {6 R- u5 K, O: T
    import cv26 M0 J! c6 Z/ t7 y% q+ X+ Y
    import numpy as np+ Q% P6 K2 I& h% O  T" |2 a% r8 Z
    import face_recognition
    # w; _% H6 e5 Z  n3 Cimport tkinter as tk  
    3 P2 L9 O3 N4 b2 vimport tkinter.filedialog* ]) m5 Q: _. S: O+ t8 W
    from PIL import Image,ImageTk 5 r1 V& Y0 k4 J4 T3 Q! N( t

    , m" I: H4 n# B$ H' b9 }* X3 _% h0 wclassNames=[]/ |" Y3 X# j( N3 S, d
    img_path='Picture'
    8 z3 p% T. l, D7 Uimg_recognition_path='Recognition'
    3 n! v4 h; R1 @; qexistsEncodeingList=[]
      Q$ z$ y4 H  t5 a8 D9 M& x#对人脸集合进行编码进行处理
    , j/ P( X4 y' t3 ?; r/ Qdef findEncodeings(images):% R8 {0 H. x4 W6 p' \
        for img in images:
    % m- a- n+ ]0 _( v* h& \        #灰度处理
    + \" n0 O& D( Q0 |6 H$ i& q        img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)' A( I/ L  Y8 l# [
            #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果
    4 M' t1 S9 ~% b- w/ A- W        encode=face_recognition.face_encodings(img)[0]( B1 _8 |) I6 ^" U2 g- Y4 H
            existsEncodeingList.append(encode), g5 l. G3 t# B  s
    1 t. I; L8 v/ x/ T* U
    #获取当前存储的人脸编码集合" j7 h! i- @# {/ P
    def findExistsEncodeingList(img_path):1 U! w  r( A8 V, E: h8 s
        images=[]
    7 r8 g' Z/ B( U9 H, f( W    #列出已经上传的所有图片! S5 t+ k5 q2 s0 W( Y
        imgList=os.listdir(img_path)
    ' a  q' z  ]9 s2 A) O: H    #处理存储的图片得到其人脸编码
    # `% c) P2 p3 l# ]' E' H0 g" G    for pic in imgList:/ ?, W+ \% w8 W: S( a
            img=cv2.imread('{}/{}'.format(img_path,pic))/ A# z* u$ X9 ]6 [; o( q
            images.append(img)9 a0 w  N3 e6 r) C& B5 f
            classNames.append(os.path.splitext(pic)[0])
    & Y& j2 E, D+ x) G# M% p0 a0 r    findEncodeings(images)4 j$ X0 M5 ]* |- F

    + ?3 _" S8 D2 {8 R6 I* E1 }#选择并对比图片
    1 D; O6 S* B3 f* T2 a3 ddef choosepic():
    : l: [# _; n) F0 P0 m) j/ O9 ~    choosepath = tkinter.filedialog.askopenfilename()
    8 m8 r  [6 [8 u: a* D: F9 U) O    path.set(choosepath)
    ; g+ V  a# ]! l, y1 m    img_open = Image.open(entry.get()).resize((530,750))
    ( X5 k; _% G8 N" L& y0 Q3 }  N    img = ImageTk.PhotoImage(img_open)# }0 k- Y- a; a$ i  s% v/ A3 ?
        lableShowImage.config(image=img)
    % p" R2 o8 S+ [  L- c+ |: X    lableShowImage.image = img5 v* I% `! n$ _7 D
        lableShowImage.place(x=30, y=70, width=530, height=750)) y5 H5 G3 m* C+ C' q
        faceRecognition(choosepath)$ \' o: P1 H& j0 @! S/ B

    9 a8 Z3 u2 s4 o& Qdef faceRecognition(choosepath):
    ' I+ g5 \* ^" P! F) C0 n+ |4 |    frame=cv2.imread(choosepath)3 g% v3 ]3 D3 z/ ]* ]# v
        frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB), M- e) X! ^/ I4 o% e6 p" Z
        #对摄像头读取的检测人脸
    6 q& Y% Z7 T9 i8 v1 a    facesLocate=face_recognition.face_locations(frameRGB)% ~0 ^/ b2 ], @8 Q
        #进行特征编码& d6 m) C: H+ X8 T+ Q6 q  p1 B
        faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)3 |" S! B5 h, d6 N5 R
            #遍历检测的人脸和库中读取的图片进行对比,计算其相似度( z; w3 K. F# c, D7 ?. N. K
        name='unknow'3 u2 L' s+ ^* t' K" ?4 h+ Z
        for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):
    2 P; U& i' \3 U: n/ o+ i  i, A  r# C6 f        #进行匹配3 o. J; S1 p2 {  P4 b; D
            matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)
    7 k# \# l- w2 U5 I5 v        #计算相似度
    9 W8 Q6 F: J: {% ~        distance=face_recognition.face_distance(existsEncodeingList,face_encoding)
    " J4 {$ J! o9 a+ o, l        lab='unknow', g' F& `) u) O& i" ^
            for index, item in enumerate(distance):
    , K: r& ]0 U4 v8 P' Z  I; s4 Y           if item<0.5:: L8 E# O9 f9 `5 B
                    if matchs[index]:5 E9 h1 h8 \! u
                        #得到匹配到的图片名称与相似度值
    & g& B; t7 j5 h9 K# `                    lab='name:{}; Similarity:{}'.format(classNames[index],item)
    $ C2 m) {! D2 `  s& |' y" y                    name=classNames[index]  B  i% T- {8 k7 ?
                        break# \3 T0 H; `! o9 [5 `  s
            #初始化面部捕捉框显示绿色
    & A( g. B9 W4 q        color1 =(0,255,0)
    1 _2 C+ ^* |1 Q2 Z+ W# D" q' q        if name =='unknow':
    " x& q0 v) f2 |' Y9 o            #未能识别的时候显示蓝色
    " ]# G& p" f0 g6 e4 Q. J" Z            color1 =(255,0,0)- T3 K3 o$ F/ X' v! C9 y+ A. M8 o
            #画面部捕捉框8 }+ L' \4 ?3 F4 q$ y! g; D2 i
            cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)" _6 W3 w7 T9 w# @; J
            #在捕捉框上添加匹配到的图片信息
    0 \, K3 M& _  m% Z! o% k- z6 V        cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)
    & @3 }7 x, U  G" y, B        cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)9 x  O. x2 p0 p
        img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))5 Q/ ?! g4 j1 A) \( z  Z! Y; v/ K
        img = ImageTk.PhotoImage(img_Recognition)/ W. x; Z( ]; g+ `' @, g: `
        lableShowImage2.config(image=img)6 i& c2 B6 |! w3 r
        lableShowImage2.image = img. z( v8 ~: s; Q# t
        lableShowImage2.place(x=630, y=70, width=530, height=750)- G8 ^0 t( o3 |) J/ G; f

    % U. E. y" R) r# cif __name__ == '__main__':( q. S2 i0 A8 X1 t3 ~" W+ z$ Y
        findExistsEncodeingList(img_path)
    ( p8 [& }; |8 ]* s& ]% ?2 }    #生成tk界面 app即主窗口+ e9 f# \. ]7 [8 N: y
        app = tk.Tk()  
    5 A4 Y! ~2 S- @5 |    #修改窗口titile
    3 n) V7 i% U' k' [  t    app.title("show pictue")  " s: M$ Z- L+ @! r
        #设置主窗口的大小和位置; C$ T' ^" G0 Z: q. j7 e# \) k
        app.geometry("1200x900+200+50")
    ) L- ~4 t$ l1 d: g3 M    #Entry widget which allows displaying simple text.
    * Q. J4 {# N) A    path = tk.StringVar()
    ' L; m" k: g4 {3 _    entry = tk.Entry(app, state='readonly', text=path,width = 100)
    ' Z' v- F, X" Y2 Y    entry.pack()0 A5 r6 a/ X, g' G+ L) t
        #使用Label显示图片
    ! m/ s1 @) x3 d    lableShowImage = tk.Label(app)
    ! _7 z9 t. k: V( x/ _2 z8 M* F8 e    lableShowImage.pack()
    ' {1 M/ [1 s) |( x; D. u  z     #使用Label2显示处理后的图片
    2 f( K1 q( J7 _    lableShowImage2 = tk.Label(app)
    3 J# r3 e8 y; G/ W" ]- y    lableShowImage2.pack()  D$ ]; T1 E0 \9 o+ n
        #选择图片的按钮
    ! @6 s1 O/ _  O9 r& g6 I' d. J! R    buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)
    9 h9 ^4 c7 }: P5 B2 B    buttonSelImage.pack()' U) `# \7 c, ~, o' H
        app.mainloop()6 y( p* ~! J9 M, n1 A: V

    / R# c. P. O5 e$ I0 i1 H, J. X3.说明
    3 e6 r* s9 y2 p" V6 H$ c$ S) ]首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。: p; T6 m/ E. N% O- M
    " s' H0 x+ M' B4 U! g. P
    7 `+ K3 D3 {: W) e! f7 m

    3 C. y& o& }. |. X8 P9 }+ o$ J 其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片
    . {9 ~; m& j0 Q0 i, J4 ^  Q$ v; B6 g. x" S+ }; z
    3 y. A! }* F8 U, z  z+ B0 i  w
    - c' n( B& q* A1 u: ]
    但是效果会存在色彩的失真,效果如下:
    & g. ^" _: w3 x! W7 H
    5 G/ ~5 c' q! @* E& n1 D
    2 n, D9 v2 q$ b; \4 s* k; E  s) G6 D5 w
    也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。
    ' x! o! j$ K" X8 n, n: I+ |+ ?+ M6 z) c/ A+ I4 t. H9 N' M/ `% s
    这里简单提下PIL的九种不同图片模式:
    ; V8 A, E: c, B/ Y* ]. `* o
    8 ~% F6 V3 B% c$ y  ?* }6 z2 _modes        描述# ?' I) Q& I1 Y+ v
    1        1位像素,黑和白,存成8位的像素
    # e* x6 Q$ p: P" T' z- b: iL        8位像素,黑白
    & n! Q) |0 ~2 U) T8 pP        8位像素,使用调色板映射到任何其他模式: i' f1 o8 M& Q6 h' G7 Q
    RGB        3× 8位像素,真彩
    ; S* D; j" C% M" f0 {0 K, k& QRGBA        4×8位像素,真彩+透明通道
    5 x/ A9 H( A1 Y$ n. |+ ~CMYK        4×8位像素,颜色隔离1 @7 h" y0 A; h; o  c
    YCbCr        3×8位像素,彩色视频格式' M9 y  h5 d& b7 G' D% M/ `3 w
    I        32位整型像素
    4 `3 J: K- p2 I# h* f; A0 F( ]7 d: eF        32位浮点型像素) ?2 R, A" X) e$ I# u* y9 h0 b
    4.实现效果; `$ @3 T; c9 F6 {
    : w2 q+ \, r- T, @

    0 g& w3 B2 {6 Z1 H/ I# k/ d) L+ |) L1 h: b, z) S
    " D9 D( K5 p% c3 z2 N, j: e
    可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。7 p: [& i5 a3 s
    ————————————————
    . F7 o2 n4 i' Y6 U4 ]版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    / k( W* x9 S( D5 g原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288/ {, A* [$ `8 v+ e. N# l

    8 N$ \! [9 Y7 f9 ~( U7 W5 z4 S7 Y( ?
    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 17:03 , Processed in 0.396634 second(s), 50 queries .

    回顶部