- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 565171 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 174774
- 相册
- 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实现人脸捕捉与人脸识别(照片对比): y0 L/ l; R4 R2 |" q9 t' m
1 C* ~5 \' ]& b4 M0 o& m+ m4 l% B& [* n7 h
1.安装包依赖
1 q' K$ I2 z( R2 @( r4 x; U, l与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。. {9 E( ~" G6 q. d, x8 M3 c% v
6 A! Y8 y& v3 R/ O7 N. X/ G0 S6 T& z
在python 3以上版本tkinter是环境自带的,所以这里不需要安装
5 P( {0 F) V/ R- ^* X( t
, Z) x, G' y% B ~) _2.代码示例
3 L+ M7 N- h9 K( Z% T3 b) Gimport os
: g2 a B* t. w# Aimport cv2
3 X1 }' ~) G3 q, fimport numpy as np9 z) f( J/ b' I. `6 b5 [! c4 ~
import face_recognition
( U' W' L( ^" W# x; \' pimport tkinter as tk , K& q3 k! ^( `' d8 T
import tkinter.filedialog6 Z2 L0 v$ n# D; b
from PIL import Image,ImageTk / j, s* X- Q& A& Z9 a8 F
1 U4 q3 p. B9 Z: h' X, L0 G
classNames=[]0 T( l0 \+ i, S1 Y
img_path='Picture'
! F( `8 z: ?. l+ ~7 n: \- ~img_recognition_path='Recognition'
" J* D5 w& H6 ^4 k1 yexistsEncodeingList=[]! `4 g& B; p$ ?6 l; r
#对人脸集合进行编码进行处理2 _* j, k! m6 c% A
def findEncodeings(images):
4 S- {% {9 n$ h" O for img in images:6 J: `2 e& z& w5 [5 p6 [# U0 w" H
#灰度处理
7 b5 |' n9 }3 g5 F img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)% I- }2 h+ A. R/ R. d4 Z" X
#face_encodings对图片对象a_images进行编码并返回数组0位置编码结果# e3 W% V; [) D8 `
encode=face_recognition.face_encodings(img)[0]
; S0 t0 S4 Z6 T7 z1 k, c existsEncodeingList.append(encode)
: \2 d. y0 {/ A+ A# }. r& k! w0 R- Y
#获取当前存储的人脸编码集合% ?; {7 _" T- w0 B
def findExistsEncodeingList(img_path):
0 h" b5 U( l' ? images=[]
; N9 h. H% a, y0 t #列出已经上传的所有图片1 a; K, z8 B1 l; b4 u
imgList=os.listdir(img_path): i: ~: Z) _6 L/ e$ {
#处理存储的图片得到其人脸编码! q$ Q! P5 N. w: n! Y4 P1 Q
for pic in imgList:$ e9 g- }+ {( A
img=cv2.imread('{}/{}'.format(img_path,pic))
3 j5 Q* m+ G) G. {) ?3 } images.append(img)
' t( v/ y: I8 b' e$ l classNames.append(os.path.splitext(pic)[0])6 G2 j8 M' ?) i
findEncodeings(images)! F; G/ w- N2 }: H: S
% k) {* n, X0 w1 p
#选择并对比图片" M6 w% v' R7 l/ {
def choosepic():
5 p- J, c) S" T+ k* W8 z- b) N2 O4 D choosepath = tkinter.filedialog.askopenfilename()
2 B5 p& `( N, S3 E* J6 J# a% t( X path.set(choosepath)
h5 s$ H- k5 c. K: |5 C img_open = Image.open(entry.get()).resize((530,750))
: e U2 T0 x7 z# ?9 n/ L& w8 U img = ImageTk.PhotoImage(img_open)4 ^% ^) r7 o6 y8 Y# e3 w: f6 s* e4 W1 Y
lableShowImage.config(image=img)
2 [- ~1 A/ h/ q4 Z' ~ lableShowImage.image = img, h( m: P0 \9 r# o
lableShowImage.place(x=30, y=70, width=530, height=750)
* H. U9 s# }+ M1 g9 V8 Q& l faceRecognition(choosepath)
5 X/ F7 W! [! h& f
* {( n, u- w1 I/ l# ^def faceRecognition(choosepath):
* F$ ~7 m3 h2 ]& L9 x frame=cv2.imread(choosepath)
4 L, X1 s. B+ P. V1 h frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
! h& o+ S O1 \ #对摄像头读取的检测人脸
1 k# H" Z9 N' U# ~: L3 T$ e facesLocate=face_recognition.face_locations(frameRGB)
" W5 Q6 |3 m: i& F; E9 P4 E #进行特征编码& }: G6 J& X: Z. v" ?5 E$ P
faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate), ^$ ?4 d- X9 ^
#遍历检测的人脸和库中读取的图片进行对比,计算其相似度
) ^: ~4 b2 d! \6 C5 M+ V name='unknow'
- ]5 K5 T5 B* H7 l8 u+ S for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):4 T$ o+ T- t% S
#进行匹配0 k9 r, s: ^, O4 q9 p
matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)
$ r, _- K7 J' C* p0 B #计算相似度
; w; y) t8 a' H% r! m8 Z& M1 W distance=face_recognition.face_distance(existsEncodeingList,face_encoding)
: D" J* y% e; } l7 f. c/ e' M lab='unknow') G/ [2 m! i9 b. M
for index, item in enumerate(distance):' J: D5 Z8 _+ v* T0 T% @
if item<0.5:
. v3 h3 p' o# a2 i6 B: @' J if matchs[index]:
/ a7 Y$ m! k: d) e #得到匹配到的图片名称与相似度值4 ^, S" I) G' w8 `3 {
lab='name:{}; Similarity:{}'.format(classNames[index],item)1 x& \# X5 A% a' V1 U7 \
name=classNames[index]
: }5 `6 s2 u) G" L break
0 |7 {# O" h, O @ #初始化面部捕捉框显示绿色
5 w3 G3 `5 }3 o. p color1 =(0,255,0); d+ B# h2 u! T- H: e' i7 Q& n
if name =='unknow':* d. _9 Y- X: k) s( R
#未能识别的时候显示蓝色9 n; i5 [1 N5 S
color1 =(255,0,0): W# h6 ?. g( Y' ?1 X
#画面部捕捉框
1 R6 B3 j- P. \: Q& r+ |. S cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)& J6 Z1 `) I9 k) g, \: t* ?
#在捕捉框上添加匹配到的图片信息# q! g' u4 [3 v$ C
cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2); W# P( b# z- }9 C$ v, Y6 G/ I
cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)6 S6 L/ P. S1 [7 y* f& i
img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))
6 r* f: _ ~" c, Y z7 c* Q* { img = ImageTk.PhotoImage(img_Recognition)
* M* ?$ L& U* `6 T* | lableShowImage2.config(image=img)
/ X) }6 T; [! ` lableShowImage2.image = img; H. j3 ?2 w* L: V" v: o- J Q
lableShowImage2.place(x=630, y=70, width=530, height=750)2 r+ ~8 ?. G3 z; Q# M& y+ D2 ~5 d
, m6 k# X. O& D0 v7 |* [
if __name__ == '__main__':
* t! }. h3 \7 m" E findExistsEncodeingList(img_path)
5 R" o# K0 g- M& }5 j) { #生成tk界面 app即主窗口
; }2 P; G1 r8 `. ?2 b% [, T app = tk.Tk() 7 h2 a# {) m6 E2 i4 R t- Y
#修改窗口titile3 k8 S. I4 W; X* l- U
app.title("show pictue") 3 I6 B4 D0 Y3 L. I O! Y7 `% j
#设置主窗口的大小和位置
7 W/ W7 ?9 b% Y' ~0 J app.geometry("1200x900+200+50")) f" x# X: k3 G. y2 n
#Entry widget which allows displaying simple text.
0 C7 h- W* C* N( R$ P path = tk.StringVar()* \! P7 x7 b$ h) l3 }$ M' e p
entry = tk.Entry(app, state='readonly', text=path,width = 100)
: C; p+ S8 M- K$ O5 x+ T entry.pack(): g4 d$ P) L) ?* L# q
#使用Label显示图片
/ W) l; M( @* } lableShowImage = tk.Label(app)' `5 o4 O8 r" {9 [) x
lableShowImage.pack()1 E9 t& f: E5 s: N i
#使用Label2显示处理后的图片6 u: z7 j3 @- L; W
lableShowImage2 = tk.Label(app)) H: T+ b E, u; @% }
lableShowImage2.pack()" b8 O) q. P) t8 |( y9 s0 U0 a9 a
#选择图片的按钮
6 Z4 c, i0 B& M5 G7 l) n buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)3 q4 x$ Y, o. y: d0 [
buttonSelImage.pack()
! K3 k$ J4 J, g# i6 g$ I/ T app.mainloop()
5 c$ F5 w1 ^5 @8 _2 @
3 I5 M* ~2 ?9 x+ v! ]# v3.说明
. J( V, k, S! i首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。
' G3 k2 G: Z; L; Q8 `4 t( T- h; m, P* D9 {* ]( h
+ Z- @1 r) C) i7 a `
( x6 k5 I- b2 Q; @5 |% m ?0 E: a
其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片" [3 W, U+ f8 v2 e: b$ `$ K) O1 U% h
, x6 }' v7 c- }. K7 ?* W
! d- w( s0 _* o4 {2 }- W
6 B* n/ n* [4 t1 A; } 但是效果会存在色彩的失真,效果如下:$ Q/ t2 |" X7 d4 f! a( c
) V" O& r, g) g1 N, Y3 \) R9 j! S& q C8 H
. P; R' i2 N# S) q1 ~
也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。5 ], ?" k1 v" k+ K5 k+ u
) O7 Q# k) K& O- x& V这里简单提下PIL的九种不同图片模式:5 e% v# j W9 C! B' t
' m, {1 u' X2 }9 O5 v. A
modes 描述
) ]2 |& w' C5 }4 X+ b1 1位像素,黑和白,存成8位的像素6 `9 E) Y7 z6 c( h. b8 y! F% b& \
L 8位像素,黑白2 _# M2 d4 d5 B" X' a4 }
P 8位像素,使用调色板映射到任何其他模式
; b) o" s2 j- ~& Q+ V0 Y# LRGB 3× 8位像素,真彩7 j& E+ u- u1 |# F% T4 g1 T% g3 R' [! N
RGBA 4×8位像素,真彩+透明通道& K/ A$ \ o. y( d% L& s
CMYK 4×8位像素,颜色隔离% k8 v/ s+ p- m( m- _+ }: x
YCbCr 3×8位像素,彩色视频格式
# V# x: o0 n/ w4 ?7 Z$ yI 32位整型像素+ @. W$ q+ V- d- A* N s5 n. ]
F 32位浮点型像素
1 L) E7 H: a* \- w4.实现效果
( h: f, z }/ Q8 b
. ]7 B, s* ~7 }! \0 l6 J& c
: y$ Q! V! t9 k+ l
, G/ M0 E7 T+ {9 j( k+ M9 }
E1 Y. E& T" J' |4 g7 \" D. i 可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。
1 l+ X- @+ e. d% a————————————————- ~. X( p) m9 o& a5 q0 _
版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
6 M! O" G* a* i O- t8 @原文链接:https://blog.csdn.net/qq_17486399/article/details/1266292881 i7 j+ [7 L& W- J1 t0 t" q+ c. u
& l- y) G' Y [* Q
1 ` x2 K: l3 |8 z8 S/ T |
zan
|