- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 565163 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 174772
- 相册
- 1
- 日志
- 0
- 记录
- 0
- 帖子
- 5313
- 主题
- 5273
- 精华
- 3
- 分享
- 0
- 好友
- 163
TA的每日心情 | 开心 2021-8-11 17:59 |
|---|
签到天数: 17 天 [LV.4]偶尔看看III 网络挑战赛参赛者 网络挑战赛参赛者 - 自我介绍
- 本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。
 群组: 2018美赛大象算法课程 群组: 2018美赛护航培训课程 群组: 2019年 数学中国站长建 群组: 2019年数据分析师课程 群组: 2018年大象老师国赛优 |
Python 基于OpenCV+face_recognition实现人脸捕捉与人脸识别(照片对比)
8 r7 n j% G: s- c% C+ P8 D+ A& D
& i; @% c# I# N& ?% {$ | @1.安装包依赖! _( D( c# V4 A4 u& F/ W. Y) }
与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。2 ]* {' v1 L" F5 O% \
8 v/ x. R) D) v在python 3以上版本tkinter是环境自带的,所以这里不需要安装
2 F0 a m( d5 j1 s3 P
# S% Q4 T' c2 j6 b. D" }7 z2.代码示例$ M; P( n4 j$ F0 q# x
import os: d) I% W6 l v. _' K/ s" N
import cv2
6 {5 X: ~; O! u6 \, d; S/ j8 ^import numpy as np
- H9 W/ o A% E/ X" Y# timport face_recognition5 p# }1 }" e' f6 G6 c% o; r
import tkinter as tk
) @3 b/ {5 h& y( oimport tkinter.filedialog
3 Y6 r6 r9 u" _( D9 o xfrom PIL import Image,ImageTk * V: ^ X/ p7 p2 @
% A# ~9 m2 q* C* k
classNames=[]
1 n) _) o1 V6 y3 Vimg_path='Picture'
( q6 Y# |9 P8 e" ~- r5 Wimg_recognition_path='Recognition'! y# K5 R* X* l
existsEncodeingList=[]
- g! a5 x2 i5 t3 j! R h; c#对人脸集合进行编码进行处理( v# P$ e9 G2 _% z& T$ k- @/ d
def findEncodeings(images):
1 r( a7 _/ [- h6 r for img in images:1 L8 S3 K) k, j4 H( p
#灰度处理
7 O& f3 w0 R* b* ~- s$ u9 k img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)) C% S- s, f9 ~" o, U" V6 O
#face_encodings对图片对象a_images进行编码并返回数组0位置编码结果
! {5 k1 l9 H( Q9 u encode=face_recognition.face_encodings(img)[0]
. a. X" ?& X+ ~' Y. J. a. T existsEncodeingList.append(encode)
0 ?" ^8 m& J5 M
, x8 x2 R. R9 Q) ]3 D3 q! d" s4 }#获取当前存储的人脸编码集合
- ?: T6 W1 Z4 ~ U$ S! r0 ~def findExistsEncodeingList(img_path):% s% f5 m7 |4 Z* g* G
images=[]
5 m# Z: S0 A) ?/ C #列出已经上传的所有图片
$ ]/ l+ s }( O" e/ W0 _ g imgList=os.listdir(img_path)8 Y+ g. G- k* i" c4 i* F5 O0 m
#处理存储的图片得到其人脸编码7 |! ^+ d k4 V1 j* \+ _6 o5 ?
for pic in imgList:
0 Z4 r m+ i8 y: O" `' \) D E+ O img=cv2.imread('{}/{}'.format(img_path,pic)) G5 B1 s! E& C: K6 A @, P# ^2 f9 F
images.append(img)
* o5 l3 [: Y" z E9 s! L1 n classNames.append(os.path.splitext(pic)[0])
' \6 Q' U! Z2 u/ |; B1 m: \ findEncodeings(images)
2 u% X5 D. A8 t0 y. P' B+ M% U. t* J- S, u
#选择并对比图片8 m/ b0 g0 S( R G( F( E* `: w
def choosepic():
5 u4 {* J; p$ g: q6 i9 m! O choosepath = tkinter.filedialog.askopenfilename()
4 W# ~4 G' @+ X9 g0 E4 \ path.set(choosepath)2 e& g) o' l5 {5 \ L8 { [; b
img_open = Image.open(entry.get()).resize((530,750))6 E& _4 E& C) t' B- R1 _+ ?4 \+ v
img = ImageTk.PhotoImage(img_open)
w: T! N: z) m1 m lableShowImage.config(image=img)
+ _$ @8 B; z! [* w# g. l lableShowImage.image = img
3 _1 [3 u* r0 _: J! T, B6 F lableShowImage.place(x=30, y=70, width=530, height=750)
3 Y4 {4 u: B3 [- n5 `( i faceRecognition(choosepath)4 F9 c+ o4 p% l7 z
8 ?) [ @6 h( I+ r7 z1 s4 ^) y. R
def faceRecognition(choosepath):+ ^) [ `8 [9 I
frame=cv2.imread(choosepath)
: ?) Y& Y) d: Q. B# i5 H frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)% ?" b O% v& I: g- b+ q+ ?4 x% o
#对摄像头读取的检测人脸
- D) e# D! M2 P7 w facesLocate=face_recognition.face_locations(frameRGB)5 |0 z, g( a- f3 l, f
#进行特征编码
5 j% R- Q; H$ }2 h3 |' t, L faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)6 _. H9 n; M \# r! L9 {
#遍历检测的人脸和库中读取的图片进行对比,计算其相似度- n& r6 _, p! `, ~' v: I6 ~) S
name='unknow'
. {! J+ E% Q6 b4 x1 v$ h for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):- Y6 T6 X+ u+ Z3 t
#进行匹配6 M5 H5 F6 w: G" K2 H
matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)4 h6 q5 _; Q7 U- q5 t
#计算相似度2 [& A1 A4 t5 @; s$ S ]/ a- q
distance=face_recognition.face_distance(existsEncodeingList,face_encoding)
7 L, @) D& g8 d, E lab='unknow'
. J8 d$ Q, ~) x& u9 C for index, item in enumerate(distance):! m3 u2 C6 Y- s! m) ^$ Z w; C$ j
if item<0.5:+ _# I4 q, b, B6 K$ D- L+ u. b: C
if matchs[index]:# T9 o1 ]% M" |- p5 \* y. F
#得到匹配到的图片名称与相似度值. b( w7 e: _5 u+ `* @+ a7 O8 l
lab='name:{}; Similarity:{}'.format(classNames[index],item)4 z' b; v/ ~" P- l
name=classNames[index]
) i! T, G# v% l* i4 d break
0 Z2 [; L; ^7 X) ~ #初始化面部捕捉框显示绿色
9 E; x% Y8 }# P color1 =(0,255,0)0 X9 b2 g$ f# z: S- s
if name =='unknow':
2 t# W- m8 t O' \, {6 N: E #未能识别的时候显示蓝色
4 @, o- O3 j# \1 I" V color1 =(255,0,0)5 Z; j4 l6 s' N2 A% o$ b9 C+ D6 ?
#画面部捕捉框2 M: @ K2 U" u3 D
cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3): @$ j7 C0 F4 B6 i/ W0 g/ K; `
#在捕捉框上添加匹配到的图片信息
1 G6 n( V" T' U4 m' x cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)0 w: H5 ], {9 q- t
cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)
3 t: o* Q, x; Z" n img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))- ]/ z6 u! H! z% S) l
img = ImageTk.PhotoImage(img_Recognition)# j0 A7 M5 z! b6 @* Y
lableShowImage2.config(image=img)
- E* N3 [8 p2 \) x* f8 l lableShowImage2.image = img' v8 n: O9 \& {4 z0 R, l: K
lableShowImage2.place(x=630, y=70, width=530, height=750)
4 k, |1 o! F9 c- R- w! r
, U2 V4 ^+ A( l6 Z7 i6 x4 nif __name__ == '__main__':
5 Z; B) S* c, l$ |8 a) Y findExistsEncodeingList(img_path)
( ^5 x( @* a# G* C6 E #生成tk界面 app即主窗口
) h& A& v3 ~, W+ K app = tk.Tk()
1 I+ f& A% a* Z #修改窗口titile6 U6 }, [7 B, A' A
app.title("show pictue") ' {/ P+ n2 j; J, S1 [
#设置主窗口的大小和位置
4 O6 g) ~* k9 g* D6 Z app.geometry("1200x900+200+50")8 {5 g, a( ?& J) C$ F
#Entry widget which allows displaying simple text.
+ e' |7 R: y6 {; b9 q path = tk.StringVar()
4 Q" [' Q' Q) E' Z5 q5 X, D5 w4 \' H* D entry = tk.Entry(app, state='readonly', text=path,width = 100)2 Z8 X4 R* x$ f
entry.pack()
1 I& Q* a5 P0 l c3 y( X #使用Label显示图片
% p* k* R- l1 q3 j lableShowImage = tk.Label(app)
5 p* p) _* {' h% ~* X1 N lableShowImage.pack()
+ ~! L1 ?2 H& O7 I3 i #使用Label2显示处理后的图片
0 L) B9 u0 o9 R) | lableShowImage2 = tk.Label(app)3 |1 g2 J& N1 C" b
lableShowImage2.pack()1 w8 t* `% g) n
#选择图片的按钮
# \9 W0 O9 L5 h buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)
/ ?2 ] L- w& k3 B6 L buttonSelImage.pack()
9 W" P8 R( c/ T5 k! J/ D+ n app.mainloop()
: {( U+ Y" ?" \" J2 L
+ N& x/ }' P) y5 M# s. @1 ^1 W3.说明% U( @* x9 k+ x
首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。
6 E) j4 @ b+ y9 w( H* R& ?# T: k+ e/ I; ]) ]
) u3 x* O( q1 {. x
6 P v7 ?/ O. c 其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片5 x7 U+ V9 X6 F
1 C* @0 M. m# E$ U) ? K
" p8 W' r: ?9 c5 j7 l9 e& j7 J5 J
但是效果会存在色彩的失真,效果如下:
; @8 ?5 s( G4 B2 B) m
( f1 Q2 i0 d! H5 E: q% I; }$ v& M" X4 }) g% I. \7 d+ ^$ Z+ T3 |* W
8 g% F' E, G+ _1 t; [
也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。
& f$ `6 Y9 [- h9 E: s! G7 Y6 q
3 r- D+ C6 c' R, b- e这里简单提下PIL的九种不同图片模式:" s H5 T# X" N4 x
+ Y/ f O- l4 Q/ L/ y9 J
modes 描述1 o1 v6 \" h; k9 N: y3 K
1 1位像素,黑和白,存成8位的像素* N0 _$ G- {( h* S4 T' Q5 O* q
L 8位像素,黑白. w" s- M) M4 i5 x( U: h
P 8位像素,使用调色板映射到任何其他模式, V" H9 R- m7 I
RGB 3× 8位像素,真彩
, S4 F( m6 h4 u! D, C' MRGBA 4×8位像素,真彩+透明通道
2 b7 k) ?) U: |( C( W% z; VCMYK 4×8位像素,颜色隔离
& r( \% o* r6 c9 @YCbCr 3×8位像素,彩色视频格式- `# c6 c' p9 q. `/ r9 H# R
I 32位整型像素( x( W4 B1 @( f
F 32位浮点型像素- w) v- V" G: H5 J$ J
4.实现效果$ t7 Q: M( a+ {. K
9 Y2 @1 S0 a2 ~
+ B! @# u3 S3 z# c
5 d! b: m' m7 g& j* E$ C! X' N c* m
可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。
# C2 g5 _' w8 L, F! t2 k————————————————
+ [) K* \2 j) _% {: t0 B版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。3 y5 y8 r7 M3 E& J" k
原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288. f( g8 e c% K3 [7 O' c5 w9 `
. d& a# b( M$ s& E- b6 e1 c; h" n5 O( Z9 s; N# w$ Q. x1 X, L4 K
|
zan
|