QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3786|回复: 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实现人脸捕捉与人脸识别(照片对比)$ \# T% t9 x4 O" H$ h

    1 R4 n6 C. B$ m  `1.安装包依赖1 f. m+ _& Y) Q+ U
    与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。
    4 N5 U" f! l& Y7 B# D$ n% Q
    # U+ e: G( @- b$ d( H在python 3以上版本tkinter是环境自带的,所以这里不需要安装
    5 J$ O, [4 h4 G$ e: v
    % k1 I9 Z( u9 e% F1 d; s+ O2 Q, r2.代码示例5 f" V1 ?# O5 R9 |- n) w9 V
    import os4 M* u1 V0 K# ~1 r/ l( ^# V! U
    import cv2" m8 M2 W+ A% \5 q0 l: c) x4 x
    import numpy as np
    7 H1 p& e$ M( {% p. Q& ximport face_recognition' `! F- L/ w& O" Z1 {. e$ |
    import tkinter as tk  * q$ t+ ]3 z/ d' N- Q% g- w
    import tkinter.filedialog( ]: S2 I" V* h. f1 ^  U3 O
    from PIL import Image,ImageTk
    $ c1 W1 C  k0 j" j- e: D* b& m
    classNames=[]
    : |+ `) E0 @! r1 F; ?4 Pimg_path='Picture'- P3 J& s/ l; g9 }5 c: z6 P" P5 r
    img_recognition_path='Recognition'
    ! h6 U( q- e4 n1 K( G$ d* DexistsEncodeingList=[]
    $ {" d3 M# O, p, S) Q% y#对人脸集合进行编码进行处理
    % x. R) T, t- \. Xdef findEncodeings(images):6 D% C3 \) @) m% j% }; w7 K
        for img in images:
    & n( F" T& i9 W, S$ X        #灰度处理; A8 y! E8 a' L- ~1 V. A
            img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)3 A8 T! }6 u1 e* P! I6 k) j: \1 P
            #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果' ~/ ^' y% R7 Q  N/ ?
            encode=face_recognition.face_encodings(img)[0]
    1 Y$ G2 Z! `& ~1 V$ e- }        existsEncodeingList.append(encode)! S' K; ]. j2 h3 ^& x' o
    ) a0 Q9 i% H8 e3 N* S! ?
    #获取当前存储的人脸编码集合
    - @+ D6 k& f9 D. {" `$ mdef findExistsEncodeingList(img_path):1 U* y, b  u) Y$ x% \1 Q0 Y
        images=[]
    . u  p! g' J: q3 e. a# K    #列出已经上传的所有图片
    / s; E- x4 s4 Y: c  Q  C/ ~3 X4 W/ t    imgList=os.listdir(img_path)3 N! |1 v, ]% Y/ a
        #处理存储的图片得到其人脸编码
    , c! m+ f% h7 m; E( e& {: e- b    for pic in imgList:
    % F6 B/ u! m7 d1 [        img=cv2.imread('{}/{}'.format(img_path,pic)): R7 `% S' r5 a6 O- J1 K) o
            images.append(img)
    ; o# c" f$ t7 }8 w# [+ D# h        classNames.append(os.path.splitext(pic)[0])
    % j! `0 b0 N5 V, P' V4 G: I2 \    findEncodeings(images)4 X4 P+ I% V* p0 q1 _
    $ g& k8 M( T. e
    #选择并对比图片
    9 ^8 |2 Q3 H8 _+ O: S+ g) |" @$ Ldef choosepic():
    2 G* H6 N- @6 Z' b9 H% [* x" I  b    choosepath = tkinter.filedialog.askopenfilename()1 c9 D$ k8 L7 p3 \; Z
        path.set(choosepath)0 ~9 h8 M- |! r/ {" R; C0 r$ W( X
        img_open = Image.open(entry.get()).resize((530,750))
    . f7 C0 k  v& r) H, j    img = ImageTk.PhotoImage(img_open)5 Q7 u- x. l. y3 A' R" y
        lableShowImage.config(image=img)
    - d& Y" R( e: q- o5 X, @5 W- G5 b    lableShowImage.image = img/ w* q' a. w9 f( G* Z' D7 I! C
        lableShowImage.place(x=30, y=70, width=530, height=750)
    7 S; B' g" H6 v! \2 w    faceRecognition(choosepath); m# u; {1 y4 c& _# R$ Z
    - n( o4 Y) U7 P9 A/ y  p
    def faceRecognition(choosepath):) N4 G4 h' g) [+ c' H$ I- g7 E
        frame=cv2.imread(choosepath)
    / g4 m8 c1 A- K# v# j1 l1 J    frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
    , G: p% f- p; _7 U# K* s& P" C7 e    #对摄像头读取的检测人脸$ d$ W4 o# V% @' y  N( Q
        facesLocate=face_recognition.face_locations(frameRGB): u$ c( I+ U. ^+ X0 f$ k
        #进行特征编码
    ' z, e- e3 s1 P# H2 |+ U# f    faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)# k/ n) e" ~( z% B
            #遍历检测的人脸和库中读取的图片进行对比,计算其相似度3 O8 d1 N- `+ R% Y7 y
        name='unknow'
    ) s+ [9 d1 J  n" g( W8 v    for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):$ N+ c4 w4 S( y3 s" `3 G& h' V( C, t
            #进行匹配$ O8 t0 ?' r& I7 X, Z0 Q" Y7 h
            matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)
    & i8 i, e/ w: K; F        #计算相似度8 ^3 o( H/ Y7 Q5 z- I6 }
            distance=face_recognition.face_distance(existsEncodeingList,face_encoding)
      i$ o3 v& v; B9 p        lab='unknow'
    2 a5 Q% N2 m' W+ W( |  S' y        for index, item in enumerate(distance):/ u' Y' e0 p& D3 Y- C$ U* t) B
               if item<0.5:1 N" q$ ?( l- \2 m5 g5 ^
                    if matchs[index]:
    , ?: I8 R( ]: x2 q) l% n                    #得到匹配到的图片名称与相似度值
    3 Z( Z4 M. p( ]( I7 ]. V, q5 R1 s                    lab='name:{}; Similarity:{}'.format(classNames[index],item)
    * e. F# Z* d1 C2 y8 x" _2 {) y                    name=classNames[index]0 C- g+ W8 M# S# ^' |
                        break
    0 O! ]  a' v7 K1 N/ I+ ?        #初始化面部捕捉框显示绿色
    " o# h+ s2 N. `  {* g% C/ ~        color1 =(0,255,0)
    * `, B6 E2 X+ Q$ x* j8 }- Q5 M! {        if name =='unknow':; |+ `1 ~0 ]/ U  K' W
                #未能识别的时候显示蓝色
    / d) o0 e7 J0 r. p- z            color1 =(255,0,0)
    + g& W& [: J2 W6 ]% p        #画面部捕捉框
    8 p. y' I/ K" N- ~3 ?        cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)5 p% ~2 X) x/ _2 n6 h9 ~
            #在捕捉框上添加匹配到的图片信息1 M' e) J" j# i0 G. _
            cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)
    % A% q- C5 D- z* t) m        cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)
    2 ~1 B( j+ i, X. S1 U    img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))
    4 e9 p" B/ @2 e5 `" M1 a    img = ImageTk.PhotoImage(img_Recognition)) v4 ~& Q! g4 o+ Z8 x% `: ~
        lableShowImage2.config(image=img)
    $ |* H# X/ h0 H2 G0 Q    lableShowImage2.image = img
    / K& \( r5 v1 x' x$ P! M! u    lableShowImage2.place(x=630, y=70, width=530, height=750)
    9 z0 O' s0 t- I; N2 F, v" w6 M3 a
    + i2 o2 H4 u5 y2 k; {if __name__ == '__main__':9 M9 a7 n0 m3 K- H- Q3 m
        findExistsEncodeingList(img_path)
    ( s  Y7 G6 k" \    #生成tk界面 app即主窗口
    3 v6 p. z! L1 r4 n3 M' G2 a- o    app = tk.Tk()  $ b: C& W1 o/ ]" L  O
        #修改窗口titile* @# d, j( z) _4 ]9 o, ~+ R4 w0 I- |
        app.title("show pictue")  
    1 e$ Z4 a( Q- w7 x5 n, c0 D    #设置主窗口的大小和位置0 p" j0 {1 ^% i
        app.geometry("1200x900+200+50")! k) T7 r. b# P2 ]
        #Entry widget which allows displaying simple text.
    4 X8 q1 G: L  N, _    path = tk.StringVar(). s4 u5 t- `" T9 a/ N% o
        entry = tk.Entry(app, state='readonly', text=path,width = 100)7 [, R- r4 C' n: l
        entry.pack()8 x. _. }# \7 a: ]3 F
        #使用Label显示图片+ g, x7 z0 b2 N! W4 n, G
        lableShowImage = tk.Label(app)% O& Y5 _" O" i$ l! N
        lableShowImage.pack()0 ~3 O6 I& K2 Y7 k) C
         #使用Label2显示处理后的图片; s- G3 z; q1 e$ }4 a) Q
        lableShowImage2 = tk.Label(app)
    ' V# E& Q2 S6 t7 {# i/ E) Z    lableShowImage2.pack()
    0 K" z" X4 {. v" f/ C- m- A    #选择图片的按钮
    , H- v, U/ ]- p    buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)
    5 `& Z# @4 \3 W/ q    buttonSelImage.pack()
    ; }! t/ b+ B; V! `' \. D    app.mainloop()9 w! e: {8 a* ]; t3 u$ ~' m

    5 W+ R! J) w0 j! ^3.说明* ^2 v+ r2 b7 S, S
    首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。) \0 w. t- i( G1 i7 O2 {' [1 n6 @
      F) s9 s" d; a/ B

    8 \$ F2 {# z! j! N- U1 `; Z9 y9 l7 P& Y) S4 }( R- S
    其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片; @8 t+ k) w$ s

    % C9 L' k: \6 _9 x
    . E1 X4 v# o. W" K; B& G+ p+ j4 V9 e. s3 S( O7 t
    但是效果会存在色彩的失真,效果如下:3 y: K/ L' F; \4 q  G0 H6 n

    & B* _* x: l! ^" C6 P. o
    & n' N: E8 s% r! V( w6 \' D, X. `8 S) J6 _# C1 i  a% b2 }" `
    也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。: M1 G; \4 J  a7 W% R. N( Y

      f8 v7 I) G5 y7 E" ]6 L9 g6 T这里简单提下PIL的九种不同图片模式:' R) [4 r" e% x
    / ~, Q9 X8 F+ V& B) w% s8 w1 S  {! f
    modes        描述
    8 l! f* k+ Y8 k/ }6 N+ c& }1        1位像素,黑和白,存成8位的像素
    $ m) }  z1 n( sL        8位像素,黑白* D" x% ]0 e; W6 K! ~' v
    P        8位像素,使用调色板映射到任何其他模式
    ; k' }& t7 [& c- C' w* dRGB        3× 8位像素,真彩
    % L( i5 T0 d9 W% ~3 R( iRGBA        4×8位像素,真彩+透明通道, j3 Q/ `+ \% E7 t, p8 d0 ^: r
    CMYK        4×8位像素,颜色隔离
    : ^2 L  L/ s5 v5 o  t1 L' k2 I' QYCbCr        3×8位像素,彩色视频格式
    ( Y' n- ?- Z0 I, d9 D5 i6 g! [' pI        32位整型像素% b& ]" v! t+ a2 I4 o, [% E3 p
    F        32位浮点型像素
    % D8 q% T5 X, w9 [# ^8 j( `4.实现效果
    7 f- n( z( F' ~) F0 M1 U+ E
    9 v: W4 S- \9 R7 g+ _# Y( U: a
    ( F, c, o" t& t  m- L. k. S- A$ G! Z& Z1 Y: p$ ^7 h) j
    . b7 D) R6 ^6 o/ k
    可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。# f3 |7 Q8 @* t, z
    ————————————————
    6 e2 a/ `5 x- v9 R版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。( S# h3 B( Q& h+ q1 q  ~4 F
    原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288
    1 F- r$ f% y/ c' }" S7 O
    1 L/ k6 ^- ^9 g' h2 S) F; g/ S  l, ^) G& Q
    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, 2025-11-22 20:14 , Processed in 2.270533 second(s), 51 queries .

    回顶部