QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4204|回复: 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实现人脸捕捉与人脸识别(照片对比)
    0 D+ V8 p4 R3 d  x( I+ P/ t! n) B4 i% f  C. X
    1.安装包依赖, d! A" @* `) J& s
    与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。
    5 Y  A6 d+ h$ x
      v9 ~( y: G8 ~0 W1 P6 j$ p/ U- \在python 3以上版本tkinter是环境自带的,所以这里不需要安装* l# `8 x# F# b
      q3 L) m8 V. i3 M9 w
    2.代码示例
    ( j8 a. s- x8 T" D3 [3 a9 Gimport os, {; c# Y6 h6 U/ u
    import cv20 I9 H9 g3 L9 A9 I  |2 {
    import numpy as np
    ) x( b6 e- t- U5 q6 s8 Iimport face_recognition
    , H; n1 A6 e* C6 {( dimport tkinter as tk  
    $ v: i5 w: j& V3 O9 v2 l! vimport tkinter.filedialog
    $ {3 n' [$ d# }7 a. c  yfrom PIL import Image,ImageTk
    " B$ H; s5 Y8 o$ R9 y/ [. Z# J* P, }. i9 Z; p/ f& `
    classNames=[]
      `2 P7 f( `! `/ Iimg_path='Picture'
    + S& J: ~% p+ o" @; o. Yimg_recognition_path='Recognition'
    $ a1 h9 C( T( B0 b1 aexistsEncodeingList=[]
    + @$ o/ v1 C- P#对人脸集合进行编码进行处理
    . |. V- \. l( }$ Ydef findEncodeings(images):
    1 b- O* X& \/ h4 [: f    for img in images:
    + P. R' s, A4 k( o/ I8 S' m9 u        #灰度处理( D( z+ k- ]2 y, S' ^( c
            img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)
    4 ]+ b# o7 d! Y, i        #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果
    6 ~" {% O1 w- P3 |        encode=face_recognition.face_encodings(img)[0]
    8 q: Y* o; A( Q9 D3 i        existsEncodeingList.append(encode)
    + H8 _3 f. w; W' d; k0 \9 C
    7 T' ?1 s( z2 \' W#获取当前存储的人脸编码集合
    % Y5 R& w$ ^" `, Ndef findExistsEncodeingList(img_path):
    / C4 x8 G) ~# A) V- d    images=[]  o9 s- z# D" u" G9 f
        #列出已经上传的所有图片0 `, a$ ?9 Z" x8 a7 K" B
        imgList=os.listdir(img_path): z1 E. M; |) ]$ ~
        #处理存储的图片得到其人脸编码
    ) @7 H5 |* `/ b3 }5 ^    for pic in imgList:
    ' d: L* {4 a9 K, }        img=cv2.imread('{}/{}'.format(img_path,pic))2 h* H, h3 k" g* t" d0 K
            images.append(img)8 p5 C$ P$ L% x+ @
            classNames.append(os.path.splitext(pic)[0])1 K4 @' J0 U# o; Y" f
        findEncodeings(images)
    2 W; k& I6 s  M. Y( ^' @1 f; v4 z" ?% K! Q6 D
    #选择并对比图片! O9 Q0 M  b9 }3 g
    def choosepic():
    % e" }+ ~* e! ]/ u    choosepath = tkinter.filedialog.askopenfilename()% \. ]7 K; m! k% d6 \: E0 P8 K! M+ g
        path.set(choosepath)
    # Y7 f7 |9 ~5 n" T    img_open = Image.open(entry.get()).resize((530,750))
    - C8 ]( Q& P+ u, j0 {7 t    img = ImageTk.PhotoImage(img_open)2 U1 `1 K9 H3 n5 L: V- y' m6 S4 E
        lableShowImage.config(image=img)
    ! a# P6 A5 n. l2 C' u8 D0 n    lableShowImage.image = img
    2 g& C/ v3 t* d$ u/ Y# ~4 Y: N    lableShowImage.place(x=30, y=70, width=530, height=750)
    2 r- {6 Y, g5 Q% V" S9 ~    faceRecognition(choosepath)
    1 N2 o' ?5 Y/ C' @5 Y. P; _4 x: L2 @7 M1 v1 u5 H
    def faceRecognition(choosepath):: r2 r' G3 E% W, O6 V
        frame=cv2.imread(choosepath)
    - D9 \# p: }! T9 W4 K    frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)0 t1 g7 s$ b. @6 ~: ?# s
        #对摄像头读取的检测人脸
    2 U5 P( d9 q) }$ g6 a5 C" L# }    facesLocate=face_recognition.face_locations(frameRGB)% w9 M/ I- X1 g1 b
        #进行特征编码% k2 B1 N" k' V0 O1 L
        faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)
      E; M% W( K9 `5 w# s3 Z        #遍历检测的人脸和库中读取的图片进行对比,计算其相似度
    . r2 N+ g2 Y8 G( u1 J  s1 b- u    name='unknow'5 q, A1 G, h; J- Y
        for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):# V/ l- R* j  N
            #进行匹配
    & W7 o' i* f& c1 Z$ c6 T+ y* l) }9 i; B        matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)$ G; x: E! D' c9 Y. i5 G- k/ [- Q
            #计算相似度
    ' H, \- ]! T9 D1 N# m( q- N/ s+ h; U        distance=face_recognition.face_distance(existsEncodeingList,face_encoding)- H! R9 n8 x$ |
            lab='unknow', q$ V+ x6 k+ q0 Q0 E' N
            for index, item in enumerate(distance):! k) W' s6 {$ i4 M2 H& ]
               if item<0.5:* ^8 D+ N- `+ U9 O$ a" j) `4 ^
                    if matchs[index]:
    : \7 U" w: O. C, L  G$ q! M& K                    #得到匹配到的图片名称与相似度值! H- p& F; T$ y; e
                        lab='name:{}; Similarity:{}'.format(classNames[index],item)
    . u. v; m; t' ^. C1 ~                    name=classNames[index]5 }% [2 s* Z) g3 V
                        break
    + N+ [, C, G* P2 v: }        #初始化面部捕捉框显示绿色
    3 s! a0 X+ c3 ^: Z5 N; N. s        color1 =(0,255,0)
    % l* {, F% t! D" i        if name =='unknow':; T) C% W% }. L
                #未能识别的时候显示蓝色0 z9 f, I1 U5 `2 z1 ]( x
                color1 =(255,0,0)0 N$ S8 I# t8 |. W
            #画面部捕捉框
    - b: x$ J* e6 n  A! P        cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)
    # q8 h3 G# u* q( t        #在捕捉框上添加匹配到的图片信息& z$ ]/ s& ]$ Y) d/ |& U" i
            cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)6 E- Z9 o6 G5 R1 o- C4 ]
            cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)
    6 p8 O9 ~% W0 W1 a( r, w    img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))
    " ~% l( h# H: [1 w    img = ImageTk.PhotoImage(img_Recognition)* `- a. \0 [: \# ~# X/ P9 z
        lableShowImage2.config(image=img)
    + {7 K. W. p9 j' F5 u' o/ g1 C, Q( T9 ~    lableShowImage2.image = img
    % }. D( U( U  I' z& ^! q) s1 D& ]  C    lableShowImage2.place(x=630, y=70, width=530, height=750)8 @1 _, r" l' @" A* p

    / N" ]  [  l) f1 W/ b* Mif __name__ == '__main__':# P* `& a' J. L' t3 g7 H
        findExistsEncodeingList(img_path)- T5 m+ s/ e) }  x, n, U) p3 W
        #生成tk界面 app即主窗口
    2 R( i3 I( [8 h' f& g    app = tk.Tk()  
    2 N- S# ~% b" v, Z4 N  K    #修改窗口titile( ^/ {2 c. U- V4 X0 H4 K  e
        app.title("show pictue")  
    - t* ?- K3 `; h5 d/ h& r: q    #设置主窗口的大小和位置* H6 P# L: r3 ~5 j- E5 s$ A8 |  i) \
        app.geometry("1200x900+200+50")# T9 I. {- p' U* S) q
        #Entry widget which allows displaying simple text.
    7 l5 n# C! X1 ^    path = tk.StringVar()8 X: P4 x1 s, F# o, r: F# Y6 ]
        entry = tk.Entry(app, state='readonly', text=path,width = 100)
    4 ]2 `4 v, x! T    entry.pack()* `* }  M3 V9 H9 b' v$ _
        #使用Label显示图片
      ?" t9 l  p9 }/ j, ?  t) @# \    lableShowImage = tk.Label(app)
    / ?: W' ^& w- r, o- o    lableShowImage.pack()
    ; w- H( q2 c* H6 ?     #使用Label2显示处理后的图片8 L4 V- b) i$ O* }( P; A$ c3 t+ M
        lableShowImage2 = tk.Label(app)0 O5 k* x3 m! Z! N3 F, q2 ^
        lableShowImage2.pack()% i7 ^, H; w+ Q' s7 {
        #选择图片的按钮
    9 Q! G8 I. s) \6 d8 E7 i    buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)
    8 H* A" t$ p" k- g% C; d    buttonSelImage.pack()
    - }- M5 c4 {! }    app.mainloop()
    , P+ |  ]$ {- a( O( g0 Q+ P: [0 v; n
    3.说明
    % f: i+ B7 E* v首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。/ F: h$ W$ D2 G/ q

    ; J; i1 a  q! T) q7 |" {' x1 R
    5 e/ }: [7 g5 k' x6 N. Z+ E3 X2 e$ C
    其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片% z/ b  e+ w, X% X& I

    1 O( ?( q; b4 q9 m1 b
    * ?( k! J6 C" @+ z5 {' q
    ' J) h% l# [6 ]+ w 但是效果会存在色彩的失真,效果如下:$ I3 m* e% W6 B

    2 q% o- p: o/ L* a. d8 D3 q- F. }9 K  F" U" v
    + [& B# U% o+ I8 L/ d8 J' F
    也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。' z- e* M& J: }
    ; K) u8 P# r9 N) k9 A0 [# R- i
    这里简单提下PIL的九种不同图片模式:
    ) x( S% a9 c% p  y  {9 x
    ' ~( a+ F! \; @modes        描述- M' ~" M# }7 K3 _% ]5 t3 d
    1        1位像素,黑和白,存成8位的像素
    " @' T$ e7 t1 O" E1 |) \/ YL        8位像素,黑白
    % x4 o# j" i  O2 ?" D3 l2 m/ pP        8位像素,使用调色板映射到任何其他模式: V8 N  ~$ J. w6 c
    RGB        3× 8位像素,真彩4 }. g% k  u* X" M
    RGBA        4×8位像素,真彩+透明通道
    6 S- ~+ j" }% z* R5 m" x" eCMYK        4×8位像素,颜色隔离' I6 D3 K. [( z' [! W3 q5 j. j
    YCbCr        3×8位像素,彩色视频格式
    / j' s3 {* D+ pI        32位整型像素
    - J+ ]8 X" X2 Z4 E9 mF        32位浮点型像素* ?, ^0 _" K* Y4 y1 S
    4.实现效果
    2 f: `6 V0 ]( @/ h, _
    $ y$ W) K/ y! N- F. Q
    % w) X+ H1 [: E
    2 W8 d$ }" T  w# ~% _8 R- Y5 ]& G, w  S; O4 w  y: P, E3 ?
    可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。
    $ g6 P5 Y( @. G2 v% a7 N" w————————————————; u- J) p8 x  ?* o0 S
    版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    7 [% ]# m8 @: C原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288; s. f/ p* |9 B7 L

    ( {6 s  j$ x* n" f: F+ W$ r; O8 ^3 R( G
    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-8-24 03:39 , Processed in 0.430411 second(s), 51 queries .

    回顶部