- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 561789 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 173910
- 相册
- 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实现人脸捕捉与人脸识别(照片对比)
5 T, G0 h6 O' N- l: w5 s# A: Q" O. n7 J6 Q5 a; Y8 i% x r3 Y8 K
1.安装包依赖: j6 D/ n$ B3 ~8 N: K7 h
与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。
9 F5 V/ \7 u# X3 O# ?; Y `5 }& {/ H
在python 3以上版本tkinter是环境自带的,所以这里不需要安装4 P% h" ]7 w# ~$ U, S
$ Q0 n# k! {7 z% U# ^& Q: T
2.代码示例' x& ?3 a' U4 J( ]
import os# G' N" [( _2 F4 i( Z
import cv2- r! x6 k, ^. } [
import numpy as np
& @9 L' t" J0 I& O/ i- Z3 @import face_recognition& ~; |* p) ^4 _5 f/ g- Q
import tkinter as tk . w3 y6 j4 T0 T/ [4 ?+ m: }" J( t' I
import tkinter.filedialog) S4 M4 u6 Y3 V1 X$ q Y
from PIL import Image,ImageTk
. Y3 f% |9 \3 a. m; g/ |$ ^3 p2 Q5 v7 B7 O# Y0 j& B
classNames=[]
2 x3 H. } H( q f% Z( o, oimg_path='Picture'$ ^' H! D2 i8 R2 }7 M( T: F
img_recognition_path='Recognition'# K, U8 Y/ | y# W
existsEncodeingList=[]
+ n- Q5 }6 A/ a' R#对人脸集合进行编码进行处理
) Y- i) T( M8 G% r) {/ T. Jdef findEncodeings(images):
3 `+ y( M/ \7 C3 b( q- ? for img in images:3 X" y! h3 |4 g0 C0 @& i% I, I$ w
#灰度处理
, I5 O4 _8 b3 Z: j img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)
2 [: a2 \9 n, C) }+ K #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果
. X) X; C+ w. x/ F/ i5 } encode=face_recognition.face_encodings(img)[0]: a' p( r+ B; h4 b' v
existsEncodeingList.append(encode)5 I* t) C8 l0 N1 c! r
* b# K* H/ ~& R+ ]. {0 Q3 `5 f) ?#获取当前存储的人脸编码集合
" e. O' w# U8 o& P4 [def findExistsEncodeingList(img_path):4 n& _/ @: N+ C" N
images=[]
4 T- S0 |- x, N; C) ^" w0 s #列出已经上传的所有图片4 w% E7 k8 x3 k, C6 N9 y
imgList=os.listdir(img_path)
1 K" V' Q3 y5 T3 h: E #处理存储的图片得到其人脸编码
0 \/ B& }0 s0 l8 C7 w Q for pic in imgList:
0 ~) t- @, T1 i* W5 |; ] img=cv2.imread('{}/{}'.format(img_path,pic))2 @$ p- L9 u2 o
images.append(img)" [4 ]4 ]) C" j0 [6 x J2 D
classNames.append(os.path.splitext(pic)[0])8 ~" V6 b2 f/ X8 U2 j2 P) @
findEncodeings(images)
+ I3 [: \8 o# V/ |
; {) ]' q8 n) s u5 H* U+ a2 n#选择并对比图片9 m* @2 f, A+ V0 h ?
def choosepic():
+ u: O. X/ I& ~9 k choosepath = tkinter.filedialog.askopenfilename()
3 v% p) c* Y5 S# k% C* | path.set(choosepath)
) I4 }$ y" K2 I4 @8 O* B0 A img_open = Image.open(entry.get()).resize((530,750)). o6 Y- u7 P, v
img = ImageTk.PhotoImage(img_open)/ @9 c+ e( @9 V+ |/ G2 ?7 C, j
lableShowImage.config(image=img)6 b# L$ |; [8 B* L2 h
lableShowImage.image = img% U: c4 p- |1 l) Z& G
lableShowImage.place(x=30, y=70, width=530, height=750)+ e2 D1 l4 P( t; g/ Y+ A
faceRecognition(choosepath)
; J- I5 z( ~% @$ D# S& o* i; {+ `9 {- T- z ^3 L% U
def faceRecognition(choosepath):$ Q1 ^2 s8 a) C: o( X0 s
frame=cv2.imread(choosepath)
) L. h% ^1 G/ S frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
4 w a K" k1 A, u7 ]( W+ s7 X8 m #对摄像头读取的检测人脸
0 P$ t. r' X, ^) ]% ^- [1 L) r. N facesLocate=face_recognition.face_locations(frameRGB) w1 r) c% [3 ?6 v+ O& X0 D
#进行特征编码1 V: o( l B( g9 S: X
faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)
4 U$ I7 r9 i: O6 g #遍历检测的人脸和库中读取的图片进行对比,计算其相似度; y% s( l- q; _. x
name='unknow'% l; t6 c" ^; F$ n
for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):
! z/ X. @4 U' W5 @: l0 m/ O/ Q& b #进行匹配
i3 e) b3 m! s3 i matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)% ~' l; W- Q: L, @
#计算相似度# C) S2 V0 L& M+ v7 N, W% o
distance=face_recognition.face_distance(existsEncodeingList,face_encoding)1 i2 h, w% E1 J7 w
lab='unknow' \' n! M2 H Y6 B
for index, item in enumerate(distance):8 T8 l, H8 Q# V7 k" e
if item<0.5:
$ W# S' F C9 M9 m" @6 P- ]' P if matchs[index]:4 y6 O5 k b* l8 ?; ` a
#得到匹配到的图片名称与相似度值% T5 W+ G2 S( ]& q- z& B9 H% v
lab='name:{}; Similarity:{}'.format(classNames[index],item)
+ m' ]$ _) _* W9 }9 x' E. n name=classNames[index]
* N% M/ T- o9 b3 z l% n7 g break
( k! o% _6 Z; u/ g7 I* n #初始化面部捕捉框显示绿色# e; W' ^5 u% L
color1 =(0,255,0)9 g; v, d& x2 x! T0 C
if name =='unknow':0 n! M7 r0 Q7 ?) E
#未能识别的时候显示蓝色8 I6 ~( ?" Q: C" ?9 ~
color1 =(255,0,0)
% m. x* I+ e- Z( D4 N& a6 }5 r #画面部捕捉框0 _# H# V( k& H
cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)
* X' R, |. t, ]' P3 e5 b2 i8 d #在捕捉框上添加匹配到的图片信息& z; t; j3 A* `3 a. I! `
cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)4 z2 ?% D. E: W2 @
cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)
3 A* t E! a+ d' r5 j img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))
+ ]" p& c' W' D- d+ v, h img = ImageTk.PhotoImage(img_Recognition)" ^! }' O9 d, y: {
lableShowImage2.config(image=img)$ B" S) b. U2 X4 W
lableShowImage2.image = img) m. g/ U9 y( m
lableShowImage2.place(x=630, y=70, width=530, height=750)
A% y1 u y0 H& s+ T) {" ~* q/ h6 Q( [, }+ V6 W W. I0 r
if __name__ == '__main__':, S) ^( s8 H! K1 i: b6 \
findExistsEncodeingList(img_path)
) X, P+ ^4 Y0 `! q& P #生成tk界面 app即主窗口
' N5 @' w' q/ g' C5 Q6 I7 X. g0 ? app = tk.Tk()
9 H6 i0 i1 R3 N) [ A3 Y8 \ #修改窗口titile
, Z- m0 _! [. Y3 n app.title("show pictue") $ Q" J2 z* [+ X& R) J; g, P2 G& X/ b
#设置主窗口的大小和位置
, s3 T' ~+ y& K$ L& R# f0 h app.geometry("1200x900+200+50")+ q6 n# g6 p9 j# M5 J5 s9 B# q
#Entry widget which allows displaying simple text.9 W9 g' O; A; v5 L2 b# w( _
path = tk.StringVar()1 t6 C2 X% {9 O, G2 z1 T) s8 d
entry = tk.Entry(app, state='readonly', text=path,width = 100)
: u' ]# r( P* A$ ` entry.pack()
7 O" m6 r1 k# | P4 Y I #使用Label显示图片, d9 i) O7 V& f: m, Q* U0 @% Q6 ?
lableShowImage = tk.Label(app)( Y" b% H$ H M8 H4 @1 i
lableShowImage.pack(). P+ T1 x5 o6 {
#使用Label2显示处理后的图片
$ s* a5 T3 p; M/ K9 ]- m/ D9 Z0 I lableShowImage2 = tk.Label(app)
8 l) L! I& f7 h2 ^! u8 g# j3 z lableShowImage2.pack()
0 `$ s* E: o& r2 D #选择图片的按钮
7 ]. M6 u& @2 {5 X: ] buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)
\4 l" m, D" z" ~ buttonSelImage.pack()
/ H2 c, H: L3 [7 i) c) w% Q8 [ app.mainloop()
% s; J9 X4 f& U0 L4 d* R" f( R7 f0 C' l( I* J
3.说明3 V0 L" \6 t2 T$ h3 S' n: A' R
首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。4 C0 W7 F0 D: Z! [/ M$ z
$ T0 `. I+ d( {8 x
: c: _ O) ^1 W8 h3 r3 u9 E. d% s9 D0 {3 X) A& _- ]; F
其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片
: N* o: o+ ~1 E: R4 ?: S6 N
1 |" f* Z! D& Q" Q+ |3 I' y' B. O. F6 N/ d1 g
4 E4 R1 g. o% d2 L X2 [0 X 但是效果会存在色彩的失真,效果如下:
$ f$ [ k- }0 I+ \8 E
4 B: K, F" c7 L! a) e' j0 N4 j9 t2 ?0 u/ O: N# \
! Y4 `5 L% ]+ L( T% ]& f
也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。) L; a# w+ B8 m4 {
# U0 y! }: r4 S1 @/ v8 Y7 k
这里简单提下PIL的九种不同图片模式:
! b3 B" A/ `: T& ^% U; P+ l* n$ D$ r6 j* f
modes 描述5 \* V, h7 j% [) i; h/ ?4 o2 G
1 1位像素,黑和白,存成8位的像素
. I. F8 V' w8 zL 8位像素,黑白
+ O& u# T) k% i& Q1 p1 n- b; _P 8位像素,使用调色板映射到任何其他模式
! e& p7 g- a. MRGB 3× 8位像素,真彩* Q- L, b2 o/ `) K. n
RGBA 4×8位像素,真彩+透明通道
8 k+ e/ J4 ~* K/ D1 f4 J4 gCMYK 4×8位像素,颜色隔离: W+ R# _$ a1 X1 O! h
YCbCr 3×8位像素,彩色视频格式0 H7 |/ _% z+ e/ h
I 32位整型像素
- ~+ R! G `7 {4 k% U5 |$ O- RF 32位浮点型像素
" ]# ?* h2 L: Q$ @4.实现效果. y; I& O1 x* B' T+ N! H3 L
2 ^; O) u$ }, x y. o
* n" N. v0 \% F) S$ X
& Y0 n% g6 ]4 i: J5 Q9 J5 ~' S. z$ c" c
可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。5 l0 E7 u5 \, g; e
————————————————
8 ^; V9 \5 F$ e h版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
& x( _8 u1 F& ^; x% _$ L原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288# Z) C0 [8 t7 H" y2 s5 v# X
6 d( U; T I2 H. t6 s$ c
s9 j5 d# b# I6 ]! }, h |
zan
|