- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 560976 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 173666
- 相册
- 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实现人脸捕捉与人脸识别(照片对比)* Q2 G' r0 C+ Y9 r' h6 M
) ^' ?, ~7 ^1 y* B4 |, |1.安装包依赖- `0 n& v! N5 l% V/ s" \0 Y5 f
与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。
* L6 Y: K1 q2 S* q) O
; L# d* u& R& h在python 3以上版本tkinter是环境自带的,所以这里不需要安装' T) u% K/ L5 u4 \! Y: K
7 }$ u B4 v3 t7 m, u2.代码示例
0 i! f8 n3 L3 H) }2 @+ T8 cimport os: u8 _( t- S- O, {8 ~5 x4 B' K; ]
import cv2
- G5 W2 o: K" c- a) T! q2 bimport numpy as np
3 k( A* P! ^ K+ g. uimport face_recognition
/ ?+ I! n. T& C# |import tkinter as tk
; v4 z- ]& \; P9 G# T$ f! f9 C+ rimport tkinter.filedialog8 @7 H5 Z! o" Z8 d! l
from PIL import Image,ImageTk
$ p3 j6 ^; `% o0 m) \/ q/ d& [! T q3 \6 a- S% v: Q8 X/ X
classNames=[]
8 z+ E1 E8 n) A/ vimg_path='Picture'
$ P3 O# j0 ]! a4 V. eimg_recognition_path='Recognition'7 A6 M7 A# U* T9 X
existsEncodeingList=[]% A- r x$ a* ~$ l- n5 S" w. ?+ g
#对人脸集合进行编码进行处理
( m) \: c Q- {! H# H( I2 D% L# Odef findEncodeings(images):
4 I) n2 ]2 h! n: f8 ^ for img in images:4 s, v0 ~5 g. A; W* j3 Q& a: @
#灰度处理/ {/ t: ]+ Z2 i7 a/ }
img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)
1 K0 Y3 r, A3 x" x5 A$ y #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果2 D) _2 Q; ]+ x7 m5 Y; M8 A) h2 e
encode=face_recognition.face_encodings(img)[0]* l; ^8 L8 n* a! [" O8 {
existsEncodeingList.append(encode)
! m1 r; D: d- d
) f# s4 {& ^& c5 H" S- R; ]#获取当前存储的人脸编码集合4 E, S- w: o1 `3 \
def findExistsEncodeingList(img_path):" ^7 i2 T/ |7 z& k
images=[]
( M" |5 ^4 a; c9 }& R' _; T! T" H #列出已经上传的所有图片
0 n* }5 G/ {6 l" ~; E t+ P imgList=os.listdir(img_path)
: `- n( R( ^$ J3 P8 [/ S #处理存储的图片得到其人脸编码3 E I7 F9 h/ u1 X' B% f
for pic in imgList:$ ?- E3 |2 Z( e- @6 F8 [
img=cv2.imread('{}/{}'.format(img_path,pic))" l q& C$ V3 z$ t" E$ ]
images.append(img): ] k) e0 k" [- F
classNames.append(os.path.splitext(pic)[0]), R1 X8 Q* X$ D1 \; H. z: E9 p
findEncodeings(images)
8 E# q. g* U! x8 _1 l
% f% b7 T# X" N+ z8 S- ]" L& g#选择并对比图片
4 w) C4 y0 Q( G+ A0 F5 Xdef choosepic():
1 Q. x1 ~; V2 P: m choosepath = tkinter.filedialog.askopenfilename(). B! o1 t: r; |. ~* |% n
path.set(choosepath). i( C& B- R: d
img_open = Image.open(entry.get()).resize((530,750))
: G3 [$ j6 k! v img = ImageTk.PhotoImage(img_open)
. Q: Q& z" K3 G0 g6 d) P lableShowImage.config(image=img)/ Y- V5 {) d( d& e
lableShowImage.image = img7 \6 [4 |2 ~" i g* @
lableShowImage.place(x=30, y=70, width=530, height=750)# ~, g* C+ M" J$ g' {9 V; {8 n
faceRecognition(choosepath)
! \4 }4 M" g5 ?1 R! L8 M1 L! S5 N: o: X
def faceRecognition(choosepath):# ]; U3 L7 [) I1 y; L+ {3 v1 Q
frame=cv2.imread(choosepath)
8 b$ ^( w K5 y frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
' u$ K# l( o. l/ p% i) S0 v #对摄像头读取的检测人脸. B" B; P6 c+ h+ E) w1 h
facesLocate=face_recognition.face_locations(frameRGB)# I4 ~: \ n3 O. V
#进行特征编码
$ Q6 Q: A& e# c( D6 J3 c2 V* {+ p faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)
3 |8 c% S$ g4 J" w #遍历检测的人脸和库中读取的图片进行对比,计算其相似度5 _& [4 f$ h! Y! j/ M: H
name='unknow'; y( P: M. v# O8 p1 n4 C
for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):+ _+ p& L! x9 }- g) b* |$ @. R
#进行匹配) S0 E. u- B, l: d3 ?% i3 J3 F
matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)
) v6 C+ n8 J( l7 h; I/ f+ o' ` i% P0 ^ #计算相似度
w, v: n+ z) J, [% ` distance=face_recognition.face_distance(existsEncodeingList,face_encoding)
2 v" P' B, z6 f% U; D. k* @ lab='unknow'7 b3 y# P4 J1 k/ M/ {) I6 N
for index, item in enumerate(distance):- G+ B, [% e! I' {& m' w
if item<0.5:/ I3 @3 X: I) H9 f) V2 G
if matchs[index]:% x2 c/ f% \* d# k9 [2 b
#得到匹配到的图片名称与相似度值, I1 o- b- P' {7 n, M4 X
lab='name:{}; Similarity:{}'.format(classNames[index],item). o4 v* t- y9 {, Y: V
name=classNames[index]
3 _5 Q4 Q9 u$ f2 g' k break
6 p6 F; q2 H5 n7 S5 M" ` #初始化面部捕捉框显示绿色
2 o2 y* J8 I% `6 p color1 =(0,255,0)8 s# R* ]4 R4 ?$ ^6 f2 g
if name =='unknow':5 F, a& [6 Y8 e3 m. Z! v( x
#未能识别的时候显示蓝色
: i& ]) S3 \9 A' ]( c color1 =(255,0,0)
8 T5 N2 t6 [% w! z1 W" A5 l; i #画面部捕捉框: c1 W, y8 h$ U) t9 Q
cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)! G: h! L5 x7 z
#在捕捉框上添加匹配到的图片信息1 m' s9 k6 \9 t* F
cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)
# @! _1 F6 E' Q- G: d0 L, f cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)' _, v$ f; X6 `; Z" @8 E2 `2 x" h
img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))
; {, l4 R" {% N" _9 l img = ImageTk.PhotoImage(img_Recognition)6 \' ^3 E* Q' ]
lableShowImage2.config(image=img)4 D3 Q( n# }' u% g8 v
lableShowImage2.image = img- b- f; x& m3 F; q: i+ `
lableShowImage2.place(x=630, y=70, width=530, height=750)* x9 V; D. M% S- F# I. z' A+ @
5 e6 H# E! Y- W1 u7 l3 Vif __name__ == '__main__':
' x, o9 M4 C1 V. d findExistsEncodeingList(img_path)
/ \% F8 R+ `' b #生成tk界面 app即主窗口
8 f+ [0 e+ p! } app = tk.Tk()
9 i+ U! E; _7 W, Z- i #修改窗口titile
$ \2 T3 Z* E1 W' }4 z$ v app.title("show pictue")
0 k! z/ p% H8 d #设置主窗口的大小和位置6 Z+ S# N3 v- z/ M- u: p
app.geometry("1200x900+200+50")
, n1 |6 Z' x& X+ [8 O( G4 s #Entry widget which allows displaying simple text.
* @* Y# v6 N; v. ` path = tk.StringVar()
7 J, E" A* E5 b& x8 @: r entry = tk.Entry(app, state='readonly', text=path,width = 100)
3 N$ `- \6 t' W! z7 I$ c! F6 o entry.pack()
0 B8 K+ S4 }$ e9 [ #使用Label显示图片
! x# |7 V" a9 M# x6 {# T. D& ?' k lableShowImage = tk.Label(app)+ P7 e6 [ I4 O* [2 T- r
lableShowImage.pack()3 d& [9 {( M0 k0 P
#使用Label2显示处理后的图片* l3 B& d/ c& s9 n- }& Z
lableShowImage2 = tk.Label(app)
/ W% d6 x* ~8 F/ e8 d, V% W$ B lableShowImage2.pack()
: }2 D' ], x/ E1 g) s #选择图片的按钮0 w2 y Y2 \) P5 p7 h
buttonSelImage = tk.Button(app, text='choose picture', command=choosepic). I" C- u8 A* k1 S+ r. e
buttonSelImage.pack()+ m: h. H$ @, R. S
app.mainloop()
# Z1 }& q% U* h, g9 d3 R0 S8 v( [# I0 d* @: E, {- B
3.说明
! f W+ V" h2 K$ I1 `+ X首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。
$ q2 k7 I% Q9 A& p, W/ C9 n/ G; m9 a3 ]/ s9 E, K% c& U
( a6 ^; V" U+ g, q" s
* V# Q7 M8 f. H2 r* t6 s v- L6 f 其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片
0 s& B( x% I) I2 ?, G( [" E* G6 ]6 S: k' C0 a
" i7 ^1 I- V% I# }
/ q1 @1 W! G/ G2 E) p) f$ @5 P 但是效果会存在色彩的失真,效果如下:
6 P0 n; K( [ f! ?) h( }# _7 D- r p7 I; m
" o+ @ k) H, V
" @( u9 U f; d也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。
9 ]; p4 ]8 j: c. `( F* ]
2 p& N. R( p6 X5 E& S- k3 L+ i! \) H这里简单提下PIL的九种不同图片模式:
3 v$ ?' z+ a% `3 i2 [8 K" z2 W' ?
" r; y* t; J$ ^! q l+ \modes 描述
2 o6 l/ s0 I. A* {( U- T$ D! t9 n1 1位像素,黑和白,存成8位的像素
x: ^% t' H# G, `' NL 8位像素,黑白$ J9 ?- f: z- e9 V
P 8位像素,使用调色板映射到任何其他模式
9 p2 C: q, n" n8 fRGB 3× 8位像素,真彩
; |, m/ D2 Y7 D) R/ U; Z, ^9 B' WRGBA 4×8位像素,真彩+透明通道
* F8 L( Y5 g9 N K9 X( wCMYK 4×8位像素,颜色隔离
* L: |+ t& D( p6 l! _6 Y BYCbCr 3×8位像素,彩色视频格式
/ U6 p( j* p$ c. n* y, m( ?- E9 ^I 32位整型像素8 ] r4 Z2 v. l9 L+ |
F 32位浮点型像素
) ^: p4 F2 i5 e6 I4.实现效果1 @! Y' P$ R. b4 n3 c6 x0 e* O
4 y9 ], z$ n" C) |* t
' w4 l+ F3 {- O! m: w
& [3 q; s8 q% B8 _7 ]+ z8 k. M" P8 {# p1 f; o# d& p
可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。/ W1 m2 y; x5 w" W8 |
————————————————% P& e) y$ F9 D9 g7 k5 [1 b
版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
4 R& G3 z+ ?! J* u原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288
/ {! J3 U- R( t0 O% u$ e4 J) f, l& u& Q- o
) P% A7 y7 W% E, v# R' v
|
zan
|