QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4186|回复: 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实现人脸捕捉与人脸识别(照片对比)
    7 F! ?1 b& m) H' g7 L
    ' _: a' r6 [( b' j- N1.安装包依赖
    3 n% P- k0 A" E# I! Z# y2 c与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。7 P: z7 D2 ?+ Y# p, b; Z$ V
    7 r! n! `5 M, [. j8 t0 U9 v2 ^' B: V
    在python 3以上版本tkinter是环境自带的,所以这里不需要安装0 }$ I& I& m( {: g8 Z

    4 g" E1 i; ~! c; m; ~' A) ^2.代码示例/ c; J& ]" T0 P, j' c
    import os$ P# V$ v# q  x. x. I, v7 h
    import cv2' M7 m0 Y' m) y4 i
    import numpy as np* P5 Y2 }: d% I$ e
    import face_recognition; Z4 ?7 v9 @8 @1 ^  k) e; V! N, R
    import tkinter as tk  
    & [+ z+ o/ I! O; L$ @0 a  }; Yimport tkinter.filedialog# A' k0 k- z: E' o  S
    from PIL import Image,ImageTk : q9 r& e2 _* R4 T  h$ ^6 N
    * y; w- ?# V6 W: \* u. k( Y0 M
    classNames=[]& R( w; C( {- ~5 w. Y
    img_path='Picture'% p: K$ i1 G3 U
    img_recognition_path='Recognition'
    + S, n# A8 I5 d9 o7 c3 o  @existsEncodeingList=[]
    " u' i" E  F' ~' q. d0 U#对人脸集合进行编码进行处理( w. n$ q2 U4 y# q/ f
    def findEncodeings(images):
    : s- Q: ?/ V4 ]    for img in images:0 n) ]9 K. R# _  X! O: m4 }
            #灰度处理
    . d$ v( e6 n4 \! W        img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)
    ) P- h: F/ d  c9 L3 m/ ]: p        #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果
    . g- x1 j7 K6 M' r  a        encode=face_recognition.face_encodings(img)[0]: J1 p- Y1 d0 s" ?9 Z$ o
            existsEncodeingList.append(encode)
    ; k! K+ O) ?: r/ i3 {1 v0 n$ ^6 h7 ?/ [- z0 d; q6 A  _
    #获取当前存储的人脸编码集合
    , c4 A0 e- }( \def findExistsEncodeingList(img_path):
    7 M, O3 N) `9 K6 j) g1 t; |4 b9 \    images=[]7 o$ I- Z( I0 Q$ f2 E
        #列出已经上传的所有图片  l$ R& D$ v6 w" ^1 ^! L
        imgList=os.listdir(img_path)
    + o. ]7 Y+ ^/ W6 x, y7 z2 X+ d    #处理存储的图片得到其人脸编码' G# }( u. Y$ ?0 Y6 {
        for pic in imgList:
    6 i: B3 z( G4 w$ B# O        img=cv2.imread('{}/{}'.format(img_path,pic))9 x) B. z; o; c  f' p4 J
            images.append(img)  X) _( @! t+ h* Z
            classNames.append(os.path.splitext(pic)[0])
    ; w- X! S+ t. h8 I8 W" z8 F    findEncodeings(images)
    ! ^; {( B% |2 i+ z2 e/ t: l' _7 x6 ^( `( k
    #选择并对比图片
    ! b9 L1 q# y2 udef choosepic():  ~  N7 D. r7 c
        choosepath = tkinter.filedialog.askopenfilename()
    / B  ]. P& b4 Q, A6 S& S: }# t7 b    path.set(choosepath)
    ( S+ f6 b- t5 X) j/ x    img_open = Image.open(entry.get()).resize((530,750))
    ( }' \# f5 R9 V, g# w) t; t    img = ImageTk.PhotoImage(img_open)/ k1 I: }7 H3 q9 Z# A( }
        lableShowImage.config(image=img)
    7 x6 M/ z/ U4 j1 s) q$ f' R  n    lableShowImage.image = img$ s9 r; H2 o" S9 }$ G* r
        lableShowImage.place(x=30, y=70, width=530, height=750)7 k1 Y; X2 v  Z) y' L5 J# \
        faceRecognition(choosepath)& @/ R5 D- D3 D1 S4 O, U
    % ]9 j+ s: l4 \
    def faceRecognition(choosepath):2 D* g( K- ]2 I: B. _4 N
        frame=cv2.imread(choosepath)2 y, h6 u1 s2 A
        frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)6 @' Z0 I; V/ c1 c$ s
        #对摄像头读取的检测人脸) d& k; n# T+ F
        facesLocate=face_recognition.face_locations(frameRGB)& o0 a3 p9 B7 q% b; X, L8 t8 u# N; Q
        #进行特征编码
    # V" G; @4 X/ q    faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)& f$ I4 o" o" Y) c6 R& C
            #遍历检测的人脸和库中读取的图片进行对比,计算其相似度
    : T5 @: o0 e6 e$ H    name='unknow'3 C! K, P  u& @! W- r  d
        for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):
    7 z0 G$ x. i2 r4 z8 W' c4 ?8 J        #进行匹配
    / n1 O. b; R2 [, U9 V: F, C7 d        matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)
    8 I2 G" |" o" \; z        #计算相似度
    # {+ E; }# n( g$ h1 _" u. |3 F1 M        distance=face_recognition.face_distance(existsEncodeingList,face_encoding)
    # n2 C/ H: w  }3 j        lab='unknow'
    7 e# q' S% x! C, q0 B8 Y6 K        for index, item in enumerate(distance):0 c$ N+ l# o, U0 s6 f% n( P9 O% ?9 V
               if item<0.5:
    & Y9 y9 k. _5 x, l8 Q/ S; ]                if matchs[index]:! A6 f+ w1 T( V- E% M2 `) n
                        #得到匹配到的图片名称与相似度值
    ; n. ?! v+ q! w  r8 w* \: q                    lab='name:{}; Similarity:{}'.format(classNames[index],item)- j% v2 G- j; U8 a
                        name=classNames[index]
    # J0 J/ [) G4 N" f5 f7 f2 u                    break! n% B( p# o# V2 H/ k
            #初始化面部捕捉框显示绿色
    " R! Q# x8 o& ~/ |        color1 =(0,255,0)
    6 r& r, c! Q( @        if name =='unknow':  L  W, D/ L, ]9 P
                #未能识别的时候显示蓝色
    ; e$ O. X# T$ U  X& l            color1 =(255,0,0)
      i% p7 X% h1 O" J1 s        #画面部捕捉框
    : L8 L" X9 q8 r' L% a. l6 {        cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)
    1 ?* c' \% j/ Y2 z+ U        #在捕捉框上添加匹配到的图片信息0 T$ D# f$ a! i; v1 |! }
            cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)
    ( G8 Y4 r' u" j0 W        cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)  W+ [  j4 k6 t- g* ~
        img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))
    2 a' ]3 ~9 r+ G. B* W. A+ I- {6 V    img = ImageTk.PhotoImage(img_Recognition)
    ( S. n6 [2 Z& R2 h! x3 l/ s    lableShowImage2.config(image=img)" M" F' M6 F/ p0 p2 U% B
        lableShowImage2.image = img
    / h6 \/ O4 G1 G+ `/ ^    lableShowImage2.place(x=630, y=70, width=530, height=750)9 c7 m( x$ R2 u5 w8 ^
    2 G! p7 f/ F/ R- W% \4 }; X# s3 z+ i
    if __name__ == '__main__':
    3 E6 }! p3 q3 j& x( {6 P; y    findExistsEncodeingList(img_path)) |# z5 E: ~2 U
        #生成tk界面 app即主窗口
    2 i2 r; p: ^% [6 n) q    app = tk.Tk()  
    4 q0 o* Z* q) ?# {5 r    #修改窗口titile
    7 ?6 X- H1 ~) z6 ]3 ]% S+ T    app.title("show pictue")  
    ) o  e% t5 z. s0 \0 E* j) J/ }    #设置主窗口的大小和位置$ D( u1 p8 D' Q2 R
        app.geometry("1200x900+200+50")
    % A! L) S$ ]: ^9 G4 E4 |    #Entry widget which allows displaying simple text., s  P3 {, ~/ o3 W  @8 b
        path = tk.StringVar()
    5 m$ r* e' z, @; W    entry = tk.Entry(app, state='readonly', text=path,width = 100)
    ' \5 u9 D: m. L. j" h6 v) |    entry.pack()0 R$ t$ b4 d3 }/ ?; Y
        #使用Label显示图片$ \. {& U( i1 V$ o7 p2 f4 D( h. }
        lableShowImage = tk.Label(app), y# j# \% \  B  A* `) ^* t
        lableShowImage.pack()
    3 o/ {8 Q, H" A4 X+ w     #使用Label2显示处理后的图片2 C5 O0 {& d$ z, P) `$ u
        lableShowImage2 = tk.Label(app)8 R7 H7 G) D1 z% i
        lableShowImage2.pack()7 t5 c/ N" j8 g" v" B, |' x
        #选择图片的按钮
    2 C6 I* l) F! s4 h6 j    buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)$ o! C5 H) N1 R2 @
        buttonSelImage.pack()
    9 g- \( \' X+ _) y. B    app.mainloop()
      U* @' m: y/ A- f4 S. f4 f, @( c
    % W6 F5 p: p# H' g) ~  h! K" |2 N3.说明
    7 ^2 H. ~! o4 u. d首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。
    7 D( ]: ~# d8 e- Z  F/ A$ }3 b; D0 [1 S' ?1 B

    : }1 Z  H( ?0 O
    , p" ]# @$ l( e' y 其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片
    ' u" N7 f9 a3 [2 S. @# O
    " i; g: s! f8 t. B' z1 o5 n9 q" `
    + e4 R& C+ l- m8 M: _, B
    8 Z7 r9 r, X( i+ ~+ Z, K 但是效果会存在色彩的失真,效果如下:" }9 O" a( c# j; s
    7 ]/ }* U$ C+ x: s3 ^/ F+ t
    & r% |2 R, V7 M5 E1 q6 @
    ( K! M" w# }( @9 a2 c# Z% T
    也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。2 [6 D  ~4 @3 L5 [* K

    & y7 z- l  h" @- w& S这里简单提下PIL的九种不同图片模式:* M4 T! J3 m3 L, p2 T$ b
    ) s* ^9 q) @* k1 O# S
    modes        描述
    3 ]3 L. O1 j% n& ?4 u5 j1        1位像素,黑和白,存成8位的像素
    # m' Q6 d. ]; \& wL        8位像素,黑白( ?1 `' e8 @+ h! U5 ]2 n
    P        8位像素,使用调色板映射到任何其他模式$ A# k' c" o1 o3 @0 n1 A
    RGB        3× 8位像素,真彩
    7 @9 ~) P3 ]" z3 BRGBA        4×8位像素,真彩+透明通道. a6 L: R9 S! [0 j
    CMYK        4×8位像素,颜色隔离
    2 ]# u* ^' k, K& z/ s' O. i6 HYCbCr        3×8位像素,彩色视频格式, l' [$ ?& F( c( _- s
    I        32位整型像素4 m/ r; ~9 Q" S$ U3 m1 v; `: m& t9 R
    F        32位浮点型像素1 x/ G  _# B# Y9 x. d! q: L
    4.实现效果" H# R( _7 J, l' p9 k# _/ B7 P
    : Q, ^$ u/ L# P5 @; f
    . D  y* p8 K1 \6 N  F% w

    ) e! g' z& ]" z
    : Y2 X8 ~* y* z; M 可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。
    7 W( U5 z+ U6 H4 r————————————————7 b  Y/ ?) o2 p. D
    版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    5 e4 R6 t, w# F/ j原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288# E+ ^" u2 q' m# U5 f& W

    ' S& D8 p# H+ P' ~9 ~/ f& B) K. c$ s
    # ~" R9 Z3 p9 T0 v! B$ B1 I
    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-7-9 13:53 , Processed in 0.423656 second(s), 50 queries .

    回顶部