QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4216|回复: 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实现人脸捕捉与人脸识别(照片对比)' Q# \) F- S& m9 c$ J

    6 I. e- l# b1 C$ I4 n, n" M9 m2 t1.安装包依赖2 h. D: z' {% k# P- w# M
    与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。  ?: u+ n0 Z. P$ r

    8 J  G6 ], \% e6 i, e在python 3以上版本tkinter是环境自带的,所以这里不需要安装" O+ j5 K1 u4 T) M" i' S

    2 Z  w, s- @/ M5 l9 g+ y* `2.代码示例$ V; N; G  J) ]6 c
    import os" a  p% [0 [) n* ^
    import cv2
    5 D. Q, k3 L, P8 b# Wimport numpy as np  D1 s4 l4 Z( g7 e7 A: p
    import face_recognition8 _* y4 Q2 i1 M) z# O
    import tkinter as tk  7 o8 i7 S: U! R
    import tkinter.filedialog
    ; S  ]& E5 E9 t9 t8 j+ Dfrom PIL import Image,ImageTk 2 s9 r! f. h7 G7 e) [# K

    # p" c* o4 s" g! S; ?classNames=[]
    / |: q" P% C% Rimg_path='Picture'
    8 f% d; ?: [4 t0 [& k) ^img_recognition_path='Recognition'( A$ j, S8 [4 J. W+ W, V1 q
    existsEncodeingList=[]9 G8 `" x+ B3 H; x7 k
    #对人脸集合进行编码进行处理
    2 C. P; p- i/ X* edef findEncodeings(images):
    % ^8 A2 a: \* s0 A9 m% R$ u5 l% i/ o    for img in images:
    : i6 \/ B6 U0 u. I) q, }1 V        #灰度处理
    5 @7 ~- i$ o; \" T% H        img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)
    9 K) J2 @) S  y2 Q* `        #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果, O! m' i/ @5 H$ N9 V3 N' P
            encode=face_recognition.face_encodings(img)[0]
    3 ?0 g8 d. C. l& y7 [2 S) i        existsEncodeingList.append(encode)
    % g" E7 k' E9 @4 H  w5 g# k0 b9 X" J, t4 C
    #获取当前存储的人脸编码集合
    ( k* X9 c! ^" ^  W$ G" g5 S! l. Ldef findExistsEncodeingList(img_path):4 z* t3 t8 X. G+ Y: V! m
        images=[]: H; P* p. D) z9 |" Q& Y+ Z
        #列出已经上传的所有图片
      |$ X# A. `$ P' t) Z8 @5 N9 D' I    imgList=os.listdir(img_path)
    + x% u2 s$ V- J2 G' `' f; y    #处理存储的图片得到其人脸编码
    " {! O9 o1 X: h: u7 @    for pic in imgList:: b( |8 i7 u- E
            img=cv2.imread('{}/{}'.format(img_path,pic))7 R3 m$ Z9 v; l3 @/ C+ ?
            images.append(img)
    ( k/ d7 U2 `& y8 ^+ c. ^2 u5 o        classNames.append(os.path.splitext(pic)[0])8 g' I, R) Z$ D) A: w( j
        findEncodeings(images)
    $ d& @7 T+ T# X' t9 V
    9 [+ p4 l& `$ ], J1 v2 E#选择并对比图片
    9 t& ~" j( R/ c% n) C$ Z  tdef choosepic():
    7 }  Q% e7 {+ ]    choosepath = tkinter.filedialog.askopenfilename(); N, A! W7 b( o' J' O: ^6 Q
        path.set(choosepath)
    ! s3 b+ p; Z- w% X+ k+ z( L5 H    img_open = Image.open(entry.get()).resize((530,750))
    ) f4 w, Y) i6 K3 e3 c/ P    img = ImageTk.PhotoImage(img_open)! @+ f  B& x1 d& C; p+ z; r
        lableShowImage.config(image=img)2 l2 s! A6 S% G3 U/ C4 o- a. ^: o
        lableShowImage.image = img
    ! @" z* c- Q3 t0 G/ e! b) O, R4 K0 ^    lableShowImage.place(x=30, y=70, width=530, height=750)
    6 l7 g, I- k% J& O) f    faceRecognition(choosepath)2 [2 A7 @9 H$ x! V! {
    2 U5 K1 A, o0 \1 L3 q6 r* j
    def faceRecognition(choosepath):9 x& Z1 m  s  Y  ?
        frame=cv2.imread(choosepath)
    8 g  C0 e1 o* w4 j; ~9 [$ c  a% ]% J    frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB). M. w% {4 T+ X/ U
        #对摄像头读取的检测人脸+ U1 E7 ^$ s4 ]: R% [
        facesLocate=face_recognition.face_locations(frameRGB)% Z2 a  [% P. l8 g9 H
        #进行特征编码5 K) I- l, Q  n
        faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)
    1 ^. B" t! g9 |, X7 q        #遍历检测的人脸和库中读取的图片进行对比,计算其相似度1 M7 a+ v) W2 f
        name='unknow'
    & E2 P( Q+ w3 Y: k; p+ V    for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):! O2 \" m, Y* V! R& l$ C- o
            #进行匹配
    ! b$ N/ I9 H3 B. I        matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)
    / Y( p: ^! `. W7 K1 l/ R        #计算相似度9 u" }* i5 F: `' a/ \8 i
            distance=face_recognition.face_distance(existsEncodeingList,face_encoding)) b* f! w1 f. s0 A& M$ \6 E, K% g7 F
            lab='unknow'" ^, B  z: M1 m8 @" _7 C& K
            for index, item in enumerate(distance):
    5 y6 U: H/ @5 o% f) {3 T4 d           if item<0.5:) V) D( K5 `1 }2 y& e& }
                    if matchs[index]:! X; n2 C7 a3 L2 {' b  @7 M/ r
                        #得到匹配到的图片名称与相似度值0 J# g2 Q  p. w. D8 O( s
                        lab='name:{}; Similarity:{}'.format(classNames[index],item)5 K1 S! e8 |0 @% b* w6 U  [
                        name=classNames[index]6 \4 L' e6 [8 n  h8 |& \3 ~
                        break( r$ [0 M% [2 M. Q/ s; U
            #初始化面部捕捉框显示绿色
    1 P& U- p6 B& @6 ~( @: t, L        color1 =(0,255,0)  L# Z6 V  o( L7 \* H9 U- o' P& ^( ?* V; L
            if name =='unknow':
    . J: U9 z" Z7 G9 W& M            #未能识别的时候显示蓝色
    . [6 c4 @6 T: J4 [/ b1 h            color1 =(255,0,0)
    5 d8 @, }# o5 I        #画面部捕捉框
    2 ^- T+ ~1 }' c3 l. \% I* ^        cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)
    " C3 t$ H, ?: p" f* I        #在捕捉框上添加匹配到的图片信息4 t1 Y  b3 n) @) a
            cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)4 u8 k) {6 U7 j& T) w
            cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)
    5 ~+ u1 p& _+ R- G  F* r9 T    img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))
    4 m0 _& ]: ^6 ?7 }& U    img = ImageTk.PhotoImage(img_Recognition). o" d) n( Z: o5 R0 b8 ]
        lableShowImage2.config(image=img)* w# E$ Y5 H+ n& X
        lableShowImage2.image = img" T, K+ n7 ~- S# g
        lableShowImage2.place(x=630, y=70, width=530, height=750)$ l" F9 k' P1 U# i. J# f: U

    4 \. \' q: Z0 N; Mif __name__ == '__main__':
    1 x4 k" |" q7 n9 R* C  w6 \2 P    findExistsEncodeingList(img_path)
    : Z) ^5 y7 i& H0 ?    #生成tk界面 app即主窗口
    5 P  w+ g( j* @    app = tk.Tk()  ! S4 C' Y1 z. l3 L+ t5 _+ k4 v
        #修改窗口titile) q3 {4 J6 d2 i0 L+ x6 T
        app.title("show pictue")  
    + i. v! B7 D8 x    #设置主窗口的大小和位置: o6 i' Z' u9 ]3 B
        app.geometry("1200x900+200+50")
    2 f- n# j2 a6 P0 \    #Entry widget which allows displaying simple text.* j5 v+ S5 x; i3 ?( X; a; P
        path = tk.StringVar()
    3 X4 `) I7 J8 q, b8 n" Z    entry = tk.Entry(app, state='readonly', text=path,width = 100)& D7 M( D) _. n: f2 u5 W
        entry.pack()
    2 h; ]9 W/ w$ [1 X4 R    #使用Label显示图片
    4 Y* |+ O$ f6 N2 E    lableShowImage = tk.Label(app)2 `% b: m. a3 @
        lableShowImage.pack()
    ! W. r( Q& R  q2 u" }1 R     #使用Label2显示处理后的图片6 k) R8 W2 o' G+ A* v5 C. S$ T& a) F7 W
        lableShowImage2 = tk.Label(app)
      n# C8 k  R) X9 E2 O& V    lableShowImage2.pack()
    - K; y3 o% `6 K8 _; N, _  \, E. Q    #选择图片的按钮% }9 p. G! V5 y8 U  I3 P
        buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)
    $ n, X. ^& Y8 M" G: d3 z. G5 u    buttonSelImage.pack()% z* k9 h- w/ s" ]7 ]
        app.mainloop()
    % t& @+ V  b$ K/ X; K. {9 d0 h
    0 H; T! q4 H4 q9 I2 ?3.说明) D+ T' V2 R1 c5 i1 c# Y
    首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。. L& Z  ^% G' f" |4 U8 r& r

    - R6 ^5 L& E8 k$ l+ h. g$ k) k/ I  O8 w9 {) H& H

    ) e: H1 V3 ?# u9 ] 其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片
    2 p" s9 h6 p; H
    - X4 E" a% H" U- j0 F1 b3 k$ K  e9 l* w9 J- H0 c  f9 ?. [" B

    4 [8 i3 ^* G; c% t: } 但是效果会存在色彩的失真,效果如下:% L: _  ~5 F) L+ Y" v
    1 _/ l6 U) F+ D% c
    $ f: K0 i& R* Y* P

      j3 j( h' j/ }8 {2 B也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。
    7 B3 g; U$ f. `% `
    + P, X2 _. h/ D6 ~5 _" y% S+ E这里简单提下PIL的九种不同图片模式:
    ; s+ V, A& R  R+ z+ M' ?5 q/ _
    0 A& J- T8 Y: e' E( `modes        描述
    0 [7 I8 P& \0 D9 A# ?* F. W, p1        1位像素,黑和白,存成8位的像素. c% n2 {) y3 x* j0 X8 m0 K4 M3 X
    L        8位像素,黑白
    ( M. Z# r( t6 x& Z0 eP        8位像素,使用调色板映射到任何其他模式- w: N& u  y' o' X$ a: t$ m4 y0 v. a5 O, [
    RGB        3× 8位像素,真彩
    0 A2 B# k5 d% KRGBA        4×8位像素,真彩+透明通道
    " |* l6 ~& I$ {" d8 R2 D- }CMYK        4×8位像素,颜色隔离
    0 s9 G1 A; l& E6 C/ o! T$ J# [YCbCr        3×8位像素,彩色视频格式
    # k) x" t" Y+ P/ z" xI        32位整型像素& K, [0 D# H. \, h$ C% \6 m6 l$ }1 x
    F        32位浮点型像素
    ; d0 j6 P0 K4 B0 r$ y' m' h3 M4.实现效果" l2 _3 X: q5 J8 ]/ e/ e

    3 B, |2 O% b; z  M  B5 r1 b1 R3 d# ?9 S+ H7 t

    ; \& p( _  @/ Q% k$ ~% N8 x$ X: H& f7 `1 z! m
    可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。) k( c% w1 ?( D
    ————————————————' @( ]/ C7 X( A# A& e
    版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。/ v6 C- G6 V, _! ?& N: R
    原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288
    ) r( F; t; B6 A- m+ ], _% v. \1 z- V8 G" a0 i" n

    # K1 ~' o* r+ n; O/ |2 L5 l
    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 23:31 , Processed in 0.545719 second(s), 51 queries .

    回顶部