- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 569620 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 176109
- 相册
- 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实现人脸捕捉与人脸识别(照片对比)( P1 \/ S' b' c A1 R3 L' T/ G# t
% H, J: Y- S @& o) t9 M# v
1.安装包依赖, n: u( X! j6 @2 g
与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。
9 X3 u! v" D3 L* e$ m
7 Y/ Y% _0 G! j在python 3以上版本tkinter是环境自带的,所以这里不需要安装) T- u7 K9 t |8 ^
. q* T" [1 i) Y, I8 L& v. X& k
2.代码示例
& @. p8 b8 e, a% J! w. K+ ~5 fimport os
/ J0 c8 ^. r/ ~! j4 [& A- \3 rimport cv21 d- f0 g* Z- E3 f5 J
import numpy as np( L( Q/ X {# ~" i# B! @: _
import face_recognition
. R7 s3 g7 W% O* `2 y4 aimport tkinter as tk ' Y- ~2 W8 y9 b, P2 t- a
import tkinter.filedialog
4 d; I2 c6 |# N1 U0 z% `from PIL import Image,ImageTk 5 G" s9 D7 F/ i% j
5 q( o2 O3 W2 a' @; ?0 `9 H4 DclassNames=[]
1 \7 A! d( ~9 M- n" cimg_path='Picture'0 I$ S: k! J0 k1 x
img_recognition_path='Recognition'
, t6 c# ~0 k+ i% m) |existsEncodeingList=[]
% D7 c& G( I, R* m* h#对人脸集合进行编码进行处理5 I a# v( Y: j; [6 y7 V4 s
def findEncodeings(images):
. V- t+ B3 v h! I for img in images:
' N8 Z/ i& L+ q) U+ ~& S4 i #灰度处理
0 u2 x) [( n$ X# T- a img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)
* e7 P7 t8 d8 g9 _" w3 r #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果7 H" W/ j1 ^0 b9 @* _: q I2 `
encode=face_recognition.face_encodings(img)[0]- q6 w3 Q, J- J. o
existsEncodeingList.append(encode)% ^6 J, P3 D2 P! C5 z; t9 {# @0 a- X
1 k) Q* E1 h/ c! c' X. ]2 E( W#获取当前存储的人脸编码集合
% h9 f# V# F" Udef findExistsEncodeingList(img_path):1 T& {! T+ r( m1 Y5 n0 o2 S
images=[]: T3 i5 V) B/ A0 O; i) }% s& c1 O
#列出已经上传的所有图片
% ?3 a* @ Y8 }9 g2 I% r0 L imgList=os.listdir(img_path)- ^- }$ m2 Z" z1 {0 ^6 i# o0 \
#处理存储的图片得到其人脸编码2 j* f3 t& y7 N2 T2 o+ S& [2 O4 `
for pic in imgList:
& r' F$ ^) H3 u img=cv2.imread('{}/{}'.format(img_path,pic))
1 X J$ Z0 ?' b# P3 { images.append(img)
$ y$ |% k# A& m! l2 O+ n) o classNames.append(os.path.splitext(pic)[0])2 t# b/ y) o3 z3 L7 y, b( F
findEncodeings(images)' z) Z' V8 \3 u3 S) R4 k- l
' M _* F9 T& @- m8 a
#选择并对比图片( t2 J$ K+ F) |$ Y2 A
def choosepic():
' _2 I6 ~4 ^' B choosepath = tkinter.filedialog.askopenfilename()
- v7 c- k: N$ b- e$ N path.set(choosepath)' f* o0 s# R3 z0 h& J# G' k
img_open = Image.open(entry.get()).resize((530,750))) W" t- F2 k) _/ C6 ~, K# T
img = ImageTk.PhotoImage(img_open)! Y; H- T" `# I9 l# C
lableShowImage.config(image=img)
1 w7 L" f# P( C- F lableShowImage.image = img+ T5 u( Q2 ~4 ]: w0 m: b7 m `
lableShowImage.place(x=30, y=70, width=530, height=750)
2 ?) R/ M' Z& Z! R) s; R faceRecognition(choosepath)% \6 k0 d5 ^7 `- ?
: V# f6 J. J7 ]+ K7 y4 w4 `/ G+ I
def faceRecognition(choosepath):2 _; n' U6 ^$ m! u9 h) R& L
frame=cv2.imread(choosepath); L# P0 k, D3 |% X
frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
" `+ {1 }. p1 R/ q# _6 ? #对摄像头读取的检测人脸( F$ ?( O0 K5 i# L& v# F }
facesLocate=face_recognition.face_locations(frameRGB)3 w4 W( n6 B! J ?% ^7 r& i2 Q" r- x
#进行特征编码
8 b$ f; s6 d# X& o5 m3 |. p faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)) J0 `: a: [* V* _ a
#遍历检测的人脸和库中读取的图片进行对比,计算其相似度$ q D: F# V! U* `
name='unknow'
; V( m, n: f: z# Z B r for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):; X5 m4 J+ y9 \0 F: _, W2 T
#进行匹配
2 K9 S P% l" N5 L. ~$ X% u9 n matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)
# o* s- Y- ]3 q8 M4 ~' x( n) f! ] #计算相似度
7 _1 b. r: R4 _: [3 E8 x5 o) E distance=face_recognition.face_distance(existsEncodeingList,face_encoding)* t/ U( R! [+ q7 o5 Q& _
lab='unknow'
. i) U/ P3 L0 Y7 I4 o* P$ S for index, item in enumerate(distance):$ T# `2 ?; I9 s, O
if item<0.5:2 ^+ A; b/ f# f8 v
if matchs[index]:/ S/ G" r, G# T' |+ O0 ]
#得到匹配到的图片名称与相似度值2 y$ d1 G' D& Z
lab='name:{}; Similarity:{}'.format(classNames[index],item)" q [" \7 F4 V) h
name=classNames[index]
3 |2 v& V `% |7 c+ V, n break
2 ~5 ^5 ~# f+ `; K8 i. c. \7 x #初始化面部捕捉框显示绿色. g$ r& C; a( M- ?
color1 =(0,255,0)! I1 p: ], u# j3 n
if name =='unknow':) m; m. k& S( [) _4 f
#未能识别的时候显示蓝色
: K4 }# u) p# s/ ]* Z' z* l' I color1 =(255,0,0)% J, i8 k! @1 E+ R2 U6 N1 g5 J
#画面部捕捉框
9 B* o; P7 L% J$ _3 R cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)+ D6 D! a/ q* d
#在捕捉框上添加匹配到的图片信息1 [* J+ G8 g& Y
cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)+ X9 }+ ~' v% @4 g
cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)
( e! }7 o( \/ o; @$ V7 v0 V: R img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))
+ B% b" E; e7 q" R2 x4 \: D. r9 s img = ImageTk.PhotoImage(img_Recognition)
: S: v1 I& a/ C7 F' O lableShowImage2.config(image=img)
% o, G& k( x9 Q/ e1 a( r# I lableShowImage2.image = img2 P/ o D- B! o% v* @
lableShowImage2.place(x=630, y=70, width=530, height=750)
* T1 \: U0 _9 ^% A0 Z& w9 \ Y/ M: R3 R% r' `$ q
if __name__ == '__main__':
) a5 }( }1 K' `5 W findExistsEncodeingList(img_path)& y9 {% t2 R& i
#生成tk界面 app即主窗口
8 ?7 D1 C* ^# f7 L0 t9 q- t app = tk.Tk()
8 y3 W" J/ ?: f; e1 b6 R #修改窗口titile9 F( n& b6 J" \
app.title("show pictue")
F9 ]# Q6 M. r& ^4 m4 c #设置主窗口的大小和位置
c4 {& v. V& U$ D app.geometry("1200x900+200+50"); ?8 Z5 V# z& e8 c; l# O( K
#Entry widget which allows displaying simple text., i8 @8 C+ `0 S5 G ~6 w
path = tk.StringVar()
* ^. n7 K; j! e; u) ~" G entry = tk.Entry(app, state='readonly', text=path,width = 100)
2 }- z3 E- A5 f5 U! @/ I entry.pack()
d5 f+ ]4 Z$ L/ b8 u #使用Label显示图片
Y) h6 T4 j) f4 ?: V4 F lableShowImage = tk.Label(app)2 H0 W( `/ u9 h5 w/ D8 f
lableShowImage.pack()) u6 r# T* J% p
#使用Label2显示处理后的图片
9 z5 [$ V; W" E9 X$ i4 P5 W' J7 s lableShowImage2 = tk.Label(app)
& b7 K; w- m, Y( ~4 X lableShowImage2.pack()% J& F1 p% U) A" d: ?/ A) k
#选择图片的按钮
2 G4 X2 I, P4 @+ v9 R( c- Q buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)
* }& _! m# I4 K4 t buttonSelImage.pack()) b. A5 Q7 X' j/ w- D0 g
app.mainloop()- U2 U$ d: T. z: u9 W
0 ~' Q1 I& \) `* `. m3 M3.说明1 v+ ^# h, _2 {3 @, y; ^/ M% M
首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。
$ M; X( D- h9 U8 k; t3 |6 P3 M; J7 @0 V$ l9 h1 ~
# i8 b/ l% `5 n: ~0 V& H& p
: R. P' ^/ ~1 }( i7 t p4 b 其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片. r- s/ R$ c; Q! x* O- X
% [: r' {) L" @& W# ]3 J
6 k' D+ l: z/ y/ L+ u! P9 V
3 b. U4 B- [; o' |# O! E5 L9 i. j 但是效果会存在色彩的失真,效果如下:2 d- D1 z- S% L2 m
0 o; N d: u6 u4 \
6 g j+ S; }9 l* N1 T. i
! f' z8 ?' H9 u) V+ p也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。; ^# g5 [. x0 e c* L% i8 Y
' [5 B3 d6 m! _9 g' ^5 x/ e! A
这里简单提下PIL的九种不同图片模式:
) N j7 X7 S, z8 a4 t5 ~2 o4 ]9 j( v% [( N( B9 `
modes 描述
9 P/ Z9 G; r9 U: W# O1 1位像素,黑和白,存成8位的像素0 P, _( C! e7 k/ [% o6 W
L 8位像素,黑白
! Z Z8 I0 N4 c( RP 8位像素,使用调色板映射到任何其他模式
; }$ l/ C- Y K, sRGB 3× 8位像素,真彩& d; C; g- y' g6 o: @$ p
RGBA 4×8位像素,真彩+透明通道. {" j+ u7 @; ]0 n& z8 T' e
CMYK 4×8位像素,颜色隔离
, L% t$ D0 m) p" c$ F0 VYCbCr 3×8位像素,彩色视频格式5 A- c v! f8 ^" Q) h. `& z2 f9 B$ a
I 32位整型像素9 l. ~3 [0 Y# c+ v* w$ Z7 o! d
F 32位浮点型像素
5 J+ ?- O. M ?2 Z6 ^2 Q4.实现效果1 Q! {% G- \, g' W5 n; F
% w2 ]; m2 |3 ^4 Z
) }7 [# Y5 x. O& S9 k: U
h. M& X; a8 L0 o. [
" B* I6 t- K/ U2 l 可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。
& d6 K$ f0 }8 u4 f4 l; [1 N————————————————
' t L5 [% \# }版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
' B; n$ k! X9 ?8 D3 V- a原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288* n( A: B# u' Z7 s& X$ L S
: J! @7 z' }; {, S* B( X
8 S# x1 s( ~( `4 s* h1 f7 v
|
zan
|