QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4151|回复: 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实现人脸捕捉与人脸识别(照片对比)9 |' Y7 D' j' r' _" h8 g3 X0 ~4 H. [

    " f. j/ g; F3 s1.安装包依赖
    " L8 K5 X6 p* F; b- u  {与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。
    - d# [# ^' A4 Z# p* `, o# Q. K' z( [4 G4 C9 e3 K
    在python 3以上版本tkinter是环境自带的,所以这里不需要安装& x# `5 `4 J3 O) K" Y( w' x
    " z7 W2 o  `# N
    2.代码示例9 ]  j7 Z1 L+ _! e+ ]; c$ J
    import os
    ! R" E5 V7 Q3 B4 U2 ^import cv2
    * g; Q, K& l3 h, F6 j& ]/ ?import numpy as np
    & P5 j1 Q9 {& z$ \+ D3 himport face_recognition
    4 D2 Z" x6 Y0 J( c) Y# Bimport tkinter as tk  3 Y1 I( S  b5 k5 t  L( s0 M$ ?
    import tkinter.filedialog
    6 |' p6 B3 ]/ W/ y% g: z7 U0 f9 I5 N: Zfrom PIL import Image,ImageTk
    & S' f. t6 M" Y! \8 U# k) y2 `1 E* k- X+ m& X' h
    classNames=[]) E9 ^% w8 [# b& |3 T
    img_path='Picture'
    ) |9 M8 G1 z' ?& U; L8 Vimg_recognition_path='Recognition'
    / ]" n3 v' d- w# c- _0 x% mexistsEncodeingList=[]
    7 O) X1 A4 E0 Q; \#对人脸集合进行编码进行处理6 _/ ?, n) x/ m" O+ I2 |! S: d
    def findEncodeings(images):
    , o% L4 T; E! j    for img in images:
    . r; y; Y- x) }) ?# k% a9 Y        #灰度处理8 u& Q$ F8 h# M5 {7 Z' N, \: ~
            img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)
    9 I8 c: S4 G3 \# M" D+ }+ Z        #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果; h& L: ?2 n/ P. b! H( _2 H
            encode=face_recognition.face_encodings(img)[0]3 f8 D! ]* ~) _
            existsEncodeingList.append(encode)5 X; A, f% g4 Z- I
    $ s; J, o7 T( O" A
    #获取当前存储的人脸编码集合! R$ s' w5 t* V' B* L4 I* S
    def findExistsEncodeingList(img_path):
    3 P9 m0 a% O2 k# V    images=[]( g6 _( {1 s( c
        #列出已经上传的所有图片" o. y3 p3 j, Y# G1 ?2 V  O
        imgList=os.listdir(img_path)1 q: {: L9 g% T' _. \* D
        #处理存储的图片得到其人脸编码& O) |6 D) n% x" g& O' _* y6 p
        for pic in imgList:
    ) o% ?& f5 A( o! \5 Q8 Y1 v        img=cv2.imread('{}/{}'.format(img_path,pic))
    4 b) y/ \/ ]) K; D( @+ S6 C( {$ t        images.append(img)
    1 n! z; N7 |8 \! g- V8 S/ S) R8 d        classNames.append(os.path.splitext(pic)[0])
    # |$ K. j8 _7 \    findEncodeings(images)
    * t- R% F; `1 H# L, m% m: ^& R7 m- o) ?# ]7 `
    #选择并对比图片  o% m) j2 r1 g/ N
    def choosepic():  e7 ]7 E$ g" |. l8 Q6 X
        choosepath = tkinter.filedialog.askopenfilename()
    ( |, D7 U7 n# n" C% C    path.set(choosepath)
    ) p- e- ?. A" Q9 u8 Q7 I    img_open = Image.open(entry.get()).resize((530,750))
    $ Y0 ]/ W. o% K+ Q    img = ImageTk.PhotoImage(img_open)/ i# {" `! k/ `  R
        lableShowImage.config(image=img)6 M( @0 D) x/ D1 R$ j$ k. Y" ?$ p
        lableShowImage.image = img! M3 C4 w# m7 g( i2 b4 ~8 ]
        lableShowImage.place(x=30, y=70, width=530, height=750); k  ^) O/ g( @' y, p( @
        faceRecognition(choosepath)9 x. }2 ]7 f6 x& P2 t( r* e

    + W, \8 b7 W, G; W) Bdef faceRecognition(choosepath):5 O* c$ I5 ]; E9 d
        frame=cv2.imread(choosepath)2 x5 @5 \: m: u  N8 N
        frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
    4 ]  m4 Q) K; i3 a    #对摄像头读取的检测人脸
    3 I/ B1 G2 |. R( m    facesLocate=face_recognition.face_locations(frameRGB)* g  |7 S" d) z1 \
        #进行特征编码
    8 F0 w. M4 ~" n% d$ K    faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)/ x* f5 h9 g& g+ z8 z# I
            #遍历检测的人脸和库中读取的图片进行对比,计算其相似度
    : l. r: W" N- M/ C    name='unknow'
    ) A' b' w/ Q! I    for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):& o7 ^: Z% ^6 x) u% ]( @0 `
            #进行匹配
    9 B( _8 d& B0 L) ]/ _" D4 z        matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding); {2 P$ z8 {; r+ D: w" e
            #计算相似度
    8 Q- K% |1 [8 |6 _3 W; a. N        distance=face_recognition.face_distance(existsEncodeingList,face_encoding)
    : a: h9 n6 f. r: `5 J        lab='unknow'  V" I- R8 z; ?- @
            for index, item in enumerate(distance):& ^# r' f. O/ f; S0 k1 k3 _" C
               if item<0.5:
    % p0 m% e9 q4 `9 n                if matchs[index]:
    # W' q0 `+ `; D( Q3 t: D                    #得到匹配到的图片名称与相似度值
    6 d& Q' k$ D2 I2 c* t                    lab='name:{}; Similarity:{}'.format(classNames[index],item); v1 g/ s% s% l3 o3 g
                        name=classNames[index]
    # }( T. Q% L- Y                    break3 h* H0 V8 ?$ w" `
            #初始化面部捕捉框显示绿色2 x( G5 [3 p" U" _$ y
            color1 =(0,255,0)4 s) P. H$ W8 B" o- V' \0 r' h
            if name =='unknow':9 x5 r+ H" t/ Z8 s
                #未能识别的时候显示蓝色9 D) X% z8 J- H) S# z6 r% r2 P
                color1 =(255,0,0)/ f  ?4 \( u) r9 d0 z/ O
            #画面部捕捉框
    & V/ i! ]( O+ }" v8 X        cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)
    $ |) y. `% |% U( m: ?        #在捕捉框上添加匹配到的图片信息  |; z3 I) i: _  s0 \& X
            cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)
    " r; a" f8 d) Q        cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)8 h+ V) y, p9 B3 P- F
        img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))2 C% m) I/ Z5 B
        img = ImageTk.PhotoImage(img_Recognition)
    * K5 O: Y' q: B    lableShowImage2.config(image=img)
    , ^$ X( T) S0 i    lableShowImage2.image = img
    3 V  D- h# N0 ?: L6 m6 O- R2 R; u    lableShowImage2.place(x=630, y=70, width=530, height=750)% B1 q3 d+ K7 q% c" }; G

    1 {5 A) R, u$ d  g( V3 b6 Tif __name__ == '__main__':
      C: t/ O( Q( u" D    findExistsEncodeingList(img_path)/ k$ ]7 ], ]0 [
        #生成tk界面 app即主窗口
    # O# A$ y$ g1 q) Y( N    app = tk.Tk()  $ |0 J* w( t! T
        #修改窗口titile
    0 z2 Z& G+ I, \: R    app.title("show pictue")  
    - \2 v- U# ]9 d' e! J5 N" y5 D; M    #设置主窗口的大小和位置: C/ C4 m8 s7 }# P+ j' u! w7 H
        app.geometry("1200x900+200+50")
      q" B: U3 p% t8 A# `5 \$ x) Y    #Entry widget which allows displaying simple text.
    + S$ t' Q4 c' B; H! H. i7 ^    path = tk.StringVar()
    & I0 V. q& e: j1 z; Y; ?    entry = tk.Entry(app, state='readonly', text=path,width = 100)
    + h9 h8 E* H' Q3 u+ l' [  a5 G    entry.pack()
    4 c  K; t4 a/ n" r" z! J, U) v    #使用Label显示图片
    & s! h: q, p! ]4 B  b, ^, I# t    lableShowImage = tk.Label(app)
    : G/ s9 m/ S6 C; p9 e    lableShowImage.pack()
    8 o. X5 g3 Z/ [" f2 o; n! i     #使用Label2显示处理后的图片7 ?( l4 @' ?. {- ?
        lableShowImage2 = tk.Label(app)
    / @6 b9 k8 r1 e+ w3 p" y! z1 W    lableShowImage2.pack()
    ) A( P' N4 {( l# d% {- ]- k& u; V6 s    #选择图片的按钮
    % P+ k; x$ T+ Q7 L4 r+ ~. p* _& z    buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)
    * j. V. g' H% W5 R9 i    buttonSelImage.pack()# n7 k  O4 |" E0 T5 ~- v( w
        app.mainloop()/ T8 L3 J4 h2 J2 N, V

    8 }9 j; F' M# Y2 _+ f( N+ Z3.说明
    + Q4 U; I6 Z8 ?9 Z* D! e+ v首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。
    + ^* ?/ K  G% H; G2 e9 q4 i2 J) L/ z  I9 d/ X- f7 ~4 _8 ~" q& M

    0 i; D  W7 {; S! N+ J( w$ m1 L' H% J1 G) V) s6 C  a
    其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片$ ^8 T. f8 b" D' |8 V1 k/ f* P6 ~
    1 C' |, {' z# K# w, d1 d0 d
    : Y9 O9 Y) g/ T1 Z; \  g
    2 e& d7 T# R; F* s- p. x
    但是效果会存在色彩的失真,效果如下:
    & E( _; o& G/ n6 E* Q6 K5 a: \8 |  r% `2 T
    * r, H" M8 T6 l+ X; {$ ?' u
    5 `. X& w: ]0 g5 f  o/ {; S' P- J
    也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。' ^8 m/ R, s; G+ c  Q" {
      \  o4 w) O5 h) W
    这里简单提下PIL的九种不同图片模式:
    / k1 }( k" B5 ?7 p# m& ]  C( r
    modes        描述
    2 O9 K/ Z0 V6 b6 d% z3 h8 d- C1        1位像素,黑和白,存成8位的像素+ O0 `. c" K  N! k$ b8 E
    L        8位像素,黑白7 p& G7 x) [( }+ R6 y" X* o
    P        8位像素,使用调色板映射到任何其他模式/ O; d% ]" \' ]  `. q: B9 C# w4 l
    RGB        3× 8位像素,真彩
    " R! E, |5 m! V( U6 {, p" mRGBA        4×8位像素,真彩+透明通道
    9 g" W! w$ [$ _8 v3 `% B+ r7 kCMYK        4×8位像素,颜色隔离6 r% y2 \% G2 X
    YCbCr        3×8位像素,彩色视频格式
    ) v& p* A) F  e4 p8 xI        32位整型像素8 f3 m9 Y/ Z: C, r- ?- q0 X
    F        32位浮点型像素7 r) W" ^) a: W! b# p, Y0 g& }1 B
    4.实现效果/ R5 L' D, r" @- D- W3 R& Y

    1 j( Z! y* i- ~1 m4 p  P" ]) N. V5 I! i- T; j" N

    * l1 L, o. d/ K) w6 D0 N, Q1 B8 h+ y" x4 w' |& I% |
    可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。
    ' f1 ~8 s! d0 T- }' S# Y1 W————————————————( r- ], T5 I8 `5 A$ R4 H4 N
    版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    ; F# A3 `$ h) n3 w+ a原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288/ D  y3 n4 x$ n8 G

    # Q, Y& d$ m, e( E2 ~- `; T; ]
    9 M1 c9 Y- k8 ~% 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-4-21 23:54 , Processed in 0.404575 second(s), 50 queries .

    回顶部