- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 566251 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 175098
- 相册
- 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实现人脸捕捉与人脸识别(照片对比)
% i- c- |* A- W1 ~0 f* V5 o
* J- E! ?) x7 W) W4 L$ G2 S1.安装包依赖
: Q' | a5 |/ X0 C与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。. o: \/ R6 d/ n$ P
! w2 y: |: T: [2 v6 V* `在python 3以上版本tkinter是环境自带的,所以这里不需要安装
\$ D5 A9 Q9 y3 z& Y
2 M7 A/ a' v6 V* f2 y& f3 x. ]# }2.代码示例
0 B8 w; N+ ]' V- I" z- _import os! s! Z9 A7 p& ]) Z: ?, v- v6 F
import cv27 ]+ y4 H. }9 U H- M
import numpy as np
8 o6 Z' P% w' t. @& limport face_recognition% p& T2 R) l0 k! s }6 I
import tkinter as tk
; \2 c9 i2 {5 z6 b; q' uimport tkinter.filedialog
G/ h4 a S I+ E' B' E& S+ [from PIL import Image,ImageTk 2 W3 M& b, u1 W! m
$ k; _* F+ X0 g0 s
classNames=[]' V* y! d2 v' Q3 q
img_path='Picture'0 D- ?: V! K/ a* l
img_recognition_path='Recognition'
' V0 W( N/ {, n) j& Y, |existsEncodeingList=[]
8 ]/ y- h; P1 e6 m% |; {2 r! O, V#对人脸集合进行编码进行处理
6 V' x u; e w% O# w. j( _4 }# ndef findEncodeings(images):
1 p' ^. A0 W/ ^5 k. T; d for img in images:' R! L+ w, |" s& E: t3 ]) r6 u( K& y
#灰度处理
q. q- b" y. ` img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)
4 k! i N% L" v( O9 g; U) l #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果' m; Z: W7 w U- }2 P& a/ V- G9 Z
encode=face_recognition.face_encodings(img)[0]) i0 N! ]: a# n- n! }2 i3 B
existsEncodeingList.append(encode)( W- l G0 }7 Q( W, K
: e* p, i. r( }! S' d( y7 u( b% z
#获取当前存储的人脸编码集合
+ u/ M, Q, N; G2 T" @4 _def findExistsEncodeingList(img_path):
, z" k$ `! \; T+ @) t images=[]
/ C: B+ X+ r% w6 @( p #列出已经上传的所有图片% _/ X, |! ]8 ~- J4 p1 b
imgList=os.listdir(img_path)
5 u) A! G- {% [+ F: R4 c- w$ Q #处理存储的图片得到其人脸编码' j+ u, _8 J0 ?. F! _
for pic in imgList:
9 J6 Y J1 j k6 d% x img=cv2.imread('{}/{}'.format(img_path,pic))9 L1 b! p/ Y7 o" D
images.append(img)0 V4 y7 {2 {- h
classNames.append(os.path.splitext(pic)[0])
: Z) I2 G1 `: b, E& Z$ X5 z- F findEncodeings(images)2 o9 V. ]: N$ Y9 X* t
' M0 z, ^* Y( K+ N& r( ?- i#选择并对比图片- r+ h, @# s" h
def choosepic():
4 t% G& P- w$ z" O choosepath = tkinter.filedialog.askopenfilename()$ c: _! N6 I( r$ z
path.set(choosepath)
4 d# f3 @6 l8 M; K! T img_open = Image.open(entry.get()).resize((530,750))1 ^" B( J1 Q/ H. I) X
img = ImageTk.PhotoImage(img_open)/ ]$ O- h: V$ f
lableShowImage.config(image=img)9 `* _1 j7 a* r1 F8 \) y; Y
lableShowImage.image = img q2 ?4 A+ ?( X2 s
lableShowImage.place(x=30, y=70, width=530, height=750)" `* z7 Q0 w/ w! k/ q; Z8 Z
faceRecognition(choosepath)* u3 U9 g& s. Z6 v& |
6 x: j5 ^% j- q6 w! r" R
def faceRecognition(choosepath):- K! _" t- {. l6 P
frame=cv2.imread(choosepath)
9 I" S( T4 f3 ~; j9 o frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
$ K: b, e/ R1 b& x# n #对摄像头读取的检测人脸( J. \6 c% s+ U1 _4 A6 j6 m5 e
facesLocate=face_recognition.face_locations(frameRGB)8 \+ J3 n' O7 z3 g ]$ c
#进行特征编码, N+ u; `- p+ j# t# R
faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)
! g2 L6 q) c8 F E& A; L3 @% L #遍历检测的人脸和库中读取的图片进行对比,计算其相似度
/ t4 a1 F5 E3 B E/ }4 O name='unknow'
6 A- M8 D( [. I( r+ N) }0 s" R for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):
# p% `# c3 X& ~ #进行匹配$ s9 I& `3 x# X1 \6 B3 i; B' ]
matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)
5 `! W* f& \" h( g. ] f; V. | #计算相似度* P9 C6 @" i* x- a) Y- Q
distance=face_recognition.face_distance(existsEncodeingList,face_encoding)1 E% V: p6 b: E+ I
lab='unknow'
1 R0 S4 J6 H; a for index, item in enumerate(distance):7 L7 [0 J: T* \
if item<0.5:
9 ?! {0 E( U0 @" z! n if matchs[index]:
7 |# k6 w7 G5 a! N #得到匹配到的图片名称与相似度值$ J# U" v2 N+ F! R8 x" }. ^% X6 {
lab='name:{}; Similarity:{}'.format(classNames[index],item)
4 r/ k" z$ s4 A8 f% h# `; p name=classNames[index]
- P7 j. ~# s' N* R8 x break
2 F9 T/ Q4 z! X) K- t: m% P #初始化面部捕捉框显示绿色
) a1 Y4 X# s. Q8 F$ x h color1 =(0,255,0)
3 ^. j9 U j8 _4 }. O if name =='unknow':
[ a) p2 F8 {( _+ K5 v: N #未能识别的时候显示蓝色
: x- R1 [$ k) H1 n7 | color1 =(255,0,0)
5 \8 }: h8 G# S. i' C( x$ K9 X" | #画面部捕捉框5 W7 q2 N1 T$ I- U; \
cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)* V8 \ W1 E4 @8 B6 X; q V5 z
#在捕捉框上添加匹配到的图片信息
+ G' w2 ~ _5 p, m& k. J s cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)4 i3 K, T9 L5 T8 K* j
cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)
% M+ s6 [7 f* ]0 F' ^* s" K. I1 ~; S img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))! n. Z1 H! o8 ?7 B- W7 l
img = ImageTk.PhotoImage(img_Recognition)
$ U9 u' Q, u) ]7 o% V lableShowImage2.config(image=img)
9 I8 Q' X# R! _$ V v' r lableShowImage2.image = img# J5 E3 X1 n5 b0 P$ `
lableShowImage2.place(x=630, y=70, width=530, height=750)
* o0 r: f/ x* j+ a) k: Q! u7 R5 O X7 A' l4 v, ?6 C. k
if __name__ == '__main__':
J, b1 z4 k9 T4 m findExistsEncodeingList(img_path)+ Z, J& z; p6 c$ F
#生成tk界面 app即主窗口: a- h4 a1 ^# h1 r7 n
app = tk.Tk()
( p' m* G% ] n5 _ ~" B #修改窗口titile
9 K- a c$ D& z4 F9 c' | app.title("show pictue")
0 s+ @! p1 E! D3 v7 C #设置主窗口的大小和位置
) \8 x- ?7 b# W g app.geometry("1200x900+200+50"), }" A+ s$ A4 G
#Entry widget which allows displaying simple text.7 r: V4 r& g! `5 ^- a" G* R% S9 g5 Q( q
path = tk.StringVar()
\4 r$ R3 b& x1 h/ |) d entry = tk.Entry(app, state='readonly', text=path,width = 100)
7 y% X1 ~) D' |1 s7 H& r# O entry.pack()/ b# q, k2 M( x$ v
#使用Label显示图片
* u) M0 Y0 ^3 I4 p8 B/ \! t$ X( W lableShowImage = tk.Label(app)
& l) v2 N# C+ ~ lableShowImage.pack()
9 T* R6 s; }3 v3 \6 |6 G. Y #使用Label2显示处理后的图片
- c& i' U5 w1 P( S( \6 q lableShowImage2 = tk.Label(app)
& N. ^% F; l0 l8 q) S6 @1 a7 x lableShowImage2.pack()
" G! {- W; ^2 I5 j #选择图片的按钮& ^; E1 t' n- s3 s" ^% t
buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)$ \# D/ {4 K3 k5 z7 ?9 y; h
buttonSelImage.pack()/ N7 n$ R% \3 A
app.mainloop()9 s& G b0 l7 h8 T# e4 m6 }: K
& [% g# K3 t2 A& g) J) ^
3.说明: c" W; K5 C+ ^% t. b( z
首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。
, m; y& I) i/ k" r3 r1 `& ]2 s+ y% a
* i. w4 |( a+ K7 {+ u
1 N% B) }# B, r1 B$ ]) n- ^, y 其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片1 a& ?5 U5 @7 N9 V; y) I
: {8 y& _9 R9 S" S, `. R' w" F- |6 H6 g! _
9 G; l6 e/ B' M; w 但是效果会存在色彩的失真,效果如下:. m7 Z! l# o! ^
% w* X! E: _$ e6 L4 N8 q, B! Y% O
0 M$ _( o0 i6 s6 G/ [2 a% @9 Q# a) U
也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。3 r; u4 J. ]' R% G! i6 H5 P9 W
; j A' q: `- A( K% n这里简单提下PIL的九种不同图片模式:+ G8 m- p# Q# t% W1 x4 x
# b7 Z4 N/ f4 h" U" W
modes 描述' h. F, J; }0 |- Q& x" J; t7 i
1 1位像素,黑和白,存成8位的像素7 v+ O. l- B# |8 R3 s1 t) V
L 8位像素,黑白4 R5 W1 I9 ~ r8 P; y
P 8位像素,使用调色板映射到任何其他模式8 H' }; e0 r. M* e5 h8 X1 w
RGB 3× 8位像素,真彩; c, X" z. y7 m7 v$ y" b
RGBA 4×8位像素,真彩+透明通道
# C! c+ r3 B7 } T FCMYK 4×8位像素,颜色隔离/ `" @# U7 R% ^" m7 [0 [/ I4 \
YCbCr 3×8位像素,彩色视频格式6 {- `# y" ^! ?" \; }2 V9 p, @( B
I 32位整型像素( _/ Q' L; l: e( A6 |& A' y
F 32位浮点型像素
; e0 s) z% q: k' }4 q# L4.实现效果
, x# X1 E8 h. [4 ~, c: p
7 Y6 B4 I8 e; g, Q7 n7 [4 a
1 A- [$ G# l' b0 e1 k. F( [+ W
/ l6 |% D- D& I 可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。
) [) V- {. i& e8 a, S————————————————* ~7 A) a$ G- x% l. T
版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。! {8 E0 t1 z1 X7 \. D! Q& f/ g
原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288
9 j+ w) h n/ `5 F, }. u& ]9 |, @" c+ P1 K/ U
$ g& N+ g- U% m/ ?* i, n
|
zan
|