数学建模社区-数学中国

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

作者: 杨利霞    时间: 2022-9-14 17:07
标题: Python 基于OpenCV+face_recognition实现人脸捕捉与人脸识别(照片对比)
Python 基于OpenCV+face_recognition实现人脸捕捉与人脸识别(照片对比)3 ^3 W7 d* I4 a/ r# k
/ }# P4 d# O& @
1.安装包依赖
5 u1 p4 `% K! `2 K! y与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。+ [4 B2 j7 `; N/ ~4 x( N  V, D4 [: N
3 b2 i" b% p% }# N, L
在python 3以上版本tkinter是环境自带的,所以这里不需要安装# f4 R; l" r, Z4 ?; G3 }6 U( E
$ b6 i/ R# J# ]3 q: c
2.代码示例
+ |  a. Q, x4 O# h# ]; bimport os" B* m9 g0 {, O
import cv26 a0 b; Z  V: T1 J# F
import numpy as np& ?& o3 C& O8 W: Q9 C* h/ |$ @
import face_recognition% ^! C# P0 v, g% X! f
import tkinter as tk  ' o' O: a( M& g9 I
import tkinter.filedialog
: [; _) L$ N* H! a5 Ffrom PIL import Image,ImageTk
3 a" g" Z5 y$ N5 Q8 B
; ?8 i/ l) F: ~classNames=[]
7 Z) D6 L, y0 v( l1 u2 vimg_path='Picture'
5 E/ M" R3 I& C) S6 kimg_recognition_path='Recognition'
. l, N$ H! }: D* h( A1 P& `" j6 M( ]existsEncodeingList=[]% d: L3 ], Z' z% p. n0 y
#对人脸集合进行编码进行处理/ B* v) Y5 X' N9 q, X
def findEncodeings(images):
  x3 T+ m$ ]- A: n! C& U/ H7 [* i    for img in images:
* ?; j4 A5 Y1 }6 K1 Z        #灰度处理) A, o1 G$ G- p8 f/ W; {7 ^
        img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)
4 ^0 ?5 S3 Z4 b' f( q8 s3 W. u        #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果
  F! `/ E: o% I7 R0 Z# U        encode=face_recognition.face_encodings(img)[0]
) A. I4 x; p$ q! N9 }        existsEncodeingList.append(encode)
$ Y& P1 g. [  K/ Y, Y% O: d$ d: Z* u* \8 ?& w1 K0 z
#获取当前存储的人脸编码集合4 O% ~- g/ f* o. g
def findExistsEncodeingList(img_path):$ r* y# n9 I+ S; L* a1 b
    images=[]
; ]# e1 o& V* L    #列出已经上传的所有图片% ^2 a4 R; T. L
    imgList=os.listdir(img_path)6 J8 X3 d' K( L  d9 |" Z2 ?/ Y4 |
    #处理存储的图片得到其人脸编码/ b7 d& a5 \% {) m: g) g; r; L
    for pic in imgList:
* f" M0 \, [9 a/ w        img=cv2.imread('{}/{}'.format(img_path,pic))
2 U) g/ [5 ^9 z3 B        images.append(img)5 {8 ?2 l+ [3 q" _+ [/ o4 {
        classNames.append(os.path.splitext(pic)[0])
* J; L3 L9 d/ ]. h! L! [, n3 N    findEncodeings(images)7 A, L9 P: d5 T

% l% _# K2 ?0 `& m; B; h4 [#选择并对比图片: X9 F$ Z6 S. ]% }& w! l, n" w
def choosepic():7 d: h$ Q# }8 R4 G+ s7 W2 N- L
    choosepath = tkinter.filedialog.askopenfilename()! B, ~5 p) O  ?6 z3 D
    path.set(choosepath)5 _2 B7 x3 ]* s. i) j5 _9 o8 e; Z9 m
    img_open = Image.open(entry.get()).resize((530,750))$ c1 ?9 s/ S. p; r3 X
    img = ImageTk.PhotoImage(img_open)
9 U2 I+ x: g* B3 L    lableShowImage.config(image=img)5 l7 @4 a% U) Q& ^# k# X
    lableShowImage.image = img
