QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4144|回复: 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实现人脸捕捉与人脸识别(照片对比)' V- l8 y! \3 \8 B( v1 z. C4 c# J
    ' i- v( @( A- b3 O" v. Y
    1.安装包依赖" n. I8 U6 L1 L  @  Y+ L) ~+ i* f
    与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。; l" s, N) D  [) f0 K# }: Y

      G1 E; e9 G% D# f. n& M在python 3以上版本tkinter是环境自带的,所以这里不需要安装
    ! I& v& |, y& U( K2 p
    3 T% \$ [/ k- D7 Q, f4 W2.代码示例3 y; p. C, p  d7 Z# ]# x
    import os) t9 H& @+ t/ }' Y. c
    import cv2
    # u0 M# H2 l# _1 N6 l8 iimport numpy as np3 k: z- x9 e5 G
    import face_recognition
    % f8 L5 m1 a3 |1 q  G( u3 u  q. @import tkinter as tk  7 c, ~) x- t7 w( B% W
    import tkinter.filedialog4 g7 g: m6 _' w( e; S; F
    from PIL import Image,ImageTk
    * B' p$ T7 T$ s( |- s6 ^5 v
    3 R: X, Q4 y7 z# Z/ c# {classNames=[]
    ( R; ~6 [* M, |4 t  Limg_path='Picture'0 a9 _) O, w% `, e
    img_recognition_path='Recognition'
    % A* l7 n( ?* cexistsEncodeingList=[]+ n5 _7 t% \2 P$ E1 c" B
    #对人脸集合进行编码进行处理( c) z! B# B( w
    def findEncodeings(images):
    % n* a% ~+ K9 E    for img in images:% o: k1 F) \& t. T: V
            #灰度处理$ G4 i# P! k! J7 I, g4 U$ s% A
            img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)& a0 B) e- n! {! m
            #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果
    / ?2 D/ M# p' n. i% |        encode=face_recognition.face_encodings(img)[0]5 z3 f8 f5 l& V% w
            existsEncodeingList.append(encode)
    , P; X* H, O: m: [, q
    % H/ x; V! N5 V& v+ {#获取当前存储的人脸编码集合6 `, I* i" x% G. _: j+ I8 i; ~2 v. c
    def findExistsEncodeingList(img_path):
    , {) M& x9 v% p1 D4 Q# F    images=[]
    ' B- }% y6 i! u- U0 X5 x  K    #列出已经上传的所有图片
    " r1 {0 t1 n$ j, ^8 x    imgList=os.listdir(img_path)
    9 @3 m7 J' N4 m8 f    #处理存储的图片得到其人脸编码
    & _7 Z+ j6 Y/ C4 J( L; }7 \! ^    for pic in imgList:" d3 t: t- d3 j: D* X" v
            img=cv2.imread('{}/{}'.format(img_path,pic))) T5 m. P) y3 u" a. r& h7 F3 ~
            images.append(img)5 ^% Y7 o* i  ^+ ]6 o. X7 Z
            classNames.append(os.path.splitext(pic)[0])% a+ E7 l! H3 [
        findEncodeings(images)
    & V' c6 `. j5 {- S7 M$ S7 y
    ' e  R3 V9 C; k1 x#选择并对比图片( n7 h6 h  ?' J) a6 n" O- R
    def choosepic():+ R* y( d& q7 l6 ^4 X5 p5 P
        choosepath = tkinter.filedialog.askopenfilename()! e; B* S* R7 Y: h' [
        path.set(choosepath)
    + Z, c! h/ N/ _) q    img_open = Image.open(entry.get()).resize((530,750))
    - z, b6 n' q; d7 p# Y    img = ImageTk.PhotoImage(img_open)1 @# W* V+ f9 }! k; k7 B. R
        lableShowImage.config(image=img)3 q7 [3 f: E4 Z% O' F+ ?0 p
        lableShowImage.image = img
    - S* A. X* y6 P" r+ `    lableShowImage.place(x=30, y=70, width=530, height=750)& \3 y9 o0 b: I9 g, p
        faceRecognition(choosepath)
    $ p0 A7 S; T  c) B% @$ t" S) [6 X! G% K9 c8 k& E" W: V5 V1 A) h
    def faceRecognition(choosepath):; V& v* Y) a* W6 I
        frame=cv2.imread(choosepath). @* n% A! V( ~' z4 V2 Y
        frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
    ' m# e* s8 c6 m" i% h  k) P    #对摄像头读取的检测人脸  I0 b  C8 E! {2 e% _+ u
        facesLocate=face_recognition.face_locations(frameRGB)
    " X  Z+ T* j$ N* k! G! d    #进行特征编码
    5 K2 _2 T1 s' Q+ P( @    faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)
    ' @2 k- e8 {. N5 G: {5 h        #遍历检测的人脸和库中读取的图片进行对比,计算其相似度
    3 P- z/ {5 E9 ]    name='unknow'4 O. a; G* b+ o2 h+ ^& y
        for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):. }7 f4 w6 e7 ^( P5 S; f. q
            #进行匹配
      C6 Q: c3 C' B        matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)
    : Z/ E- m9 u' c" F        #计算相似度
    3 k  p; M) t* I7 \- ]& _1 G7 u        distance=face_recognition.face_distance(existsEncodeingList,face_encoding)
    9 H( y$ O* h, h' e" [" N& Y! \/ h        lab='unknow'1 d8 c1 p  l, ~$ }3 O
            for index, item in enumerate(distance):
    + D: A) }" u* a9 \           if item<0.5:& s; D6 O$ p/ `3 T# O. _
                    if matchs[index]:
    7 V$ E# G+ l' b* l# G5 T                    #得到匹配到的图片名称与相似度值
    1 ?' w! b( J$ z+ k                    lab='name:{}; Similarity:{}'.format(classNames[index],item)2 d, S$ f- A' f7 C" ^
                        name=classNames[index]
    9 k2 F9 `5 C" A! e                    break
    ! I( Z; j; Y: G) S        #初始化面部捕捉框显示绿色
    , U3 `) |3 X. ~. X, {2 y        color1 =(0,255,0)( p: q' b' r8 u
            if name =='unknow':
    3 ^: ^6 C$ i1 E: ^% L  _            #未能识别的时候显示蓝色; m0 o8 ?5 E: p  o5 x- q9 |2 A
                color1 =(255,0,0)
    % F8 y" o! I8 m: `        #画面部捕捉框
    , X6 |% f- v. G$ B        cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)& ~+ s$ L2 `' _6 P6 W
            #在捕捉框上添加匹配到的图片信息" j- O1 G$ l+ Y4 L% ]
            cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)
      s; C7 @0 R& x        cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)
    6 j0 f, o! r0 j# @  I7 W1 I    img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))
    3 j4 t7 A  B/ J, |) W: v+ |    img = ImageTk.PhotoImage(img_Recognition)) V$ p1 U' E6 O# Z3 \, N+ }
        lableShowImage2.config(image=img)
    0 g+ [: _. j! V/ K    lableShowImage2.image = img
    ( H! X/ K) E+ l' Z    lableShowImage2.place(x=630, y=70, width=530, height=750)
    ' D* A6 C- s- ]7 N& q/ t! I7 H8 r3 G6 T
    if __name__ == '__main__':$ m/ k2 Z" N0 G/ H2 J$ M
        findExistsEncodeingList(img_path)" J8 P  |. e7 \/ t" ^8 p
        #生成tk界面 app即主窗口
    & L, l  n4 {+ A, P" @    app = tk.Tk()  
    ( `: V" X5 p6 ~4 {! G1 D% c2 M- R& X    #修改窗口titile
    ! C7 D* _5 D( w    app.title("show pictue")  
    3 N1 n( c# z+ V9 I2 r8 D1 ~0 L* w; G# }    #设置主窗口的大小和位置# q1 y5 R: I8 q2 P6 w, E# I! ~  d
        app.geometry("1200x900+200+50")
    2 Q$ I; v5 B2 q# ?3 q& U    #Entry widget which allows displaying simple text.+ C7 L/ F. a$ b8 D' ]6 S
        path = tk.StringVar()
    ( w6 _2 G% k: T, y" @    entry = tk.Entry(app, state='readonly', text=path,width = 100)7 M# n% l/ i; q, Y% s2 D: [( Z
        entry.pack()+ g+ F3 k( ^, k
        #使用Label显示图片
    ) L$ H2 m5 w: c4 M% f) y6 `    lableShowImage = tk.Label(app)
    " u8 y2 e, k- v$ I    lableShowImage.pack()9 B1 c& X8 i! n. h' {, \% m
         #使用Label2显示处理后的图片6 n% e# z& ]# O8 M0 }
        lableShowImage2 = tk.Label(app)( j8 j- y& n( u0 f/ t
        lableShowImage2.pack()
    4 N6 C7 r5 i9 e4 A4 G8 e4 v    #选择图片的按钮
    $ B) i7 H) o4 Z9 N4 _, \$ f    buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)
    & M9 A. I& U! o8 \    buttonSelImage.pack()
    : Q0 V8 S/ j4 y* U/ E" A    app.mainloop()6 w5 ^  K( E- l6 {, L- N1 t" p/ S
    8 ?: g# o) n4 Z6 M0 f
    3.说明9 t  f5 o$ D( x/ _* e. x6 F
    首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。# R- M% Z- F+ V! \

    : V6 D; S( B- W4 C* }1 O
    1 Q+ g7 P& r) U+ U8 }1 e! H4 E- p: ?' o9 q& o
    其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片
    5 ?' {2 G/ E, t  f$ b7 y% C# _/ o

    & A! |; P2 p( {7 a0 \- E7 M7 j5 S: x; g& Q4 J5 `! T7 b2 u
    但是效果会存在色彩的失真,效果如下:' u! M, H6 f6 X. V- q; [
    3 d9 t7 p. _% L

    6 v) }: D% l. k- D7 S: f: V: y" M1 n8 q6 x- y
    也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。3 _' \1 C7 Z4 ?: [9 r
    * _3 g% }) r& A
    这里简单提下PIL的九种不同图片模式:
    / N1 g3 H6 q" G$ C3 q% G) i/ T2 _% _0 c9 i' b1 a
    modes        描述
    6 V3 v+ R  b9 t6 {6 v9 p1        1位像素,黑和白,存成8位的像素$ }7 _: _( R. v/ x* S
    L        8位像素,黑白
    6 y. z$ k+ ~2 T- S# m, [7 JP        8位像素,使用调色板映射到任何其他模式% K) @0 G9 M9 I, W7 }( Z* l9 a: r
    RGB        3× 8位像素,真彩
    5 [3 q3 Y  S% ?0 PRGBA        4×8位像素,真彩+透明通道
    ; m! w& l" h" Y0 r, i) GCMYK        4×8位像素,颜色隔离
    - G( }5 u. b  }& [YCbCr        3×8位像素,彩色视频格式
    $ M  ^' p2 v& z  |: W. n! t1 [I        32位整型像素8 ?2 w- ^7 c/ k: w4 S
    F        32位浮点型像素
    $ B4 c4 ~, u) t  D1 }" L" B4.实现效果4 w8 M- Q' r  [3 k0 E! x, x& J6 k6 }
    % t! T' g  f6 k6 t7 {$ N

    " T; k- |$ e& M# K# Z1 z# e
    * J: I9 s9 K2 b& v. i9 B
    7 Q5 x/ G& [3 M$ J2 b5 ^* E6 w 可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。- y! V+ u. g- Q) g. j
    ————————————————
    ! h8 f3 ?/ ^) M; ?  u版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    ! u* ~4 b4 I$ Q, O0 f# a. y原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288: B1 t& Y4 i; R7 W4 ?; [7 {

    $ n, u: ?8 H- E) M/ ^  w  T
    5 F7 Z- N- S& S6 _- N4 \
    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-10 01:24 , Processed in 0.365015 second(s), 51 queries .

    回顶部