QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4185|回复: 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实现人脸捕捉与人脸识别(照片对比)
    & Y/ S$ T# H2 e; A, q/ O) n6 n3 }% M
    1.安装包依赖7 I7 a0 k# T" g) k* Z4 S
    与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。  c4 y3 q. M' g& D

    * m" \" R! b' j0 D6 P在python 3以上版本tkinter是环境自带的,所以这里不需要安装
    , L  Q% J& ^7 `3 C; A
    - N5 R) m# f$ t3 k5 Z+ b& \0 x& ^2.代码示例! ]1 b8 |) i' D$ F
    import os: r$ @2 E# s2 t4 _
    import cv2$ j" b  R$ B8 X. K
    import numpy as np
    - A4 l8 |  [5 a$ f) N( Oimport face_recognition5 N6 u6 f' v% R2 L
    import tkinter as tk  
    3 C0 f* }7 e% a" l% ?6 |9 A* Qimport tkinter.filedialog
    $ S0 W- b3 I' s7 F0 X9 pfrom PIL import Image,ImageTk ( C- L6 s# p* `' B: h" k

    , U- I6 I1 B8 ~3 s0 d) JclassNames=[]
    % s8 u+ N% A8 n0 R, Jimg_path='Picture'
    8 `% i# \( W6 N, v3 Z) p4 }img_recognition_path='Recognition'. n3 Z9 d. a* |9 X
    existsEncodeingList=[]/ l7 ]  @8 W- a
    #对人脸集合进行编码进行处理; r% c# Q& `+ b, p" C
    def findEncodeings(images):
    2 y9 T% [( ?$ Q4 v2 m% X0 J: ?    for img in images:" v3 ~6 i7 r- w
            #灰度处理" Y, d  s+ Q' k1 T0 ~5 X4 Z* i" e
            img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)
    " A4 E+ Y0 M8 [6 s        #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果
    ! t$ k0 q0 S; t1 t+ E1 \        encode=face_recognition.face_encodings(img)[0]
    1 u! I) B' z* @) ?8 q1 `        existsEncodeingList.append(encode)1 s+ M2 F  g) Q6 F) W$ h

    6 m4 N% n  `5 d! X6 X! d6 f#获取当前存储的人脸编码集合( J) P$ `$ \) i+ ~& @; B& V4 G3 R
    def findExistsEncodeingList(img_path):
      A% F8 i! w. i6 s    images=[]- W! K- u2 q3 z' h6 Z
        #列出已经上传的所有图片$ k5 k! ?- [$ f# ~1 y) j
        imgList=os.listdir(img_path)* u! h7 [  r# M
        #处理存储的图片得到其人脸编码
    . ~5 F3 K& L2 R; B    for pic in imgList:. s# h, ]7 z$ F6 x7 a& H  R
            img=cv2.imread('{}/{}'.format(img_path,pic))
    ) V/ \4 }; g( [  J% S9 t' l        images.append(img)
    4 ?* i% v) h# B$ D: j5 [: H        classNames.append(os.path.splitext(pic)[0])
    9 y9 X* z1 E6 t5 @. _    findEncodeings(images)
    5 }( _& h6 b. D' j4 n4 D6 u2 b! l3 H7 @7 e2 n
    #选择并对比图片! b6 W% b- H9 B, n( r1 v
    def choosepic():
    : _9 m2 T2 C: v  m3 I" z- Q, s1 i# K    choosepath = tkinter.filedialog.askopenfilename()2 j7 n3 c: S( v: b: w3 L! P4 K
        path.set(choosepath)2 ]' |6 d, d5 m' t, S
        img_open = Image.open(entry.get()).resize((530,750))
    ( d) X" h. N+ h, {. X    img = ImageTk.PhotoImage(img_open), j/ u& F5 Q% x: ]' j, c* d2 I+ r
        lableShowImage.config(image=img)
    ; u5 M' _3 @0 Q$ U0 Y# d0 P    lableShowImage.image = img
    $ \' e& e: T5 C9 C% S/ @/ l    lableShowImage.place(x=30, y=70, width=530, height=750)8 j/ ?  U) E) y
        faceRecognition(choosepath)1 F2 z5 j" A2 ]4 Q% x( T& c, c. O1 B8 y
    ' q; P( P% R. g: o3 y  Q
    def faceRecognition(choosepath):
    1 m: {8 O3 C7 k, @( f$ r: Y* f5 m. t    frame=cv2.imread(choosepath)
    ( J+ t: A9 j; V$ A7 m3 T    frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
    ! ?' W- d5 j$ k4 \& j$ t: q    #对摄像头读取的检测人脸
    2 p# V6 K; u% Y5 D4 T    facesLocate=face_recognition.face_locations(frameRGB)2 u* J$ P3 x5 M) z- ^8 O! y
        #进行特征编码
    * M( R$ Z2 x+ ?    faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)4 E6 \. n, B6 p7 P) G
            #遍历检测的人脸和库中读取的图片进行对比,计算其相似度! ]# b) i, Q( Y4 s% m
        name='unknow'
    " B/ o5 t* ~" Q' ~/ Q/ D" B' ]    for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):- A8 K7 z4 X7 }: j+ w7 F  ?
            #进行匹配2 A9 E. F1 N* f' N4 I' a* |) f$ r1 ^
            matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)4 z3 e- ?; O5 n) M% d. I
            #计算相似度% Z1 R% G) k' R, D( f2 x; {
            distance=face_recognition.face_distance(existsEncodeingList,face_encoding)
    + |  t2 p7 s, s& y# N        lab='unknow'8 R. N" M% v. [
            for index, item in enumerate(distance):) `) c1 f0 |2 [! ^0 ~' L
               if item<0.5:0 K, p$ x- v1 f5 [. |$ f- ]) i1 b
                    if matchs[index]:" y% V) Y# y, {% Q* B6 k
                        #得到匹配到的图片名称与相似度值
    : \+ l; ^! ~# h                    lab='name:{}; Similarity:{}'.format(classNames[index],item)9 t+ w  i3 e, x" V
                        name=classNames[index]9 A, I9 P! n' n) w
                        break. [) k8 Y3 P* F: {( s1 d
            #初始化面部捕捉框显示绿色
    6 ?% \( K. Z( Z# P& G" J) ]        color1 =(0,255,0)- r6 H+ b# w) X. P
            if name =='unknow':
    % L4 Z4 \; a8 M; o  B: r            #未能识别的时候显示蓝色
    ; E0 D. ^! j8 g; d            color1 =(255,0,0)7 R0 e  {2 A& M( b7 s
            #画面部捕捉框# R- k! P* |- U
            cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)* S4 w5 b0 U+ L& \/ x6 D/ c
            #在捕捉框上添加匹配到的图片信息1 S3 p, V! @2 W! c  \
            cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)7 U( e' a1 G  N
            cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)0 h! h4 M3 e' `6 }" J" [
        img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))
    7 A4 |' n2 q/ e1 i& I    img = ImageTk.PhotoImage(img_Recognition)* w) ]1 p2 W; j+ a
        lableShowImage2.config(image=img)
    - B/ ]! W! [) z0 B9 k    lableShowImage2.image = img
    / j) v$ Q( p% n$ }    lableShowImage2.place(x=630, y=70, width=530, height=750)
    ' s" h" N& J- h1 J. C5 O
    9 q4 m4 S  y9 ]if __name__ == '__main__':- U; @* |7 g. @+ s  \( g2 R- y0 Q2 Z6 _
        findExistsEncodeingList(img_path)
    . L* v7 R* b% ]9 b) ^    #生成tk界面 app即主窗口
    8 _. @! i3 O$ Z    app = tk.Tk()  
    ; X4 a# E' H/ F1 Z& q. n6 \    #修改窗口titile
    6 ?' p7 N& f, W* O    app.title("show pictue")  + I& g/ s, ?) |
        #设置主窗口的大小和位置' g1 a8 B% V' r  E) d
        app.geometry("1200x900+200+50")4 G- O. o' y. i) h6 C7 u: |
        #Entry widget which allows displaying simple text.
    + e- h# f% D1 U9 K2 i    path = tk.StringVar(), Z! }' ^& b3 w
        entry = tk.Entry(app, state='readonly', text=path,width = 100)0 b( x' S7 E3 ]7 n/ g3 J
        entry.pack()
    1 v  A% R# t% g+ v; |( J    #使用Label显示图片
    9 w( h. v  p7 {1 d5 c    lableShowImage = tk.Label(app)
    ! @" E+ B* |7 R* s2 ?- l    lableShowImage.pack()
    * \  s! v" K% w7 x$ t     #使用Label2显示处理后的图片
    / J) p- [. S8 Y6 p    lableShowImage2 = tk.Label(app)
    - T# C; o/ ~6 J. A8 g, h    lableShowImage2.pack()
    6 U  L/ B2 N4 o! K6 n+ o+ B    #选择图片的按钮+ q. Z# J# x1 R1 [4 E' h
        buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)
    6 {) `0 @' t" d& q. s% e    buttonSelImage.pack()
    # J+ q- x9 L2 X. D( g& {$ R7 j  {    app.mainloop()* R; R" m5 `& I8 n" v

    * ~% [6 \' j* X- ~. Q+ A- r3.说明2 y9 z* q. @5 `/ {! ^
    首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。5 D: i8 Q) _1 G0 H# {( t
    - N2 E. b1 T' M: R
    4 O1 R/ S& B. H5 |6 j% _

      u. p( [; {- g5 K1 o2 u9 H8 p. C 其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片) J2 l. u/ |3 h! ~: E) U6 d$ Q/ m
    0 I3 [" i2 r, t8 f) e. g- W: V  X6 V

    : g1 |% {# V0 e8 p* M6 v" V+ O: v+ C+ I) u* ~6 }! W& u% [
    但是效果会存在色彩的失真,效果如下:
    + s0 U( a! Z: l/ |3 v* B
    : j0 K7 j! {" O; x
    9 J8 P; C' A* `* b2 a! v) V: F( i( u1 ]$ x
    也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。: t4 _7 i- n. B
    0 x: `/ q; ~% M8 ^
    这里简单提下PIL的九种不同图片模式:7 I7 C0 m9 C( A8 r: T# B/ [7 j
    & q  R. S' [( Z/ ?3 E( ^. R
    modes        描述
    1 y! ?) b% f: J* p% ~1        1位像素,黑和白,存成8位的像素
    / ]" @1 D9 U; H( N3 fL        8位像素,黑白
    5 c( h" u, M' u7 WP        8位像素,使用调色板映射到任何其他模式1 d4 d( }7 W& O% B
    RGB        3× 8位像素,真彩2 `  q; ?( _0 J$ U
    RGBA        4×8位像素,真彩+透明通道
    " ~% Q& a" V+ `( z; Z6 }CMYK        4×8位像素,颜色隔离2 N. ^6 A* V- q* @7 [
    YCbCr        3×8位像素,彩色视频格式
    1 C  V# s1 o" ]I        32位整型像素" Q+ F# G! d. A' e/ U( [+ P
    F        32位浮点型像素8 W8 U1 @- e7 D' S
    4.实现效果; A# o. `# u( Z6 C  ^3 }7 m* b

    0 l3 K. L; c3 @! e1 N) x
    * L$ s( M" J' w; `* A) B: r5 J3 c7 ~$ ^$ a' ]  U6 f. X% W

    5 z& ]6 Q! F; c* V 可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。
    ! o8 R2 ~/ u) P( s" B6 H' n————————————————  B1 S. B  U! S8 G. j- ^' f
    版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。1 E' {4 [. T5 g& c# R: Y* I
    原文链接:https://blog.csdn.net/qq_17486399/article/details/1266292889 f; u1 I$ ]+ }5 x0 s" t/ @9 T

    ! _( H; T$ H& r! Z7 J; Q8 {5 |7 A$ {; S. e' e
    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 12:40 , Processed in 0.402404 second(s), 51 queries .

    回顶部