- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 561788 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 173909
- 相册
- 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实现人脸捕捉与人脸识别(照片对比)
# }1 [& F4 ]" w# N# B/ c0 P. o. l! ]" ^* }9 e+ j
1.安装包依赖0 } \& n5 n: X& b
与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。: A ]% o6 T5 r) x ~0 m5 C% f
4 L. U# a' k5 D
在python 3以上版本tkinter是环境自带的,所以这里不需要安装' l6 \& D6 |6 N* Z+ B9 c
. h2 Y$ j8 V( b$ P) @
2.代码示例
8 f0 J Y- V# Wimport os
7 }/ k8 t* d; F8 Aimport cv2
0 e6 ~2 s8 e y; C8 |4 v4 f- z( nimport numpy as np
; W- ^1 j# R! G: e( [) w! P# S& Nimport face_recognition @1 d# @5 J8 J- ~1 Y
import tkinter as tk 9 R, J5 S. D% a( A6 d E8 a/ r6 @
import tkinter.filedialog
! ~! C5 C" h1 _8 hfrom PIL import Image,ImageTk & \# q6 U9 `8 s! t3 X0 T
% h W# B6 B; N! D4 w4 _/ m/ A( d& i
classNames=[]8 U) W$ [* P1 W0 b% T: I0 a9 @1 [
img_path='Picture'
: f( F- d1 x4 Y& F/ gimg_recognition_path='Recognition'
% q- V2 g" F( S# w- r1 texistsEncodeingList=[]
" H2 p( j( n" a4 X( P" O g- n8 r#对人脸集合进行编码进行处理+ \8 @/ L* O& O. I8 E2 ]) M/ ]
def findEncodeings(images):
* M1 F" z0 W8 F5 S# j& i8 q for img in images:# h; Y9 o0 n# h5 p$ d- C c
#灰度处理, C) ], C0 q0 G& K, M" r1 N
img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)
- C1 v8 ^1 B t! A- n# k) }$ h. T #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果' C* @% Z! n0 X* e7 S
encode=face_recognition.face_encodings(img)[0]
) U5 ^- L/ a1 `8 L' c existsEncodeingList.append(encode)
% z# J! p8 ]+ Q8 x4 n8 `4 Q4 ?7 ^( \! ^5 A
#获取当前存储的人脸编码集合
7 `( h* b' ?( i9 I( h% o+ |def findExistsEncodeingList(img_path):
5 G9 C* S& ^6 W2 L8 [/ v2 b3 {& f images=[]" |6 n4 [& _9 K8 T1 x0 F7 T
#列出已经上传的所有图片& r' V5 i E+ K7 f& F5 D1 a
imgList=os.listdir(img_path)
4 W6 a( y( g* T" I+ H) P. W1 [( s #处理存储的图片得到其人脸编码
7 p$ ] C% @. K1 E/ t+ d! U for pic in imgList: h5 F9 \0 O+ A5 Y
img=cv2.imread('{}/{}'.format(img_path,pic))
) g% V6 D. f' A0 y7 s; r4 Y9 F# W0 M images.append(img)
5 d) z( D8 J" L6 |) @ \ classNames.append(os.path.splitext(pic)[0])' i8 u- |$ T' u) K J+ f
findEncodeings(images)
( `) z; Q3 ]. _7 |2 \6 A5 C
9 j/ p% Q8 Z' g5 o6 l! @0 C#选择并对比图片8 [; q- B9 j+ q9 w
def choosepic():
1 u7 s$ Q; ^0 J; U6 x, U choosepath = tkinter.filedialog.askopenfilename()
5 k, D& w4 i6 S; l9 L, T path.set(choosepath)3 J, k9 x" d+ u j0 F. u
img_open = Image.open(entry.get()).resize((530,750))
3 ]: a/ t& v( @) Q6 S: C4 ] img = ImageTk.PhotoImage(img_open)
" q1 Y) G1 A V: D( m lableShowImage.config(image=img)) X3 O& x+ Q Q# D
lableShowImage.image = img
# g- A5 a" ? I8 A. j9 l lableShowImage.place(x=30, y=70, width=530, height=750)2 w0 p# l5 @: w* c" H; v! Z( z
faceRecognition(choosepath)0 t9 |- u6 t2 W6 b- e: v7 s- |; t
) T9 J: J! H9 q2 H: k5 ~, udef faceRecognition(choosepath): ]; p( y/ E, s. S, t8 w: R
frame=cv2.imread(choosepath)' v, m9 U9 ^/ b7 ? c5 t2 A. z/ @, l
frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB) T: o( E! I8 n* u4 e5 g3 F
#对摄像头读取的检测人脸
9 a2 t1 L$ w1 g5 g( f b9 E facesLocate=face_recognition.face_locations(frameRGB)3 Z. _$ u% ]) C" Z$ x( r+ Z
#进行特征编码
3 ^% C! s0 Q2 j; v4 H faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate) J5 h5 R Z" m3 \& p
#遍历检测的人脸和库中读取的图片进行对比,计算其相似度
3 y" |6 a+ ^( ]5 [ name='unknow'
b* g% i# g) S2 t. P for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):+ y- f- A) y2 x) a! o6 H
#进行匹配6 v/ ]8 |+ @# f- H- X4 o
matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)2 Y1 o, V3 c) V8 _" {
#计算相似度( t8 A" k8 i- f* h) N, {& x
distance=face_recognition.face_distance(existsEncodeingList,face_encoding)' z: S& C& H, L) ~
lab='unknow'% G) s. ^- x9 Z9 G
for index, item in enumerate(distance):# W4 n) T5 u6 I9 J9 @
if item<0.5:
1 c& E2 J, a' Y6 \+ w. W+ s if matchs[index]:7 m( G0 k" s. W" `2 R ]3 l; p
#得到匹配到的图片名称与相似度值7 r! k$ D" m( y; U% ~% @3 B/ j
lab='name:{}; Similarity:{}'.format(classNames[index],item); A1 y% F( m$ C
name=classNames[index]' z2 h5 F- [) [. V. I# K
break& z8 t+ m+ K. r1 q% f
#初始化面部捕捉框显示绿色+ N r' d' {# a9 K y
color1 =(0,255,0)
( k4 I0 A# r8 F1 }' ^ if name =='unknow':4 C$ `1 f3 k9 T8 f
#未能识别的时候显示蓝色
8 Y" z! A6 g! s7 X; D color1 =(255,0,0)
% V0 a7 ]8 D6 `1 [+ p9 Z #画面部捕捉框
R* d! L) b/ w cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)
8 H1 y2 T6 r$ a, m #在捕捉框上添加匹配到的图片信息1 V! T" g W8 n7 y" N5 E; ?
cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)
6 G2 \5 V! `2 ^0 _' ~3 ~3 g5 r9 l cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)9 @# m: h1 x5 x$ v" _4 @$ K' |+ l$ I
img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))+ t+ g0 H3 U1 D, U# f& S) L
img = ImageTk.PhotoImage(img_Recognition)+ ]6 n. X: {+ e w6 s8 z
lableShowImage2.config(image=img)
3 o0 }; j9 v( o lableShowImage2.image = img
5 h) O- `4 q( ~7 r1 ~. u lableShowImage2.place(x=630, y=70, width=530, height=750). |3 h+ F& f5 G/ h$ T* W; D
# y* E! @5 |3 J9 zif __name__ == '__main__':
" ~; X) e9 ]0 G- F0 Y0 [# S. P( z findExistsEncodeingList(img_path)
" `8 E/ ^; Z( @, E #生成tk界面 app即主窗口
+ g. L3 h1 i8 G app = tk.Tk() ! u3 V3 X7 ] u8 |# I' g1 D
#修改窗口titile2 ]& r0 r3 [! D# y! v8 N3 c! q$ ^% ^
app.title("show pictue")
: w) z# H( p0 H9 J9 K #设置主窗口的大小和位置
$ h$ K7 Z$ ^& Q, N! X: E0 o# p app.geometry("1200x900+200+50")
$ ?) V) l( R# Y: I #Entry widget which allows displaying simple text.
& ~. \& `5 U! T0 O. \ path = tk.StringVar(), R! R: Z4 X1 ]( f( r8 p9 K6 \
entry = tk.Entry(app, state='readonly', text=path,width = 100)
' B$ P4 c, t# e) J+ Q/ E entry.pack()
" N+ Z" q) s& j& W( N: [4 I# W #使用Label显示图片# }% Y- \1 c- C6 Y8 A$ X
lableShowImage = tk.Label(app)
! m- ~1 X) G" N& ]* x. D lableShowImage.pack()
! N, x. @0 J2 W' i #使用Label2显示处理后的图片
4 n* J2 k) V# K- N2 u3 | lableShowImage2 = tk.Label(app)0 \7 \* @( ?6 i! c+ }; H3 C$ F
lableShowImage2.pack()
6 c$ f! I9 F/ Z #选择图片的按钮! M6 g" w: u9 D" s. d" d
buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)
7 Z9 r y9 T7 F! [" F2 S buttonSelImage.pack()
- C8 E) L5 N# a/ N; A app.mainloop()+ \3 ?2 ?4 s' |% r* N
2 w% F2 P% h, _3 Y4 U) r. G5 a- @3.说明
* F" L% l9 p- P7 [5 X首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。7 z5 V0 i' h( @
* T; L# W" t) Z
S0 o9 K5 G( y" H: |0 D
. K7 a0 o' \# H2 H5 ]1 A 其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片
* [7 _( B9 u* w- b/ t! B- [- l- ]" |9 a; l8 o/ E* l9 U
T; y1 V6 e# ]+ ~) r+ c- f: @
& _5 ^# q! |4 x# W. L
但是效果会存在色彩的失真,效果如下:3 b, t/ w+ B! X# `8 D# Z% d$ W
6 P! C5 P& o- s" Y3 x( R2 Z, g# Z P
" P: ^ ^" ]) v- Z6 y/ N; c) ~1 R& x3 k% o4 K2 a5 f
也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。
# v5 a# _# I! z. a0 l! F3 G0 W" I( ?8 c) ]- J$ i2 E0 e
这里简单提下PIL的九种不同图片模式:, Y8 _$ v: p- C% W7 d4 B
* G; o: R3 Q6 r" N" E+ |9 w
modes 描述" E3 o# Y+ |/ F) O# G
1 1位像素,黑和白,存成8位的像素" ?, y2 B6 U' y4 x6 r1 l4 i
L 8位像素,黑白, \$ c7 w8 e: j* B( c4 I; v
P 8位像素,使用调色板映射到任何其他模式( O" a, z& U X+ Y2 m5 ~, e
RGB 3× 8位像素,真彩6 J. p- J" X7 [1 F! d% L0 a
RGBA 4×8位像素,真彩+透明通道
; H8 i* L$ q+ E, [CMYK 4×8位像素,颜色隔离
) S d& ^, ^8 T! R) A# MYCbCr 3×8位像素,彩色视频格式
8 B% e2 ^: A9 a5 `- @3 ZI 32位整型像素
/ _5 f0 A$ v7 z4 L' [F 32位浮点型像素3 J8 l# V4 g) R4 S5 m& m% P
4.实现效果2 W5 i- H5 d* m. Q5 x; P& l. k
9 L6 ?+ u# j- d# j2 q9 O3 }( c
( }7 ]7 J, b4 q8 l+ Y& U+ n
+ I: T+ G: s( V# p. n b
1 w6 h8 x3 Z* S8 H9 c1 u 可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。+ L8 F1 Q {% u% n! `, L
————————————————6 j$ l2 O/ P! y' m
版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。" c6 u q+ H- o# F. ?, I7 ^" {
原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288
2 |& O7 U" ]- u/ ]8 D: h7 A- X' v/ c# s) k" a. H. j& ~4 J
0 c) M, R6 n6 L+ @' ~
|
zan
|