数学建模社区-数学中国

标题: Python 基于OpenCV+face_recognition实现人脸捕捉与人脸识别(照片对比) [打印本页]

作者: 杨利霞    时间: 2022-9-14 17:07
标题: Python 基于OpenCV+face_recognition实现人脸捕捉与人脸识别(照片对比)
Python 基于OpenCV+face_recognition实现人脸捕捉与人脸识别(照片对比)) c2 D1 e) n: _% n* ]. ~; L  d3 u$ N

, H  H. F! u- r" L( G, r: F1.安装包依赖
& u: S) b9 T6 I2 Y( X$ ^与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。
) W7 A( k1 W& V( g$ [3 ^/ i! h
+ s, S$ N, T6 I' z+ M% A* e; [在python 3以上版本tkinter是环境自带的,所以这里不需要安装7 @1 q$ F3 s) V: x

0 x7 I- @$ I: b" I) A2.代码示例% o$ L* k' }* T# E$ ^7 d( B7 H  ?7 T6 W
import os
! m( y! ]0 [* }5 Dimport cv2  K$ d8 ~8 w3 O- j' D
import numpy as np2 ?$ g! i1 j* |! l# z7 F! ]
import face_recognition
/ B- T1 i4 b& R6 H# z. u! @. qimport tkinter as tk  
, J; S  o& Q2 ~9 c  ?/ P' S4 Rimport tkinter.filedialog
) |5 w# {" N0 T7 vfrom PIL import Image,ImageTk - m' O! E7 Q& q, J
. C, k, ]  c2 K! N2 h! Q) i
classNames=[]
% j* J3 f. C: ], r) eimg_path='Picture'3 l$ S1 _2 W0 ~2 _8 I+ [
img_recognition_path='Recognition'
- w7 E$ {" a5 Q3 LexistsEncodeingList=[]
" ?0 o% u0 t1 A% m5 b#对人脸集合进行编码进行处理3 [1 \6 o6 G. r, F4 Q
def findEncodeings(images):
' ]) T( J1 f  R" R    for img in images:
, T" C$ @2 w' O: l5 V0 j* k) _        #灰度处理) ]2 J9 {; P2 \  k* {8 U7 z5 L
        img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)- C/ W+ U( S) X2 [, e: t% A
        #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果
1 E( s6 x, d& F        encode=face_recognition.face_encodings(img)[0]
0 |' [! g8 i$ V  M        existsEncodeingList.append(encode)
) Z% f4 d* c- e0 G5 S% f( l  A& W0 Y+ ?% l; v6 n0 q4 Z$ K' F+ N! d
#获取当前存储的人脸编码集合1 S* C6 y& Q5 S
def findExistsEncodeingList(img_path):* y8 X6 s4 I$ w# U* _! [  r" b
    images=[]
9 S* e) T2 G3 F. G    #列出已经上传的所有图片9 K5 H( E8 m! L1 i) E# L
    imgList=os.listdir(img_path)
$ {# `% Y& T1 {9 S* |4 g, g2 p    #处理存储的图片得到其人脸编码
7 ^9 [* o4 x# f; m    for pic in imgList:0 V3 e- @( y# X- U3 A- I
        img=cv2.imread('{}/{}'.format(img_path,pic))
9 i. r! X* Q, w; a1 j, M; z        images.append(img)
# g( K3 ]$ \  b9 I        classNames.append(os.path.splitext(pic)[0])
- a' f0 S+ g, g- T    findEncodeings(images). m* B7 G% P0 V! A9 L: t8 M8 c, T3 y

7 }+ C( c% z; W# F; M#选择并对比图片: p& v) l% p3 O; F& Y- Y
def choosepic():( E" Z$ z8 b6 I) l
    choosepath = tkinter.filedialog.askopenfilename()! F: @. d* G3 w5 I
    path.set(choosepath)
! a2 H' Q) \9 ]* M. B    img_open = Image.open(entry.get()).resize((530,750))
; `, O. E! r2 p8 ^5 {! K6 t, B. r    img = ImageTk.PhotoImage(img_open)
0 Q8 b3 V: @% t( C" U# }    lableShowImage.config(image=img)# e# Q( v( d* d
    lableShowImage.image = img! i9 ^' b* O+ C, [9 K. c
    lableShowImage.place(x=30, y=70, width=530, height=750)
) X: z" K7 d2 R: D' H    faceRecognition(choosepath)
2 g) v2 Q8 f, B% S8 C8 ^7 }4 p1 E
# u$ L- Q0 `( {8 f2 t' @def faceRecognition(choosepath):' O! q& Y0 k2 l- Z& Z* C  ~" f
    frame=cv2.imread(choosepath)
% Y2 M+ T5 m2 |4 j    frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)& I5 h. P3 Y1 S4 ^  `4 Q
    #对摄像头读取的检测人脸! W' T# F+ M0 {$ B; R
    facesLocate=face_recognition.face_locations(frameRGB)
3 p+ o4 P4 _" @5 f& ]    #进行特征编码; g8 U- y/ p+ Z2 ^- p* [
    faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)
+ M3 c* m  O2 z! b        #遍历检测的人脸和库中读取的图片进行对比,计算其相似度
5 T9 g9 W, |6 J  ^' t* d8 U    name='unknow'
6 f( e7 [! z4 @% z# Q' }- p  [    for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):5 N; V8 A6 U& k) i+ e8 n
        #进行匹配) C4 U2 G& y0 n3 c' @
        matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)) l3 x( g# e& f9 d# R, [+ v! G% ^
        #计算相似度8 F/ D4 R5 b- O5 L) a* `$ R
        distance=face_recognition.face_distance(existsEncodeingList,face_encoding)
( o5 {! ~" E& L0 |6 W        lab='unknow'
5 ]6 _5 C' a5 G8 D+ R* g4 ~        for index, item in enumerate(distance):4 a3 f- b+ h. x5 n5 k; t
           if item<0.5:
0 D8 b) k! P; V; H; d                if matchs[index]:" n. A0 C- S* e5 L# w/ k
                    #得到匹配到的图片名称与相似度值2 {2 F* j4 {" n3 f+ b! p& W9 }. i
                    lab='name:{}; Similarity:{}'.format(classNames[index],item)
( }7 q3 G3 }$ N( l9 ?( Q                    name=classNames[index]
! l0 N$ J: r2 ?. h' l' U; R. B7 O                    break+ h+ a9 ]4 k. V8 [' e
        #初始化面部捕捉框显示绿色0 D0 o8 |& Y( I4 N
        color1 =(0,255,0)
3 ]: S4 u0 v: E        if name =='unknow':
6 d) j" n% {0 R" V) e. J            #未能识别的时候显示蓝色
+ P5 H7 V' A7 }( J$ ?, B: ~: v& P            color1 =(255,0,0)* |2 q) [- K2 F; `7 a
        #画面部捕捉框0 u: P# v" L1 S$ \5 v$ I/ u
        cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3). E. [* f& q/ E8 L1 [" C) L- ]
        #在捕捉框上添加匹配到的图片信息
: I3 e3 w1 e& z* r; W        cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)$ T$ y. @, K8 F2 M* r; B! \
        cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)/ ?' Q1 k: `- c5 a" i# d
    img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))
  U, |: j3 Q* Y; h    img = ImageTk.PhotoImage(img_Recognition)
# z" F) F$ I' s; b  U    lableShowImage2.config(image=img)
1 s6 D' F: e7 l' p9 Z7 I    lableShowImage2.image = img
% H4 V5 h3 g) s0 @# V    lableShowImage2.place(x=630, y=70, width=530, height=750)& {! L* S2 A/ u
9 i5 M' h. z* H. h0 x
if __name__ == '__main__':
9 k% z  Q# H7 J: J    findExistsEncodeingList(img_path)
/ N. Q$ M4 R; l- g4 @8 C; `/ e    #生成tk界面 app即主窗口
2 w$ M! j7 G" [8 O0 k, n$ W    app = tk.Tk()  , G5 y, J2 l- p. F, Q( G4 p) i
    #修改窗口titile7 }  n" I8 t( g# z% X
    app.title("show pictue")  ; c7 i2 k1 \0 e  K/ R: {2 m
    #设置主窗口的大小和位置
0 ?; i" a# y" l0 l5 l! ?1 U6 e: w    app.geometry("1200x900+200+50")! c) t: C4 ]8 O( b8 \
    #Entry widget which allows displaying simple text.
3 j$ V( R" W- Y    path = tk.StringVar()
/ W" e& h2 O0 W0 T    entry = tk.Entry(app, state='readonly', text=path,width = 100)
" ^" z# m1 v' T# x" R! A6 G* F    entry.pack()
$ \3 Y' S0 M4 D3 B; @  O    #使用Label显示图片
5 d9 T: I9 M" I' h  s5 B2 @1 z1 ^    lableShowImage = tk.Label(app)
$ U: {) z8 Y3 k1 R6 x+ r! M  b    lableShowImage.pack()
, h7 @( G1 ~  f5 h' {     #使用Label2显示处理后的图片# d/ ]3 a- S1 p: Z3 x
    lableShowImage2 = tk.Label(app), G8 u5 w" I. S3 c1 ?2 w+ F! m$ q8 }; z5 H
    lableShowImage2.pack(), u! X5 e6 @9 m0 t% B+ |
    #选择图片的按钮* y& R2 @. ~5 X! z/ a: V
    buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)# s1 l& u* M+ c! c1 t
    buttonSelImage.pack()
; N0 y9 z0 P2 s( {7 N7 e! [    app.mainloop()
; G, d' c* |+ E' u7 P1 Z. W- f' n( Y2 P. m* B' {) E
3.说明1 B. J9 Z' L& L3 \( K
首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。1 P2 G, p" i& p* f" p3 t+ D& ~
3 I2 z. }# G! t- H+ ~3 r# H0 N
3 D: b3 E3 O/ y3 w! W( p
+ ?; O( M' ?7 i. F) {
其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片
* k9 H; P+ S+ W7 w
( |: `8 ~: X; v8 i+ U/ I* ]" k
1 X" O: q/ |- Q( c& y2 u4 t
( _& O" {2 Z% ]& e# g: \6 y4 S, [ 但是效果会存在色彩的失真,效果如下:
, ~; ~; b4 ^: Z/ k; x2 d# ]/ i9 s8 M& t# \# ^5 q
7 J- K5 i' k# C7 t) L) K0 u
' @; b& T, [3 f; ?' g, m
也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。( S9 c" C+ ?# _! C! L. H6 X

) T& }- w' R! x  q这里简单提下PIL的九种不同图片模式:! u& J0 G& ^1 V+ _
* r: ]  [3 v& n
modes        描述
  m; t- s% c: Q) V) ~0 N1        1位像素,黑和白,存成8位的像素
