- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 561369 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 173784
- 相册
- 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实现人脸捕捉与人脸识别(照片对比)
# L/ `# i6 S& a: ~" ]- V
7 G2 P* G! t* D: i1.安装包依赖
! H+ k0 H) ~" I( K$ o& z0 W与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。5 `4 v- V! o t; q( L( i
8 U. ]% S2 n" Z
在python 3以上版本tkinter是环境自带的,所以这里不需要安装
1 Y7 v) e) R* g3 v* Z3 W
( F: a% Z- ~5 T2.代码示例
2 E+ m9 B0 ?% X: O( L: w% Iimport os- [1 v. x3 D: n
import cv2' ~& L; [3 w3 \
import numpy as np
" ]" r& w- z- c3 |# o, ~0 Timport face_recognition/ D6 ?1 x, x* H3 | o, w( z
import tkinter as tk
. O" c" C& T! o4 bimport tkinter.filedialog8 P% b* A! k( m
from PIL import Image,ImageTk
3 }& j, ]2 C6 \$ [5 ~6 S1 w8 _9 I4 p8 r1 u$ e6 q: T
classNames=[]
% q/ w1 r. |/ @% @( u& |img_path='Picture'6 F! M2 p0 f, ]
img_recognition_path='Recognition'
0 P0 K% z- N) [7 q1 v7 UexistsEncodeingList=[]0 i: r3 j6 s# d6 F% U! ?6 E
#对人脸集合进行编码进行处理
2 X2 k0 A& b* j2 t, H/ B, |2 m0 pdef findEncodeings(images):5 r# f% F( j, |9 B
for img in images:
1 u6 n" `0 s* B) C* z2 S- X. l #灰度处理
0 o, N9 J1 K, b+ s: D, M( D* ~ img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)
6 Z D4 u/ u, Y& Q #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果
5 q6 N' A& `+ \, S6 y, P" c2 s encode=face_recognition.face_encodings(img)[0]
( ]) U5 [4 ~' J2 x; C* H. X existsEncodeingList.append(encode)
3 T4 Q- r& o2 K( X% W: O4 _4 X/ Y: L8 k
0 X" |/ f; r$ s! R#获取当前存储的人脸编码集合
* R( i( B4 @1 ]5 G' bdef findExistsEncodeingList(img_path):
/ N- ]* t1 ?( L+ Q. t( [: W/ D images=[]. k! m! p( G* C2 H0 b% }
#列出已经上传的所有图片
* D5 M0 j; O. x9 R$ Q imgList=os.listdir(img_path)
& h8 X9 D$ Z/ [, F& r9 Z/ W #处理存储的图片得到其人脸编码
% @& J9 E( d e% k' l- {% ~, m for pic in imgList:
6 g' X4 [3 T! N1 W img=cv2.imread('{}/{}'.format(img_path,pic))
( E* O2 R; w. L images.append(img), \, U7 J! T; `3 \! X$ j
classNames.append(os.path.splitext(pic)[0])
- w1 F' I: a6 G9 c# L findEncodeings(images). M* ]1 J) H I4 V$ q
5 m) t; `/ @) i#选择并对比图片
4 A* a4 ^/ T( @def choosepic():& Z( P1 F* U3 B
choosepath = tkinter.filedialog.askopenfilename()' I# {6 G3 p7 w. ^- L4 Y0 o9 _% X
path.set(choosepath)
# ~& K' \8 f9 P img_open = Image.open(entry.get()).resize((530,750))0 y3 e7 K q. `( O
img = ImageTk.PhotoImage(img_open)
# C0 O# l, Y3 G+ A6 s4 z* W lableShowImage.config(image=img)
" a! L! [3 Y6 B+ {4 s h: A lableShowImage.image = img& x V% Y$ J" m, ^* U
lableShowImage.place(x=30, y=70, width=530, height=750)
# k$ V- V$ Y. p. k* V" [, a faceRecognition(choosepath)
( m* m6 d3 f6 K) _
$ i" o/ q9 v1 N1 q2 Sdef faceRecognition(choosepath):1 ]! l6 D8 C+ Z4 t! v
frame=cv2.imread(choosepath)
+ B6 x1 d" p: I+ _ frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)' b+ p0 Q1 M# @' l
#对摄像头读取的检测人脸
% z4 `: A2 _* Z' x$ ? facesLocate=face_recognition.face_locations(frameRGB)
7 a4 N1 U% r! N* A #进行特征编码
* `* a4 Y# V/ ^2 s s& Y; u% C8 |6 } faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)
% S5 n- C, c7 k- |7 z' | #遍历检测的人脸和库中读取的图片进行对比,计算其相似度4 {2 r' w9 r D( Z- {( N9 V
name='unknow'3 n) ^! K2 E P8 G
for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):8 |$ f% P" x6 ?* r7 u2 e
#进行匹配! ]) V( w t& |! \: {- I7 d# o
matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)) \) N9 j% [3 A) J( H
#计算相似度" F6 |* E; k, o- J% @4 p
distance=face_recognition.face_distance(existsEncodeingList,face_encoding)- o/ \; j* T& x7 O, ]$ o
lab='unknow'' Z, u4 L9 j9 U$ b5 }2 v' ?: a* h
for index, item in enumerate(distance):* M5 i$ ]* b- s7 ?" k- b K
if item<0.5:
' w' c3 m' {; ~ if matchs[index]:
% \. z9 }! t$ {4 n #得到匹配到的图片名称与相似度值: y( T" s6 j5 l" b8 D( P! Y0 m
lab='name:{}; Similarity:{}'.format(classNames[index],item)
/ Q$ R/ F8 h/ g2 j name=classNames[index] \ ^4 {* a. U) @! E* |1 J+ G) x
break. I# ~3 i, b' ~* @3 d# \$ R
#初始化面部捕捉框显示绿色2 R$ R$ h$ `& g' W: G
color1 =(0,255,0)
! W2 ^: N8 N& t6 f if name =='unknow':2 w% Z5 R n6 c# q
#未能识别的时候显示蓝色/ w8 }3 f" X; i4 |3 ^1 R, i2 J( u3 ~
color1 =(255,0,0)
+ G! T/ ]$ v6 q( \6 G #画面部捕捉框
# k: l/ _. u: W& \7 O `7 [ cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)# e0 M5 Z5 ? S8 A2 U; h
#在捕捉框上添加匹配到的图片信息
6 M4 z. N0 M% M+ ? j- | cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)
# L! E" @2 a/ h. e8 O) P# U: h cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)
8 y9 x4 N4 D& S2 Z: {3 t4 q. y, i img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))! i" @+ U2 e, q
img = ImageTk.PhotoImage(img_Recognition)
: j3 b2 a0 R7 F5 m+ }+ C2 f* X lableShowImage2.config(image=img)8 D7 x" w0 D' A# T! G* i; d: m* s
lableShowImage2.image = img7 m" R* x W1 v% M4 C$ p7 E
lableShowImage2.place(x=630, y=70, width=530, height=750)# f1 p( C# l" L0 I8 h
; N2 f; x' w* o! ]) W: O, m
if __name__ == '__main__':
2 R8 V! U2 j% U2 v2 p findExistsEncodeingList(img_path)8 k0 N% p- `3 D' h) J
#生成tk界面 app即主窗口: g% f0 ]' D% v# i/ e7 D2 U$ {
app = tk.Tk() " F0 D7 X9 V. o; v6 _% `
#修改窗口titile
. u7 V6 N8 \3 p6 l. n app.title("show pictue") $ z! S, h+ y- N4 G3 T7 ?
#设置主窗口的大小和位置
. x- `+ g& ]$ T/ u- }& ]% m app.geometry("1200x900+200+50"), W" g+ ^9 W. U4 u* t, K5 R2 D; T; o
#Entry widget which allows displaying simple text.' u! [$ o, P% \) L+ X( \
path = tk.StringVar()
4 t) U0 F* k, | entry = tk.Entry(app, state='readonly', text=path,width = 100)
7 b: ]9 B0 ]! B- `# _: N }! m entry.pack()
! `3 B# h. I9 \3 d/ G; Y h' q# T$ p6 @9 ? #使用Label显示图片# `5 j0 b2 g3 E/ ?5 f
lableShowImage = tk.Label(app)
4 N' W8 O) S+ c) m4 U( } lableShowImage.pack(); J7 H2 m( l2 t) X- z6 T) L! W( W h
#使用Label2显示处理后的图片
& @' n5 n: \/ @ lableShowImage2 = tk.Label(app)
' ], h6 e! K' g% p lableShowImage2.pack()7 {/ W a- O9 ?& g; N1 W6 O' N% N
#选择图片的按钮
9 D; O4 b5 M# T+ E& D7 ^- U ` buttonSelImage = tk.Button(app, text='choose picture', command=choosepic), ^8 k* w" Z6 i- U* h) N3 k( J5 i
buttonSelImage.pack()) D; \4 ?. A8 W. Z8 y
app.mainloop()
: G4 z/ [# C# B
' h9 w8 ~5 A; ]/ Z$ P$ l3.说明7 K# J+ h# s9 Y. W. x- D; s
首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。 K" b) K K4 H/ }; a7 h5 ~
; S- b$ B# H, F! l' i% b
4 M3 m8 J8 | b& y2 {. z
/ F/ x# G+ F/ o. ]) E
其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片- [+ G. B9 D g' l0 k& y
( ?; v/ m, b! x0 T
6 y; [* J3 E9 v/ {, @6 z. {
# e: F: B! }% q0 U
但是效果会存在色彩的失真,效果如下:# ~7 ?; @! i9 }% @9 {" R+ \
" }7 F1 p4 R* j+ u: c J
& s" j3 {5 N/ \8 B1 z( T, d
. ~: M; f+ R9 h6 V: ?1 S
也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。 g% l9 q) o& _& \+ r6 M
* q# v1 @' }% o8 b1 r# p这里简单提下PIL的九种不同图片模式:
9 n9 C7 c) h2 K# f3 G. L& |
# o+ t/ S6 d& Z7 A0 Z% |7 lmodes 描述
2 Q7 e! F4 `% S% P1 i D7 G1 1位像素,黑和白,存成8位的像素
+ w3 y+ x4 n8 ~" s' ?$ }L 8位像素,黑白
. ]/ s- T( C! \3 u P, ZP 8位像素,使用调色板映射到任何其他模式
* G7 U+ c8 e1 x5 I4 d" v0 U+ g4 p0 `* V. @RGB 3× 8位像素,真彩+ G$ W$ N) M% d3 P4 @8 l. J1 B
RGBA 4×8位像素,真彩+透明通道! _. s& ~- C* X4 {1 q# E6 B
CMYK 4×8位像素,颜色隔离
3 J$ Y5 K- ]; M5 N5 ^YCbCr 3×8位像素,彩色视频格式
/ t4 Q; A0 M& ]; |# q' nI 32位整型像素7 @! C3 R. m0 s/ ~" O: g, x
F 32位浮点型像素0 J: H7 i `, {0 F8 L
4.实现效果
$ U8 ]) S& {4 W. X- y
9 z, a; V. E. Z! p9 p' G" B, Z8 B1 V; v
+ v$ y$ M. b6 x% s' N
* n1 K' y+ Q6 E# a h
可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。. P. C) a1 J( n/ s, W+ h9 x" \
————————————————
% Q) |) @1 p/ _. j) m3 p0 U' X1 c( K版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
5 {& X3 ~, I0 N% @( w" p原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288 e+ r7 G/ Q1 `: K% d
% k* u q, ^; D- w d( ~8 F; F [, ~ c9 g2 ]5 m( u. {
|
zan
|