- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 554648 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 171767
- 相册
- 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 T; f, t' ~. d6 ~1 N9 r
( E7 o0 V( @+ {' q: m( Y; w* g1.安装包依赖
6 n+ W: b6 O, h- u. f7 ~' v. v与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。
/ ]. b& k2 g# `# E E% l2 r! _
* b% H9 T, n9 _' J在python 3以上版本tkinter是环境自带的,所以这里不需要安装: J0 `1 j- Y# {( a/ y
% j+ N, l* j! S; @. T/ Q: {2.代码示例9 _5 h- d @" ~6 N! c! q9 `4 X3 x
import os) U! K5 E; R* o2 j1 W
import cv28 _7 h: e8 R D3 U, m5 t' ^
import numpy as np& S3 ^$ d) i/ Y
import face_recognition- H2 z9 v) u' W( U7 b& J2 `
import tkinter as tk
4 @8 t. ~! R* {$ M+ yimport tkinter.filedialog
9 |- S8 _- b6 l$ Hfrom PIL import Image,ImageTk ) T( s1 O* }. ]; H
" n2 P6 I/ P! h+ K6 D2 h, A0 L2 vclassNames=[], K' n. Q9 X+ u! b+ U, ?" d
img_path='Picture'
) g! i. D* }% X+ Y' H# ^8 _: @6 |img_recognition_path='Recognition', A" W/ }: r) q$ v! h( o1 g
existsEncodeingList=[]7 y+ ?2 t! Q0 G* }0 j
#对人脸集合进行编码进行处理3 }# _2 M E$ ~% D$ J! \
def findEncodeings(images):
, w4 g; j9 x9 Z5 P, I for img in images:7 X' e* y9 C L4 d$ l2 H6 R
#灰度处理
1 I! Y! x C: ` img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)$ c) w" @5 K5 A) a: @% y
#face_encodings对图片对象a_images进行编码并返回数组0位置编码结果: T5 E; b C0 N
encode=face_recognition.face_encodings(img)[0]
' S0 P2 x8 _! H4 R/ E9 K6 d existsEncodeingList.append(encode)
_0 u' l$ J! I" I
/ X/ P* q7 S0 V! D' e6 d. y#获取当前存储的人脸编码集合
6 X/ w8 E! i: q% [def findExistsEncodeingList(img_path):0 m j/ l9 H1 X5 h
images=[]7 o$ T. B4 A6 P+ ^0 j3 h
#列出已经上传的所有图片 x5 w8 V) `) c+ u4 G
imgList=os.listdir(img_path)8 X3 I2 c6 k8 _/ T) g4 j" O' s
#处理存储的图片得到其人脸编码
" }& V! k0 G+ e, W' l/ E2 k for pic in imgList:6 D. l0 M- a0 E
img=cv2.imread('{}/{}'.format(img_path,pic))3 M# H% V& |/ [' _3 d* t* R
images.append(img)
8 k! q/ k2 h a; S) _6 f6 E* o classNames.append(os.path.splitext(pic)[0])* c$ P/ K9 z2 k2 }/ `1 x
findEncodeings(images)
q8 n( K6 W F9 y, T: z
6 c9 J' \6 r. v+ b, e5 _#选择并对比图片+ X C' @& J( C4 ?$ R/ M2 [9 C8 B# V) |
def choosepic():
! L) {) s% N$ ^: k5 v) v: m) K choosepath = tkinter.filedialog.askopenfilename()
1 k) ^0 p$ R, _4 s- w1 ?3 h path.set(choosepath)+ S% c, u2 E H5 h, Q1 F4 U. [
img_open = Image.open(entry.get()).resize((530,750))
1 W1 X/ p$ S7 Y/ r img = ImageTk.PhotoImage(img_open)- t+ x. J3 c; _* A1 F/ a! F
lableShowImage.config(image=img)
! f0 N7 h6 b! X4 @+ M S8 s) s lableShowImage.image = img7 @# M/ G3 e0 x) H( B! @
lableShowImage.place(x=30, y=70, width=530, height=750)
' f( _2 h5 o2 o# e$ o faceRecognition(choosepath)
N$ w1 D4 L1 Z, k( a+ @! a) \# ^6 k, [' _2 a( Y1 G
def faceRecognition(choosepath):7 \8 N$ A' `9 `, u
frame=cv2.imread(choosepath)
$ K Y3 y" x( p* l r& N! `/ r( g frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
5 q. L; |) L* I/ u# ?5 X5 ]0 `" @ #对摄像头读取的检测人脸4 T0 o1 b# M2 a% \ U
facesLocate=face_recognition.face_locations(frameRGB)0 h. D$ U. p1 D$ i9 I- d4 }
#进行特征编码
4 [! Y6 A2 e- [. b, t/ }: S: Z faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)- y8 _& X7 k, O. Z- c7 C) `0 h
#遍历检测的人脸和库中读取的图片进行对比,计算其相似度! K: B/ |6 n% Q. g& ?3 D
name='unknow'
7 \. z6 t9 P+ ~5 C5 M for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):
" r. X5 q/ {, ]5 l. H. ]& ] #进行匹配2 i: F0 Z- R( E$ N
matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)/ d/ a) S" ?1 g
#计算相似度
0 ] X) \) J4 `! B distance=face_recognition.face_distance(existsEncodeingList,face_encoding)
4 n* Y$ d" F9 J9 R( r* b1 ] lab='unknow'
2 m0 G/ D, O+ M* E! Y9 ]' u for index, item in enumerate(distance):
. J/ @) _. P5 _+ j8 G# s if item<0.5:; @9 B( e+ B+ n8 U1 L
if matchs[index]:
: q% Q w) a$ ] ?: k) ~ #得到匹配到的图片名称与相似度值
1 [7 u) U X. @* ?' O- ~ lab='name:{}; Similarity:{}'.format(classNames[index],item)2 d7 T; b+ j0 e. w' N1 K* a
name=classNames[index]7 Y! a! q) p, |- x0 a8 K
break
5 S6 j5 |: m) ?+ O# @/ ]: ?, K0 N, ? #初始化面部捕捉框显示绿色
- N' i6 f, ^" a" B# i2 y, V color1 =(0,255,0)
' Q' H% v/ u+ o+ p* g0 J3 z/ W7 ? if name =='unknow':
; q$ {- I3 H) r, }; F" M& t0 I1 [ #未能识别的时候显示蓝色
# _3 ~* X( b% B+ z0 @ color1 =(255,0,0)
0 @7 _6 u% ]( N5 _2 F/ i2 b6 B #画面部捕捉框8 I' g! i1 T. W* r: y" N
cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)
2 K7 ~# H! g* x3 s: J" N' `3 M$ \ #在捕捉框上添加匹配到的图片信息
4 S; u8 F; F5 m/ B: q$ h% J* r0 o& x cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)- L' _7 j4 ^0 `: L2 S8 B& ?
cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)$ S' z! y/ [1 V7 W: S
img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))) Z( U1 v8 g0 G3 ?+ ~' m c
img = ImageTk.PhotoImage(img_Recognition)7 C0 B; v8 [) {1 t% ?
lableShowImage2.config(image=img)
' G1 j8 z, a# G1 w lableShowImage2.image = img1 O' Q$ ]( u2 ]) U8 [# Q& U8 X# o
lableShowImage2.place(x=630, y=70, width=530, height=750)* f d& ~4 ]( B
3 u8 Q7 F# z- s4 ?- C/ M" D
if __name__ == '__main__':' V' z! e2 g, V3 m# c3 h
findExistsEncodeingList(img_path)
6 N& J, U! B+ I& c* X$ r% l, x #生成tk界面 app即主窗口! v, S5 s9 L7 r2 O$ r; Q
app = tk.Tk()
9 |/ A! W6 B9 {+ [5 Q3 X; m #修改窗口titile
% \9 {+ R) {3 t0 A; o& Y# P/ V1 j app.title("show pictue")
' V% z7 w* ~- H/ `# F #设置主窗口的大小和位置1 b9 B7 J2 {- s( t! U! ~: r @/ ?: p$ X
app.geometry("1200x900+200+50")/ ]1 T+ j/ @+ l9 `
#Entry widget which allows displaying simple text.
0 p3 r- B/ _8 A- c) K path = tk.StringVar()9 C- a( ~: D7 B
entry = tk.Entry(app, state='readonly', text=path,width = 100)
4 n6 L/ B& p8 L: f% q5 D1 d5 e entry.pack()
' e# n- Q5 f3 U; c' k3 B #使用Label显示图片3 x! ~# L' V* v7 e- x* w; }3 N# i
lableShowImage = tk.Label(app)- {3 y' C7 {; p( z3 R
lableShowImage.pack()
5 p* W& W# @* M0 T$ B# i$ D #使用Label2显示处理后的图片
0 A6 W) |) r4 }! T. _" \7 n6 L lableShowImage2 = tk.Label(app)
, H- y9 a- ]- L9 P; b lableShowImage2.pack()0 y$ l/ U" b4 F, l! U2 m% Q
#选择图片的按钮/ b, H, ]; w$ I y9 k
buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)
% \/ j. m1 h* J& H+ a R5 t buttonSelImage.pack()$ B$ G5 m! J- {: I
app.mainloop()
R2 f; h; d6 Y. f; i9 |
7 n1 t a: a" r3 M3 O; r) [3.说明
( i N. G% ^) E. N3 t8 V) l首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。8 @# D& `4 s/ j2 @
2 t! I9 L( j* n* ]+ q9 r9 K; T; Z W9 l* x$ r* u9 F' h6 R3 Z
8 F* ?5 s# S, J) f0 R% ] 其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片6 v, `/ m c$ {. H9 v5 x* Y: J
7 y5 ^8 N: S/ z3 c# y7 I8 ?/ e8 R
7 @" h x' G/ @' q' S( C e+ Y4 z4 m" c3 ?4 O
但是效果会存在色彩的失真,效果如下:; P) r$ z3 l% N
6 R+ h% V* S4 n6 @6 I
. i: `, ~6 W0 d+ W! X+ z
+ y9 \1 U: W1 U, t5 S8 Q' R% S也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。
2 X5 U4 G1 N" Y+ m
5 g. T/ z" S5 B4 {1 _. V& a这里简单提下PIL的九种不同图片模式:
; ?; H" y$ Y# x: Y1 U9 ~
4 M; \9 A2 i& v. a1 p5 Smodes 描述
) L7 F! S5 l& K+ f( @1 1位像素,黑和白,存成8位的像素! m! l# {! g) h5 p9 @+ W
L 8位像素,黑白
/ C, P" i e3 l: PP 8位像素,使用调色板映射到任何其他模式8 O7 a+ E, S, |7 @8 b& w! i
RGB 3× 8位像素,真彩
: S- O I5 m, H, xRGBA 4×8位像素,真彩+透明通道, H8 U. l2 r* y, O
CMYK 4×8位像素,颜色隔离, y; W x2 X5 \$ P( k& t. r* W
YCbCr 3×8位像素,彩色视频格式& n9 d1 F* f7 \" w4 F9 g9 e- t5 v
I 32位整型像素# h7 D) n1 k0 }; ^ ^/ R7 j
F 32位浮点型像素
6 H0 I# a3 ?8 P4.实现效果# D8 h/ W$ q' q) k5 w4 G" D. }
- \. f; W- d" B% x
' h' Z; ]+ J" x5 C i) P0 Y
~0 d) Y2 ], W# z3 v5 j; ~
& [, H9 A: z5 f/ o; Z- ]. |
可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。
: d2 l4 E9 W% l0 _6 z————————————————
4 g3 y9 U$ A4 {2 J4 K版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。! b5 q" d, c9 g
原文链接:https://blog.csdn.net/qq_17486399/article/details/1266292882 B- Z9 K# q$ K) r+ U* D
- l. U g0 O2 N/ [
8 b: f! p0 N& U0 a1 g Y# y( K2 y |
zan
|