* G6 o& ~) B; n" P* ]( D- A+ ]7 j    lableShowImage.place(x=30, y=70, width=530, height=750)" d# `5 f0 Y% |/ C2 t% t  i# z
    faceRecognition(choosepath)
9 g/ w1 e4 Z  F, I. e4 T6 e8 p/ s2 r5 M  g' b
def faceRecognition(choosepath):
4 ^) T8 P& k+ q' N. F9 P/ X. y    frame=cv2.imread(choosepath)* y6 K$ m0 p1 B. K, M) W7 B
    frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB), {6 R6 T& o2 C- u
    #对摄像头读取的检测人脸
. Z9 C) I2 P. Q    facesLocate=face_recognition.face_locations(frameRGB), R- x6 ]4 M# Q0 J# o' r" @* V
    #进行特征编码2 O5 f6 _0 \+ P4 I4 v' U
    faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)
; b, D( Q- T1 G  r+ C        #遍历检测的人脸和库中读取的图片进行对比,计算其相似度+ \( }5 t' m, h; f) N" r% O
    name='unknow'
# M+ E6 K" v1 \* `6 |    for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):
0 x8 Q1 j: b( a. A        #进行匹配
! r! O2 y: J7 h8 l* Y        matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)
( M1 _( K2 E/ X* k  ?- a; T/ X$ L        #计算相似度
+ R" H6 S$ i& W# |* C. U' |2 T# v        distance=face_recognition.face_distance(existsEncodeingList,face_encoding)
$ P7 \! h% `+ Z6 E        lab='unknow'# M! S. Y& V9 [9 I7 t  v
        for index, item in enumerate(distance):
0 G$ E7 H0 ^  S& w           if item<0.5:
; t; w9 H2 F/ S% w/ ?3 @7 \                if matchs[index]:; ?$ o2 `0 W! d: \! E
                    #得到匹配到的图片名称与相似度值5 o6 s  e) K3 n6 G1 A6 |/ q! U
                    lab='name:{}; Similarity:{}'.format(classNames[index],item)
5 B6 \& x( x0 z3 R                    name=classNames[index]
% V* c8 S% E- A- k5 V                    break- S2 ^, O5 N: p
        #初始化面部捕捉框显示绿色
) b" n9 ^) c& e8 y( l; E: W' W- x        color1 =(0,255,0)
$ v: K* E9 N2 I7 I8 ]        if name =='unknow':# N5 `2 A3 f+ X2 k& Z/ s; A- l
            #未能识别的时候显示蓝色& u! F! j7 F# S) l+ a7 ]3 C( Q& M
            color1 =(255,0,0)
% v& z) Y, G1 {% C+ [7 E        #画面部捕捉框7 y' F8 k) T/ y! \4 d
        cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)% j5 X; h3 Y$ x1 j& q( D. s4 J3 b- ]9 q
        #在捕捉框上添加匹配到的图片信息
* O9 I. L# o% O; z6 g$ S; Z  l/ E7 I        cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)
/ [" [' w6 Z2 D* I        cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)
: l1 P* {  X2 B4 L+ p0 N0 Q    img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))" P2 t( f0 m$ ^: L; r+ H' I) j
    img = ImageTk.PhotoImage(img_Recognition)
! Y8 d9 f7 a: q7 H1 p7 b( H    lableShowImage2.config(image=img)
; I+ W3 h+ W0 I1 n6 R7 W, S  [    lableShowImage2.image = img# Z9 g3 n; N6 V/ L; c) V# j9 D* M3 g
    lableShowImage2.place(x=630, y=70, width=530, height=750)
4 S1 Q5 z& L4 j+ m3 }  ]+ S, r3 u. f# D0 K& k$ O# F3 s
if __name__ == '__main__':
( y# }1 M8 N+ \; O5 p    findExistsEncodeingList(img_path); c: O, |& S* E4 n- j
    #生成tk界面 app即主窗口6 U2 L( p. b% K; {9 z
    app = tk.Tk()  
! `0 m! `+ [5 P$ D, m    #修改窗口titile
8 ^- k& t. u* l3 M4 O7 I0 n+ S4 c5 o    app.title("show pictue")  
- O# D% ~& p7 W3 |2 P    #设置主窗口的大小和位置
) ?& v) R- @7 `1 y7 p    app.geometry("1200x900+200+50")
) H& y; x0 g6 R0 B9 a% q' S    #Entry widget which allows displaying simple text.
7 L- I! P+ \% _3 B& ?    path = tk.StringVar()1 e* J7 n3 E# F" n% @
    entry = tk.Entry(app, state='readonly', text=path,width = 100)# |( o! P  H( \0 R& D
    entry.pack()
% }$ @5 M; c7 p0 F6 r8 ?  r2 c    #使用Label显示图片
0 r; T% r/ N6 d9 o    lableShowImage = tk.Label(app)
* G3 `, \' P( ?* O9 F0 O    lableShowImage.pack()+ `" X9 `, ~6 ]+ C- \# O: f
     #使用Label2显示处理后的图片
) B; w4 n9 {  c+ j0 j. A    lableShowImage2 = tk.Label(app), J5 J- |) V: N0 ~
    lableShowImage2.pack()
9 A$ n1 l. g$ \9 H, F    #选择图片的按钮
- O% T. T! K4 p5 }/ ?/ u    buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)  e; _8 M. O/ D. r4 L8 V
    buttonSelImage.pack()/ t+ J5 _9 D3 r4 J+ s" m, a+ Y
    app.mainloop()
