QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3787|回复: 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实现人脸捕捉与人脸识别(照片对比)
    # }1 [& F4 ]" w# N# B/ c0 P. o. l! ]" ^* }9 e+ j
    1.安装包依赖0 }  \& n5 n: X& b
    与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。: A  ]% o6 T5 r) x  ~0 m5 C% f
    4 L. U# a' k5 D
    在python 3以上版本tkinter是环境自带的,所以这里不需要安装' l6 \& D6 |6 N* Z+ B9 c
    . h2 Y$ j8 V( b$ P) @
    2.代码示例
    8 f0 J  Y- V# Wimport os
    7 }/ k8 t* d; F8 Aimport cv2
    0 e6 ~2 s8 e  y; C8 |4 v4 f- z( nimport numpy as np
    ; W- ^1 j# R! G: e( [) w! P# S& Nimport face_recognition  @1 d# @5 J8 J- ~1 Y
    import tkinter as tk  9 R, J5 S. D% a( A6 d  E8 a/ r6 @
    import tkinter.filedialog
    ! ~! C5 C" h1 _8 hfrom PIL import Image,ImageTk & \# q6 U9 `8 s! t3 X0 T
    % h  W# B6 B; N! D4 w4 _/ m/ A( d& i
    classNames=[]8 U) W$ [* P1 W0 b% T: I0 a9 @1 [
    img_path='Picture'
    : f( F- d1 x4 Y& F/ gimg_recognition_path='Recognition'
    % q- V2 g" F( S# w- r1 texistsEncodeingList=[]
    " H2 p( j( n" a4 X( P" O  g- n8 r#对人脸集合进行编码进行处理+ \8 @/ L* O& O. I8 E2 ]) M/ ]
    def findEncodeings(images):
    * M1 F" z0 W8 F5 S# j& i8 q    for img in images:# h; Y9 o0 n# h5 p$ d- C  c
            #灰度处理, C) ], C0 q0 G& K, M" r1 N
            img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)
    - C1 v8 ^1 B  t! A- n# k) }$ h. T        #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果' C* @% Z! n0 X* e7 S
            encode=face_recognition.face_encodings(img)[0]
    ) U5 ^- L/ a1 `8 L' c        existsEncodeingList.append(encode)
    % z# J! p8 ]+ Q8 x4 n8 `4 Q4 ?7 ^( \! ^5 A
    #获取当前存储的人脸编码集合
    7 `( h* b' ?( i9 I( h% o+ |def findExistsEncodeingList(img_path):
    5 G9 C* S& ^6 W2 L8 [/ v2 b3 {& f    images=[]" |6 n4 [& _9 K8 T1 x0 F7 T
        #列出已经上传的所有图片& r' V5 i  E+ K7 f& F5 D1 a
        imgList=os.listdir(img_path)
    4 W6 a( y( g* T" I+ H) P. W1 [( s    #处理存储的图片得到其人脸编码
    7 p$ ]  C% @. K1 E/ t+ d! U    for pic in imgList:  h5 F9 \0 O+ A5 Y
            img=cv2.imread('{}/{}'.format(img_path,pic))
    ) g% V6 D. f' A0 y7 s; r4 Y9 F# W0 M        images.append(img)
    5 d) z( D8 J" L6 |) @  \        classNames.append(os.path.splitext(pic)[0])' i8 u- |$ T' u) K  J+ f
        findEncodeings(images)
    ( `) z; Q3 ]. _7 |2 \6 A5 C
    9 j/ p% Q8 Z' g5 o6 l! @0 C#选择并对比图片8 [; q- B9 j+ q9 w
    def choosepic():
    1 u7 s$ Q; ^0 J; U6 x, U    choosepath = tkinter.filedialog.askopenfilename()
    5 k, D& w4 i6 S; l9 L, T    path.set(choosepath)3 J, k9 x" d+ u  j0 F. u
        img_open = Image.open(entry.get()).resize((530,750))
    3 ]: a/ t& v( @) Q6 S: C4 ]    img = ImageTk.PhotoImage(img_open)
    " q1 Y) G1 A  V: D( m    lableShowImage.config(image=img)) X3 O& x+ Q  Q# D
        lableShowImage.image = img
    # g- A5 a" ?  I8 A. j9 l    lableShowImage.place(x=30, y=70, width=530, height=750)2 w0 p# l5 @: w* c" H; v! Z( z
        faceRecognition(choosepath)0 t9 |- u6 t2 W6 b- e: v7 s- |; t

    ) T9 J: J! H9 q2 H: k5 ~, udef faceRecognition(choosepath):  ]; p( y/ E, s. S, t8 w: R
        frame=cv2.imread(choosepath)' v, m9 U9 ^/ b7 ?  c5 t2 A. z/ @, l
        frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)  T: o( E! I8 n* u4 e5 g3 F
        #对摄像头读取的检测人脸
    9 a2 t1 L$ w1 g5 g( f  b9 E    facesLocate=face_recognition.face_locations(frameRGB)3 Z. _$ u% ]) C" Z$ x( r+ Z
        #进行特征编码
    3 ^% C! s0 Q2 j; v4 H    faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)  J5 h5 R  Z" m3 \& p
            #遍历检测的人脸和库中读取的图片进行对比,计算其相似度
    3 y" |6 a+ ^( ]5 [    name='unknow'
      b* g% i# g) S2 t. P    for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):+ y- f- A) y2 x) a! o6 H
            #进行匹配6 v/ ]8 |+ @# f- H- X4 o
            matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)2 Y1 o, V3 c) V8 _" {
            #计算相似度( t8 A" k8 i- f* h) N, {& x
            distance=face_recognition.face_distance(existsEncodeingList,face_encoding)' z: S& C& H, L) ~
            lab='unknow'% G) s. ^- x9 Z9 G
            for index, item in enumerate(distance):# W4 n) T5 u6 I9 J9 @
               if item<0.5:
    1 c& E2 J, a' Y6 \+ w. W+ s                if matchs[index]:7 m( G0 k" s. W" `2 R  ]3 l; p
                        #得到匹配到的图片名称与相似度值7 r! k$ D" m( y; U% ~% @3 B/ j
                        lab='name:{}; Similarity:{}'.format(classNames[index],item); A1 y% F( m$ C
                        name=classNames[index]' z2 h5 F- [) [. V. I# K
                        break& z8 t+ m+ K. r1 q% f
            #初始化面部捕捉框显示绿色+ N  r' d' {# a9 K  y
            color1 =(0,255,0)
    ( k4 I0 A# r8 F1 }' ^        if name =='unknow':4 C$ `1 f3 k9 T8 f
                #未能识别的时候显示蓝色
    8 Y" z! A6 g! s7 X; D            color1 =(255,0,0)
    % V0 a7 ]8 D6 `1 [+ p9 Z        #画面部捕捉框
      R* d! L) b/ w        cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)
    8 H1 y2 T6 r$ a, m        #在捕捉框上添加匹配到的图片信息1 V! T" g  W8 n7 y" N5 E; ?
            cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)
    6 G2 \5 V! `2 ^0 _' ~3 ~3 g5 r9 l        cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)9 @# m: h1 x5 x$ v" _4 @$ K' |+ l$ I
        img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))+ t+ g0 H3 U1 D, U# f& S) L
        img = ImageTk.PhotoImage(img_Recognition)+ ]6 n. X: {+ e  w6 s8 z
        lableShowImage2.config(image=img)
    3 o0 }; j9 v( o    lableShowImage2.image = img
    5 h) O- `4 q( ~7 r1 ~. u    lableShowImage2.place(x=630, y=70, width=530, height=750). |3 h+ F& f5 G/ h$ T* W; D

    # y* E! @5 |3 J9 zif __name__ == '__main__':
    " ~; X) e9 ]0 G- F0 Y0 [# S. P( z    findExistsEncodeingList(img_path)
    " `8 E/ ^; Z( @, E    #生成tk界面 app即主窗口
    + g. L3 h1 i8 G    app = tk.Tk()  ! u3 V3 X7 ]  u8 |# I' g1 D
        #修改窗口titile2 ]& r0 r3 [! D# y! v8 N3 c! q$ ^% ^
        app.title("show pictue")  
    : w) z# H( p0 H9 J9 K    #设置主窗口的大小和位置
    $ h$ K7 Z$ ^& Q, N! X: E0 o# p    app.geometry("1200x900+200+50")
    $ ?) V) l( R# Y: I    #Entry widget which allows displaying simple text.
    & ~. \& `5 U! T0 O. \    path = tk.StringVar(), R! R: Z4 X1 ]( f( r8 p9 K6 \
        entry = tk.Entry(app, state='readonly', text=path,width = 100)
    ' B$ P4 c, t# e) J+ Q/ E    entry.pack()
    " N+ Z" q) s& j& W( N: [4 I# W    #使用Label显示图片# }% Y- \1 c- C6 Y8 A$ X
        lableShowImage = tk.Label(app)
    ! m- ~1 X) G" N& ]* x. D    lableShowImage.pack()
    ! N, x. @0 J2 W' i     #使用Label2显示处理后的图片
    4 n* J2 k) V# K- N2 u3 |    lableShowImage2 = tk.Label(app)0 \7 \* @( ?6 i! c+ }; H3 C$ F
        lableShowImage2.pack()
    6 c$ f! I9 F/ Z    #选择图片的按钮! M6 g" w: u9 D" s. d" d
        buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)
    7 Z9 r  y9 T7 F! [" F2 S    buttonSelImage.pack()
    - C8 E) L5 N# a/ N; A    app.mainloop()+ \3 ?2 ?4 s' |% r* N

    2 w% F2 P% h, _3 Y4 U) r. G5 a- @3.说明
    * F" L% l9 p- P7 [5 X首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。7 z5 V0 i' h( @
    * T; L# W" t) Z
      S0 o9 K5 G( y" H: |0 D

    . K7 a0 o' \# H2 H5 ]1 A 其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片
    * [7 _( B9 u* w- b/ t! B- [- l- ]" |9 a; l8 o/ E* l9 U
      T; y1 V6 e# ]+ ~) r+ c- f: @
    & _5 ^# q! |4 x# W. L
    但是效果会存在色彩的失真,效果如下:3 b, t/ w+ B! X# `8 D# Z% d$ W

    6 P! C5 P& o- s" Y3 x( R2 Z, g# Z  P
    " P: ^  ^" ]) v- Z6 y/ N; c) ~1 R& x3 k% o4 K2 a5 f
    也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。
    # v5 a# _# I! z. a0 l! F3 G0 W" I( ?8 c) ]- J$ i2 E0 e
    这里简单提下PIL的九种不同图片模式:, Y8 _$ v: p- C% W7 d4 B
    * G; o: R3 Q6 r" N" E+ |9 w
    modes        描述" E3 o# Y+ |/ F) O# G
    1        1位像素,黑和白,存成8位的像素" ?, y2 B6 U' y4 x6 r1 l4 i
    L        8位像素,黑白, \$ c7 w8 e: j* B( c4 I; v
    P        8位像素,使用调色板映射到任何其他模式( O" a, z& U  X+ Y2 m5 ~, e
    RGB        3× 8位像素,真彩6 J. p- J" X7 [1 F! d% L0 a
    RGBA        4×8位像素,真彩+透明通道
    ; H8 i* L$ q+ E, [CMYK        4×8位像素,颜色隔离
    ) S  d& ^, ^8 T! R) A# MYCbCr        3×8位像素,彩色视频格式
    8 B% e2 ^: A9 a5 `- @3 ZI        32位整型像素
    / _5 f0 A$ v7 z4 L' [F        32位浮点型像素3 J8 l# V4 g) R4 S5 m& m% P
    4.实现效果2 W5 i- H5 d* m. Q5 x; P& l. k
    9 L6 ?+ u# j- d# j2 q9 O3 }( c
    ( }7 ]7 J, b4 q8 l+ Y& U+ n
    + I: T+ G: s( V# p. n  b

    1 w6 h8 x3 Z* S8 H9 c1 u 可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。+ L8 F1 Q  {% u% n! `, L
    ————————————————6 j$ l2 O/ P! y' m
    版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。" c6 u  q+ H- o# F. ?, I7 ^" {
    原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288
    2 |& O7 U" ]- u/ ]8 D: h7 A- X' v/ c# s) k" a. H. j& ~4 J
    0 c) M, R6 n6 L+ @' ~
    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, 2025-11-22 22:41 , Processed in 0.420689 second(s), 52 queries .

    回顶部