. ^% r8 o- l! C% u! N- w/ [9 b& _9 NL        8位像素,黑白
! N2 j5 N, ?; E) yP        8位像素,使用调色板映射到任何其他模式2 k+ S5 `8 E6 {! K! B# x! `) Y' ]
RGB        3× 8位像素,真彩& u- y! c+ B- P* V
RGBA        4×8位像素,真彩+透明通道  ?" Q, L# F, `( }
CMYK        4×8位像素,颜色隔离+ c3 f2 x2 [3 G1 s; W9 P% _. ?4 z
YCbCr        3×8位像素,彩色视频格式
" z/ i7 I: k, m/ p) D  ZI        32位整型像素
' E6 R( K9 L: F3 tF        32位浮点型像素% C- r1 H. n, p  ^" S
4.实现效果
4 a& v3 Q, J. M# p; }* b+ ?+ l3 v4 s8 M4 j
( ^! L" m; w! ~2 z+ o
+ N6 ~* O, U+ B* X0 m, A2 {" B- k) @
" e2 X1 L) v/ U* g
可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。
8 W% j' W0 Q8 u. u# n2 H8 }& ^————————————————
$ Z4 ~& \5 X' ]4 p6 M! z. V2 I版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。" @! d) C' n/ B3 \. w5 j
原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288
. |0 b# e, i- |- `9 [/ X2 o8 z3 }5 Q: S: q: f
/ h  u0 _. c! G6 f% O6 O& ^





欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5