- 在线时间
- 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实现人脸捕捉与人脸识别(照片对比)4 K3 ]# }2 H4 E9 e9 w$ T
8 a& x2 Q* V+ p
1.安装包依赖
1 a' P/ z0 F% Q0 j# Q' J5 U& e与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。
2 {+ \: N# N9 @5 e# `0 L; f" G. z. R2 ^* F9 _0 {" ?6 e" @5 \
在python 3以上版本tkinter是环境自带的,所以这里不需要安装9 _, m; j% r. N$ c
$ |5 r8 a1 b' B8 q; O0 H2.代码示例
0 ]/ Q. C9 j0 Q: x$ b0 F2 mimport os0 A/ i) v0 C6 m) B
import cv2
* d3 e- r+ L" C: R* }; u$ Timport numpy as np- c! I* J! p' A( c8 x$ t0 I
import face_recognition* `6 s6 Q9 R8 m" K2 c
import tkinter as tk / W; ^! U' d8 I
import tkinter.filedialog
$ d/ u9 R/ N. z+ O9 ?9 O' Bfrom PIL import Image,ImageTk + N' g* `# h4 [# x! w ?3 ?
1 `5 ]. H5 ^, T( ^# XclassNames=[]
, I9 E+ y! s, t/ w3 L2 j) |' C3 nimg_path='Picture'' g3 D" Z. }- G% s0 \, W
img_recognition_path='Recognition'
% o, g0 n' o; PexistsEncodeingList=[]
4 C- B" P. W" Z$ N5 z4 b- i- ?% X#对人脸集合进行编码进行处理! g# R b0 @( e# S5 e1 i/ H
def findEncodeings(images):
4 t' K4 l. E( y2 h0 H' n for img in images:
4 L) s. h/ P8 a/ f x$ f1 P% h) w #灰度处理$ o5 S3 M" k' l
img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)
* e D- e `/ o' h7 k- |" D #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果3 P. P, `& H ~, t2 b
encode=face_recognition.face_encodings(img)[0]8 n5 j" P# n b& p2 e2 y& R
existsEncodeingList.append(encode)
& q v6 I3 A7 M8 J: W& g8 ^& r+ j4 e
% v1 D- b3 i. k9 v#获取当前存储的人脸编码集合
0 C2 C; |3 V! J5 ~" p' f* ~def findExistsEncodeingList(img_path):
1 K8 V% P h& C. `. |3 i1 J* B images=[]/ G! ~! M: x# Q
#列出已经上传的所有图片& R. ~( Y0 f" H/ B- ]' v
imgList=os.listdir(img_path)
0 Z: l+ s( L' i; _1 ` #处理存储的图片得到其人脸编码) B; f6 O; u1 c7 c; d- ~
for pic in imgList:
. f' @/ {; {# N+ {; Y9 u( d, T img=cv2.imread('{}/{}'.format(img_path,pic))! x* w; y3 a2 o( N/ C
images.append(img)+ D0 s# P. `' }0 X3 k9 U% ~
classNames.append(os.path.splitext(pic)[0])
8 E! C \4 i2 D5 F6 x findEncodeings(images)) s+ @! j+ Y" `# l. ^3 x; X8 p
6 j |5 |+ Y9 x
#选择并对比图片
4 H. Z3 S8 S5 i% ^6 wdef choosepic():- w V, W* Q' Z( h( T7 \
choosepath = tkinter.filedialog.askopenfilename()8 E: N2 u, E/ F3 h9 y
path.set(choosepath)
" U$ m* w' S0 f+ S v( J& e img_open = Image.open(entry.get()).resize((530,750))
4 k! n' E. f/ m" `4 ~0 M img = ImageTk.PhotoImage(img_open)
( r+ q0 q+ [, l+ ?7 X% S3 H lableShowImage.config(image=img)
$ C, d) S; D' X$ V. d lableShowImage.image = img
; V* c& `4 ~7 K* G1 G! w) U! b lableShowImage.place(x=30, y=70, width=530, height=750)! _( p2 h$ j( F3 Q: B! m- \1 a
faceRecognition(choosepath)
, g8 L; m4 u7 ]! s9 u- Z! l a4 V" N0 k* d
def faceRecognition(choosepath):
4 h2 Y/ G2 V3 H2 N7 F7 t frame=cv2.imread(choosepath)
- w4 Y7 d% D) I% ` frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
+ U7 Q1 C1 w8 v$ f3 d #对摄像头读取的检测人脸
0 x. T3 J7 g5 ~% ~+ ] A, `% _: W) } facesLocate=face_recognition.face_locations(frameRGB)
/ V Y0 u; [) ]* d) q+ R% k #进行特征编码6 J3 \0 Y- w+ Q4 C3 M
faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)1 \4 _% r/ f8 b, Z0 n4 c
#遍历检测的人脸和库中读取的图片进行对比,计算其相似度9 y! N$ j% t; U2 T$ I" o
name='unknow') }1 P5 M- j' A
for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):
) H4 z* ?9 j, `, L2 |3 F8 I2 ]" r% H #进行匹配
# Q: R. D" z3 s8 l% I matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)
' G% q2 [/ ~7 H, B9 Q8 z% \2 Y/ I #计算相似度
8 Z0 A& V% T5 [+ K2 R distance=face_recognition.face_distance(existsEncodeingList,face_encoding)# _4 T+ J! d K E8 Y6 Q$ L
lab='unknow'$ b- y5 m2 A" {" B- ]3 B
for index, item in enumerate(distance):
5 [0 |/ e0 w) p9 |7 W if item<0.5:% ?* V( b7 S0 S6 U- Q
if matchs[index]:
) h- k' k5 J' L/ V. j& P #得到匹配到的图片名称与相似度值6 \- c4 o$ w- x4 i2 K
lab='name:{}; Similarity:{}'.format(classNames[index],item)
$ E! K( _ \/ v- y name=classNames[index]
9 n) Y3 r+ R# G! s3 M% y break
2 x. F, a9 v" w, d& y( E/ q$ { #初始化面部捕捉框显示绿色: u7 i! ?7 a$ G
color1 =(0,255,0)
P5 n, k5 k- t, k, S if name =='unknow':
* r( U9 U6 F5 m$ ~- F' A+ Z% L5 l #未能识别的时候显示蓝色
: p/ O3 j+ _4 u7 H3 `$ ? color1 =(255,0,0)
+ ]6 x% T% F9 Z: S #画面部捕捉框
7 [! ?6 a- ]0 U cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)
: \8 ~+ w: h8 } J7 y #在捕捉框上添加匹配到的图片信息; @4 j! t9 z1 l2 d7 E
cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)9 F6 _3 H& H9 k6 L P3 B/ D
cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)- Q$ G0 `) r2 _# B! C
img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))
A2 a, l4 \: C" p) O, W' q img = ImageTk.PhotoImage(img_Recognition)+ v% D( W2 { M3 B- J$ W
lableShowImage2.config(image=img)$ _7 Y9 Q3 i. c
lableShowImage2.image = img
4 u* D( a) J) a, W3 { lableShowImage2.place(x=630, y=70, width=530, height=750)+ f- l* I) W. {! |/ Y* H# [ V7 [
6 ?' f \/ B2 Y% A5 pif __name__ == '__main__':
2 M- N2 l% d5 w& ~" \0 N, I findExistsEncodeingList(img_path)8 s+ h. d0 V* C% X* n$ W4 G: k! @
#生成tk界面 app即主窗口
, u: c) ]5 k: X0 E2 o9 y) ] app = tk.Tk() * b7 j5 _5 ] i# ?2 ~- Z
#修改窗口titile
4 U0 H) A% K# y( j, `2 s7 V app.title("show pictue") % ~+ X; u: m0 S& l+ W& o; E
#设置主窗口的大小和位置8 r" d% _1 t" ^
app.geometry("1200x900+200+50") D M* B2 W! z- x
#Entry widget which allows displaying simple text.6 o$ W1 w8 B8 T$ ]0 m2 `4 ^* @
path = tk.StringVar()/ k$ \6 d2 j9 ?/ y9 h# x+ j" ]
entry = tk.Entry(app, state='readonly', text=path,width = 100)
% f% W: M, L' ~8 N( I$ N entry.pack()3 z5 P' F( ?2 |
#使用Label显示图片) G6 b2 j" I* S7 M- {: R1 G
lableShowImage = tk.Label(app)& \: {. D; G/ m" _; i" w+ z* H' z% z
lableShowImage.pack() V, d0 X( C' T& Q( e
#使用Label2显示处理后的图片% Z! U' d; v; v1 a2 F8 M
lableShowImage2 = tk.Label(app): A* \% M3 z3 `2 N
lableShowImage2.pack()$ g# E; `) ~2 Z2 u+ X
#选择图片的按钮 U2 m$ ?8 ? G. b" c% |1 p
buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)
- O& s3 e) h$ E" t buttonSelImage.pack()) ]3 @; g' L" H
app.mainloop()5 S: Q: w* y% u, o5 i( a$ H
9 U. O7 `/ ^. u; M+ Q8 G" f$ N
3.说明/ A" ]% l/ I& u) U8 A
首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。4 N$ h! }3 k$ k3 T
1 B5 x2 E) S+ Z! ~
- y0 m3 D& `- H/ B& `! O
6 i+ F w( N: Z0 b( }6 F1 i( h 其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片
$ B( N) U" c# I# m. C7 F9 d0 K5 J* H% l3 ?0 y2 `8 q; ~! C; S1 t6 k
( e% K. H! M% v1 S+ [" V4 q8 U" S: R4 N0 W6 P
但是效果会存在色彩的失真,效果如下:
: n$ _6 ~7 D2 ]# t# Y" v# g. M3 C" I
. C2 F# `9 l0 Q, O
% j; w1 U0 `4 F8 n1 ?: S+ i
6 ?2 ^$ l/ G3 c3 J" x也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。! S1 h3 Q, Q$ I# g+ D9 C* a: u
4 y5 f/ {; p1 b8 ^: ~7 Q6 y0 h
这里简单提下PIL的九种不同图片模式:. I4 n+ ]6 V/ o; d4 l1 \8 v; ~
: c) l0 t& C: r% p* @; \modes 描述% |; E/ }! G3 N8 @
1 1位像素,黑和白,存成8位的像素( R7 w* h5 i6 q; D! {
L 8位像素,黑白, N7 ]0 u6 a2 W* u4 F
P 8位像素,使用调色板映射到任何其他模式
, ]; i+ f$ U. r. a4 ]RGB 3× 8位像素,真彩
8 r' i' e/ n4 X% a2 [RGBA 4×8位像素,真彩+透明通道 N* j( _" n# _( E& u; v7 `
CMYK 4×8位像素,颜色隔离' q* P k$ E8 O& ?0 Q, F; H
YCbCr 3×8位像素,彩色视频格式
5 H/ W* q2 `4 T! f( U3 HI 32位整型像素
) G' s9 S* s5 B1 fF 32位浮点型像素5 S" M9 z9 n6 G3 U& T
4.实现效果" C; N3 ~+ ^# y" l+ k0 l
! ]! F5 }; j# ]2 o, x* p/ W. K# \
/ v' d# X6 N7 Q K* e+ m8 d
8 @9 [" q: a t- ?/ g% A
4 l% ?2 E* z+ e3 Y 可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。! ?5 m0 k1 N% E
————————————————$ D8 y S/ o* Z8 |
版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
1 p3 o. }. c2 F8 z( c% }( A6 ~. f原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288
$ ]7 u+ ?9 n. t) s2 M9 T* Q( q/ `( y3 D) W% @! x0 E2 g% Q* L# O
W k) @- V. z- p1 z: {- _
|
zan
|