. A! V8 R% l/ q% M% k4 Y) ]" h; q7 s; x( ^. C8 ]7 a8 D9 x+ j
3.说明8 {  A/ D4 |- h; K1 v; a0 L9 k" _# d
首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。2 F3 N0 S+ |+ a. P

- D- U0 D1 d8 l* n7 S  j% U
8 f7 i" z8 k" _; a1 ^
9 x  P& b$ m" g2 z* o" J0 r) K3 O 其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片: m# r* P4 w- a1 O6 U: n& o

) D( a8 c* A* i9 i! a2 l5 u
8 l6 T( {2 C1 G
- R4 A4 x2 q# i( t$ H' v" q6 o 但是效果会存在色彩的失真,效果如下:% O. n: S8 {& S) _. `8 y5 v
& R6 f0 O. n2 J5 \
7 M4 U# ?: X6 f# ^% a0 u

6 u) {4 ]) z1 s9 {+ Q也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。9 i4 ?6 e& k6 O! _8 U5 {2 d0 m$ |
0 J( x- Q) i8 h# U0 b
这里简单提下PIL的九种不同图片模式:/ r7 }; M7 R* ^  x

% X* y& F9 j& @$ V# Gmodes        描述" l/ |0 A: Y3 i7 D' W( ~. M, h! w% }
1        1位像素,黑和白,存成8位的像素
# |, E  R) }8 YL        8位像素,黑白
0 H# e& s3 H8 z, P9 \% MP        8位像素,使用调色板映射到任何其他模式2 D6 `* r! k7 i0 S5 `1 o
RGB        3× 8位像素,真彩" f0 Y% @2 _! }5 u
RGBA        4×8位像素,真彩+透明通道, U4 y3 e3 s+ j& D
CMYK        4×8位像素,颜色隔离
8 Q% B9 ~" t. ~! {' I4 xYCbCr        3×8位像素,彩色视频格式
, `. `0 r" d+ m/ Y5 F2 fI        32位整型像素, D  x$ e* n9 K
F        32位浮点型像素
+ W  v8 P3 o4 K. A+ I4.实现效果" }% V: a: y/ W0 B  {3 }

9 _, u8 ^7 ^( _( a9 a  D0 W
+ O1 R, x7 T/ N' w0 d0 ~1 P8 ^; W+ m* @5 @6 ~
6 O  t" c1 }2 I# ^& o9 m
可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。9 ^9 V$ V7 H0 O$ o# w# T1 p
————————————————9 Y% X# l0 M; M  i1 M8 j" T
版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
* u: q$ _' f8 t' C0 w原文链接:https://blog.csdn.net/qq_17486399/article/details/1266292884 a) g, G9 T( l9 @/ m
1 `/ R1 N; L* x% h6 x
2 o4 [. s, |: R- y/ o7 D6 t' _; y





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