- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 561778 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 173906
- 相册
- 1
- 日志
- 0
- 记录
- 0
- 帖子
- 5313
- 主题
- 5273
- 精华
- 18
- 分享
- 0
- 好友
- 163
TA的每日心情 | 开心 2021-8-11 17:59 |
|---|
签到天数: 17 天 [LV.4]偶尔看看III 网络挑战赛参赛者 网络挑战赛参赛者 - 自我介绍
- 本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。
 群组: 2018美赛大象算法课程 群组: 2018美赛护航培训课程 群组: 2019年 数学中国站长建 群组: 2019年数据分析师课程 群组: 2018年大象老师国赛优 |
Python 基于OpenCV+face_recognition实现人脸捕捉与人脸识别(照片对比)$ \# T% t9 x4 O" H$ h
1 R4 n6 C. B$ m `1.安装包依赖1 f. m+ _& Y) Q+ U
与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。
4 N5 U" f! l& Y7 B# D$ n% Q
# U+ e: G( @- b$ d( H在python 3以上版本tkinter是环境自带的,所以这里不需要安装
5 J$ O, [4 h4 G$ e: v
% k1 I9 Z( u9 e% F1 d; s+ O2 Q, r2.代码示例5 f" V1 ?# O5 R9 |- n) w9 V
import os4 M* u1 V0 K# ~1 r/ l( ^# V! U
import cv2" m8 M2 W+ A% \5 q0 l: c) x4 x
import numpy as np
7 H1 p& e$ M( {% p. Q& ximport face_recognition' `! F- L/ w& O" Z1 {. e$ |
import tkinter as tk * q$ t+ ]3 z/ d' N- Q% g- w
import tkinter.filedialog( ]: S2 I" V* h. f1 ^ U3 O
from PIL import Image,ImageTk
$ c1 W1 C k0 j" j- e: D* b& m
classNames=[]
: |+ `) E0 @! r1 F; ?4 Pimg_path='Picture'- P3 J& s/ l; g9 }5 c: z6 P" P5 r
img_recognition_path='Recognition'
! h6 U( q- e4 n1 K( G$ d* DexistsEncodeingList=[]
$ {" d3 M# O, p, S) Q% y#对人脸集合进行编码进行处理
% x. R) T, t- \. Xdef findEncodeings(images):6 D% C3 \) @) m% j% }; w7 K
for img in images:
& n( F" T& i9 W, S$ X #灰度处理; A8 y! E8 a' L- ~1 V. A
img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)3 A8 T! }6 u1 e* P! I6 k) j: \1 P
#face_encodings对图片对象a_images进行编码并返回数组0位置编码结果' ~/ ^' y% R7 Q N/ ?
encode=face_recognition.face_encodings(img)[0]
1 Y$ G2 Z! `& ~1 V$ e- } existsEncodeingList.append(encode)! S' K; ]. j2 h3 ^& x' o
) a0 Q9 i% H8 e3 N* S! ?
#获取当前存储的人脸编码集合
- @+ D6 k& f9 D. {" `$ mdef findExistsEncodeingList(img_path):1 U* y, b u) Y$ x% \1 Q0 Y
images=[]
. u p! g' J: q3 e. a# K #列出已经上传的所有图片
/ s; E- x4 s4 Y: c Q C/ ~3 X4 W/ t imgList=os.listdir(img_path)3 N! |1 v, ]% Y/ a
#处理存储的图片得到其人脸编码
, c! m+ f% h7 m; E( e& {: e- b for pic in imgList:
% F6 B/ u! m7 d1 [ img=cv2.imread('{}/{}'.format(img_path,pic)): R7 `% S' r5 a6 O- J1 K) o
images.append(img)
; o# c" f$ t7 }8 w# [+ D# h classNames.append(os.path.splitext(pic)[0])
% j! `0 b0 N5 V, P' V4 G: I2 \ findEncodeings(images)4 X4 P+ I% V* p0 q1 _
$ g& k8 M( T. e
#选择并对比图片
9 ^8 |2 Q3 H8 _+ O: S+ g) |" @$ Ldef choosepic():
2 G* H6 N- @6 Z' b9 H% [* x" I b choosepath = tkinter.filedialog.askopenfilename()1 c9 D$ k8 L7 p3 \; Z
path.set(choosepath)0 ~9 h8 M- |! r/ {" R; C0 r$ W( X
img_open = Image.open(entry.get()).resize((530,750))
. f7 C0 k v& r) H, j img = ImageTk.PhotoImage(img_open)5 Q7 u- x. l. y3 A' R" y
lableShowImage.config(image=img)
- d& Y" R( e: q- o5 X, @5 W- G5 b lableShowImage.image = img/ w* q' a. w9 f( G* Z' D7 I! C
lableShowImage.place(x=30, y=70, width=530, height=750)
7 S; B' g" H6 v! \2 w faceRecognition(choosepath); m# u; {1 y4 c& _# R$ Z
- n( o4 Y) U7 P9 A/ y p
def faceRecognition(choosepath):) N4 G4 h' g) [+ c' H$ I- g7 E
frame=cv2.imread(choosepath)
/ g4 m8 c1 A- K# v# j1 l1 J frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
, G: p% f- p; _7 U# K* s& P" C7 e #对摄像头读取的检测人脸$ d$ W4 o# V% @' y N( Q
facesLocate=face_recognition.face_locations(frameRGB): u$ c( I+ U. ^+ X0 f$ k
#进行特征编码
' z, e- e3 s1 P# H2 |+ U# f faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)# k/ n) e" ~( z% B
#遍历检测的人脸和库中读取的图片进行对比,计算其相似度3 O8 d1 N- `+ R% Y7 y
name='unknow'
) s+ [9 d1 J n" g( W8 v for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):$ N+ c4 w4 S( y3 s" `3 G& h' V( C, t
#进行匹配$ O8 t0 ?' r& I7 X, Z0 Q" Y7 h
matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)
& i8 i, e/ w: K; F #计算相似度8 ^3 o( H/ Y7 Q5 z- I6 }
distance=face_recognition.face_distance(existsEncodeingList,face_encoding)
i$ o3 v& v; B9 p lab='unknow'
2 a5 Q% N2 m' W+ W( | S' y for index, item in enumerate(distance):/ u' Y' e0 p& D3 Y- C$ U* t) B
if item<0.5:1 N" q$ ?( l- \2 m5 g5 ^
if matchs[index]:
, ?: I8 R( ]: x2 q) l% n #得到匹配到的图片名称与相似度值
3 Z( Z4 M. p( ]( I7 ]. V, q5 R1 s lab='name:{}; Similarity:{}'.format(classNames[index],item)
* e. F# Z* d1 C2 y8 x" _2 {) y name=classNames[index]0 C- g+ W8 M# S# ^' |
break
0 O! ] a' v7 K1 N/ I+ ? #初始化面部捕捉框显示绿色
" o# h+ s2 N. ` {* g% C/ ~ color1 =(0,255,0)
* `, B6 E2 X+ Q$ x* j8 }- Q5 M! { if name =='unknow':; |+ `1 ~0 ]/ U K' W
#未能识别的时候显示蓝色
/ d) o0 e7 J0 r. p- z color1 =(255,0,0)
+ g& W& [: J2 W6 ]% p #画面部捕捉框
8 p. y' I/ K" N- ~3 ? cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)5 p% ~2 X) x/ _2 n6 h9 ~
#在捕捉框上添加匹配到的图片信息1 M' e) J" j# i0 G. _
cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)
% A% q- C5 D- z* t) m cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)
2 ~1 B( j+ i, X. S1 U img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))
4 e9 p" B/ @2 e5 `" M1 a img = ImageTk.PhotoImage(img_Recognition)) v4 ~& Q! g4 o+ Z8 x% `: ~
lableShowImage2.config(image=img)
$ |* H# X/ h0 H2 G0 Q lableShowImage2.image = img
/ K& \( r5 v1 x' x$ P! M! u lableShowImage2.place(x=630, y=70, width=530, height=750)
9 z0 O' s0 t- I; N2 F, v" w6 M3 a
+ i2 o2 H4 u5 y2 k; {if __name__ == '__main__':9 M9 a7 n0 m3 K- H- Q3 m
findExistsEncodeingList(img_path)
( s Y7 G6 k" \ #生成tk界面 app即主窗口
3 v6 p. z! L1 r4 n3 M' G2 a- o app = tk.Tk() $ b: C& W1 o/ ]" L O
#修改窗口titile* @# d, j( z) _4 ]9 o, ~+ R4 w0 I- |
app.title("show pictue")
1 e$ Z4 a( Q- w7 x5 n, c0 D #设置主窗口的大小和位置0 p" j0 {1 ^% i
app.geometry("1200x900+200+50")! k) T7 r. b# P2 ]
#Entry widget which allows displaying simple text.
4 X8 q1 G: L N, _ path = tk.StringVar(). s4 u5 t- `" T9 a/ N% o
entry = tk.Entry(app, state='readonly', text=path,width = 100)7 [, R- r4 C' n: l
entry.pack()8 x. _. }# \7 a: ]3 F
#使用Label显示图片+ g, x7 z0 b2 N! W4 n, G
lableShowImage = tk.Label(app)% O& Y5 _" O" i$ l! N
lableShowImage.pack()0 ~3 O6 I& K2 Y7 k) C
#使用Label2显示处理后的图片; s- G3 z; q1 e$ }4 a) Q
lableShowImage2 = tk.Label(app)
' V# E& Q2 S6 t7 {# i/ E) Z lableShowImage2.pack()
0 K" z" X4 {. v" f/ C- m- A #选择图片的按钮
, H- v, U/ ]- p buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)
5 `& Z# @4 \3 W/ q buttonSelImage.pack()
; }! t/ b+ B; V! `' \. D app.mainloop()9 w! e: {8 a* ]; t3 u$ ~' m
5 W+ R! J) w0 j! ^3.说明* ^2 v+ r2 b7 S, S
首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。) \0 w. t- i( G1 i7 O2 {' [1 n6 @
F) s9 s" d; a/ B
8 \$ F2 {# z! j! N- U1 `; Z9 y9 l7 P& Y) S4 }( R- S
其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片; @8 t+ k) w$ s
% C9 L' k: \6 _9 x
. E1 X4 v# o. W" K; B& G+ p+ j4 V9 e. s3 S( O7 t
但是效果会存在色彩的失真,效果如下:3 y: K/ L' F; \4 q G0 H6 n
& B* _* x: l! ^" C6 P. o
& n' N: E8 s% r! V( w6 \' D, X. `8 S) J6 _# C1 i a% b2 }" `
也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。: M1 G; \4 J a7 W% R. N( Y
f8 v7 I) G5 y7 E" ]6 L9 g6 T这里简单提下PIL的九种不同图片模式:' R) [4 r" e% x
/ ~, Q9 X8 F+ V& B) w% s8 w1 S {! f
modes 描述
8 l! f* k+ Y8 k/ }6 N+ c& }1 1位像素,黑和白,存成8位的像素
$ m) } z1 n( sL 8位像素,黑白* D" x% ]0 e; W6 K! ~' v
P 8位像素,使用调色板映射到任何其他模式
; k' }& t7 [& c- C' w* dRGB 3× 8位像素,真彩
% L( i5 T0 d9 W% ~3 R( iRGBA 4×8位像素,真彩+透明通道, j3 Q/ `+ \% E7 t, p8 d0 ^: r
CMYK 4×8位像素,颜色隔离
: ^2 L L/ s5 v5 o t1 L' k2 I' QYCbCr 3×8位像素,彩色视频格式
( Y' n- ?- Z0 I, d9 D5 i6 g! [' pI 32位整型像素% b& ]" v! t+ a2 I4 o, [% E3 p
F 32位浮点型像素
% D8 q% T5 X, w9 [# ^8 j( `4.实现效果
7 f- n( z( F' ~) F0 M1 U+ E
9 v: W4 S- \9 R7 g+ _# Y( U: a
( F, c, o" t& t m- L. k. S- A$ G! Z& Z1 Y: p$ ^7 h) j
. b7 D) R6 ^6 o/ k
可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。# f3 |7 Q8 @* t, z
————————————————
6 e2 a/ `5 x- v9 R版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。( S# h3 B( Q& h+ q1 q ~4 F
原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288
1 F- r$ f% y/ c' }" S7 O
1 L/ k6 ^- ^9 g' h2 S) F; g/ S l, ^) G& Q
|
zan
|