QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4208|回复: 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实现人脸捕捉与人脸识别(照片对比)) T4 \" m  l2 H: I
    , N# P. C: o' @. B" o% L! p; g
    1.安装包依赖
    ; T/ p/ t' k* U; `* H与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。
    " s4 I3 \( k# Y8 g% |1 N7 E7 h4 N
    $ p  O) z& _; ~% E0 v6 G0 Z在python 3以上版本tkinter是环境自带的,所以这里不需要安装. R! E2 ~1 }, `  O) k' A2 d
    / t* V5 ?5 z' w
    2.代码示例
    + B# ?9 G) o7 v4 simport os4 l) s8 V) q* y- F5 k
    import cv2
    ( f. `& S- ]; fimport numpy as np
    % s5 a! j* h/ B6 M: f+ n0 timport face_recognition
    8 e  }; K% V. L, x" R! P/ uimport tkinter as tk  
    $ M3 a  M2 D3 g+ {: |  Cimport tkinter.filedialog, X+ e( M0 G/ I. {" }' |# X, g+ A
    from PIL import Image,ImageTk $ F. ^2 w# N7 M" b* C" l& F: F

    ( s" m) D% M) q+ `" F+ V6 Z& CclassNames=[]
    ! @' X- [& f. ~4 l5 kimg_path='Picture'
    : o; @( h1 S7 u% d+ F3 fimg_recognition_path='Recognition'
    3 }# K! `* _9 q$ HexistsEncodeingList=[]
    * v, `' B4 }4 X0 {" ]: a6 `& q: B; j#对人脸集合进行编码进行处理3 I2 \$ ?* [( G, Z' g! R8 u
    def findEncodeings(images):: h* z! Y+ C: |3 O" Y0 R1 x
        for img in images:9 F. w" ]8 J- Z  R: m
            #灰度处理
    . W  s6 H8 P  G6 j, S        img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)
    , \' X) ~- f) Y; z& m% p- D, o7 p        #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果  W9 z& I; O* N' n0 J
            encode=face_recognition.face_encodings(img)[0]
    6 X$ v* n" U8 f" Y. H# ~0 L5 T2 ^        existsEncodeingList.append(encode)% q6 y' H4 L/ G  t

    - _$ f7 \, K/ H, c) }#获取当前存储的人脸编码集合
    3 f2 x( g8 ]! mdef findExistsEncodeingList(img_path):
      ]5 C7 `/ C* A8 X7 ^6 P    images=[]4 }) n0 r) [4 K
        #列出已经上传的所有图片& S; R0 K) K' ?8 A' Q% i
        imgList=os.listdir(img_path)
    # L4 v5 {! u8 z" n* F* E    #处理存储的图片得到其人脸编码
    * W) B3 v$ n# i! t3 |3 R; g$ F( G    for pic in imgList:$ V: y2 {1 y- I) b
            img=cv2.imread('{}/{}'.format(img_path,pic))/ I4 I( ]+ X9 N' J8 }/ Z
            images.append(img)8 M% \+ `/ @* h( N8 ^8 U( V% \
            classNames.append(os.path.splitext(pic)[0])
    ) t. N- j; I7 `    findEncodeings(images). B" |- _/ U; S  A. Q- D8 G! m; Y& Z
    4 \5 u, b0 }  H& S' M' Y1 k6 [  Y
    #选择并对比图片( L6 Y. D* n8 J- s# M2 u
    def choosepic():, Z; ~! x. l0 }+ T
        choosepath = tkinter.filedialog.askopenfilename(): n, s; `1 l6 A  H& i
        path.set(choosepath)1 R+ w( ~6 T% d# |
        img_open = Image.open(entry.get()).resize((530,750))
    6 d: v6 x  S( C8 p% N    img = ImageTk.PhotoImage(img_open)
    , T" F' s6 o  Y/ T3 z    lableShowImage.config(image=img)
    # c; m% m* W$ ?8 V! E3 l    lableShowImage.image = img% W# _. {. H  e: D5 d3 I, Q
        lableShowImage.place(x=30, y=70, width=530, height=750)1 M% S% E' d0 T
        faceRecognition(choosepath)
    / e0 S$ E' ]  \" [  x5 D7 o
    ( b& u- B- n! l- P  A3 idef faceRecognition(choosepath):
    " o9 k1 n) e6 i/ f# ]- y    frame=cv2.imread(choosepath)
    * t" H$ B6 C# |0 {    frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
    1 O8 @" w" ~" o# ~  _    #对摄像头读取的检测人脸. A1 |3 ^9 W; ^5 g* l6 ~
        facesLocate=face_recognition.face_locations(frameRGB)
    5 q% r' T; Y9 H( ]# P    #进行特征编码% V3 B, w: S& g6 j( y
        faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)+ P' ]8 ]7 }& E5 [$ ^9 ?4 N
            #遍历检测的人脸和库中读取的图片进行对比,计算其相似度, ?( ]' @2 W8 P: ^. m
        name='unknow'$ b& v/ ]# K* \% D; z4 l2 ^  I
        for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):6 y  j3 P6 w; _+ t5 b" c4 z
            #进行匹配: i, v% U1 i) \$ F/ w
            matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)
    # U, U$ M, J) a( e1 O( D        #计算相似度
    % t: Q: ~$ Q7 G% e: Z0 U        distance=face_recognition.face_distance(existsEncodeingList,face_encoding)" `, s+ V: o7 V. _
            lab='unknow'
    ) Z* g7 Z9 }; u1 E& l8 p        for index, item in enumerate(distance):
    ' S+ W/ Y, \( W( x' S           if item<0.5:$ }+ w; z9 g$ g
                    if matchs[index]:
    + g( a3 ~1 B8 M+ C, Y) f$ b                    #得到匹配到的图片名称与相似度值+ u- O' o' P7 t
                        lab='name:{}; Similarity:{}'.format(classNames[index],item)* C+ [# @; k6 k" i0 K
                        name=classNames[index]' F, ~, {# S9 r+ J! T( z9 p8 l( z+ W) [( D
                        break7 i- V7 h' P6 y. l$ w; O6 s
            #初始化面部捕捉框显示绿色
    + |# k" A9 s/ F. y" u        color1 =(0,255,0)
    # u) ?8 [- [! g5 T. q        if name =='unknow':
    1 o6 H9 b9 ]7 N' `+ W2 i$ b& c7 E            #未能识别的时候显示蓝色7 `, i- T; U9 X. l9 L7 s: r1 [
                color1 =(255,0,0)
      W* ?& k- |1 S6 x: w& G        #画面部捕捉框
      T9 C- o' q4 [& X) c$ Q. }        cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)
      r0 A( Q. |3 W3 o( Z        #在捕捉框上添加匹配到的图片信息
    8 v- s7 I! F; z# ?# B4 S8 A% a+ @        cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2); h! `, M0 B0 f
            cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)
    ! j0 m; C: o( `5 |& B/ j( m    img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750)), t: S7 g6 d) I
        img = ImageTk.PhotoImage(img_Recognition)
    + e' r  @" X4 g9 a    lableShowImage2.config(image=img)
    4 x) _0 Y7 I4 E- X" ^2 c    lableShowImage2.image = img8 P3 I& a' @) y/ M- _3 H
        lableShowImage2.place(x=630, y=70, width=530, height=750)
    ! u2 A. W4 z- D7 b/ a4 V" K- c8 b8 `6 `" R9 a; }6 q. G
    if __name__ == '__main__':: ]# d8 f; Z/ v9 G! F1 Q
        findExistsEncodeingList(img_path)
    6 f9 |; @4 v6 {! a$ j5 k    #生成tk界面 app即主窗口
    / R6 {- S1 w: ?: x* ~* [    app = tk.Tk()  
    " d+ B! F8 x5 e. u' R, O2 z. I    #修改窗口titile
    # g3 B9 ^7 \6 z  }    app.title("show pictue")  , h  b3 N% x/ r, l
        #设置主窗口的大小和位置5 }$ P' w; b% V6 f# z8 G0 B4 S( A
        app.geometry("1200x900+200+50")9 _! g: E/ n2 K" o
        #Entry widget which allows displaying simple text.
    + k7 E  C4 V5 Y7 _    path = tk.StringVar()
    9 a+ k* B3 ^0 F6 h    entry = tk.Entry(app, state='readonly', text=path,width = 100)
    8 N+ z3 h4 x# s* m    entry.pack()
    7 O* f& j3 u/ D, A    #使用Label显示图片
    7 A4 f7 D9 w4 a- e0 ?& \% A2 U  s9 o    lableShowImage = tk.Label(app)1 m, W8 X. R3 ?& T7 R
        lableShowImage.pack()2 K) ^0 Z1 n6 s6 x7 {: |6 Z/ k6 k# Q: _
         #使用Label2显示处理后的图片
    , @: f- ]6 u) U    lableShowImage2 = tk.Label(app); _5 ~! [- I+ `  o( D
        lableShowImage2.pack()
    7 R# B/ \% C% G2 k    #选择图片的按钮
    6 z# a9 N0 R" \5 w    buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)7 P( y; K5 \2 Z6 d  A5 ~
        buttonSelImage.pack(): l$ E4 i5 F" }2 c, N' }
        app.mainloop()0 k! l( f. \5 D2 u# w8 |
    - w% }4 b) N0 Z3 Z; ?$ j
    3.说明, K3 j+ N$ w- R# }( X/ y  r
    首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。8 `9 s, ]0 _! j# w& y. N* ^
    * n7 W+ i" \8 H7 n

    1 Y9 N" Y- `' z0 F* r' p$ {  R* C7 @
    其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片
    - D8 @5 K/ J' c1 O' X
    ( ?  n; @4 E! @/ U
    ! ]$ N+ J5 O; h- k" c' @( f2 p+ @. q9 n. ?% s
    但是效果会存在色彩的失真,效果如下:+ Z5 ~: G: O6 B4 G6 i

    . |* |" G% t1 k* E( S1 {- v5 m/ g9 x9 X6 M
    ) b7 o* J" N5 o  F5 O" l
    也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。* @% W' w2 V* u5 G& C! M9 g
    ; y& @' U, |) G5 X0 e6 i8 t% n
    这里简单提下PIL的九种不同图片模式:
      k) t6 F5 ^: t6 M/ q1 G/ G  w1 \8 ?# G. f6 B, |' M
    modes        描述8 L7 ]/ c: B) j, c' I- F3 h
    1        1位像素,黑和白,存成8位的像素
    + S' w0 R6 [* K) L! qL        8位像素,黑白( Z2 J1 Q, c; }  M" J9 f
    P        8位像素,使用调色板映射到任何其他模式# D. Q: N! y% c  Y$ @9 l/ k. g3 q
    RGB        3× 8位像素,真彩0 Q: P/ b0 {% d0 b
    RGBA        4×8位像素,真彩+透明通道; u( R; L$ X8 z3 v4 A+ e
    CMYK        4×8位像素,颜色隔离
    6 S" Y) ^, U% Q0 H$ LYCbCr        3×8位像素,彩色视频格式6 p7 K- s) N. H0 P7 M
    I        32位整型像素
      I. V9 S) D8 B# I: L# W7 Y7 g# V, FF        32位浮点型像素. z! t; X9 ^$ ?, f6 s' g5 y2 @
    4.实现效果
    ( _, W4 p! |0 X- d8 b, _3 ~
    3 Q# X0 f0 `3 c" y3 }0 v- X+ V) t2 H  e* b* R2 s

    & Q) y! ^5 h4 C7 ?, X9 e
    ( Q/ e6 e  j7 @ 可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。
    * G! Y9 F- J- s, r9 u  p4 a7 v————————————————
    6 J, M6 x3 [/ p& Q' p版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
      X2 j; |2 K6 ?7 b# s& N原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288
    5 s$ @7 }  H0 U) t8 b* k# X9 @2 ~
      j7 @$ o$ ]9 T( @/ F) X2 S& M* F) G/ y5 m
    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 04:28 , Processed in 0.577981 second(s), 50 queries .

    回顶部