- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 565164 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 174772
- 相册
- 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实现人脸捕捉与人脸识别(照片对比)* X- }6 R1 E6 h! D) ~+ Z. B
8 P/ f- L8 h* w4 _+ @' }" q
1.安装包依赖. m/ e/ J: ~+ T; ^% @) X- l6 b
与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。
( q, ]% q' H2 f( U2 }; o; p" q' _( s( @* o9 ]) o9 G
在python 3以上版本tkinter是环境自带的,所以这里不需要安装
$ z0 H+ j2 p+ @8 \) u6 _$ _# f+ Z. G4 R# u# A. ?/ [5 Y) e
2.代码示例
) {% r& P3 {( e5 E, ^import os0 k8 U# {6 R- u5 K, O: T
import cv26 M0 J! c6 Z/ t7 y% q+ X+ Y
import numpy as np+ Q% P6 K2 I& h% O T" |2 a% r8 Z
import face_recognition
# w; _% H6 e5 Z n3 Cimport tkinter as tk
3 P2 L9 O3 N4 b2 vimport tkinter.filedialog* ]) m5 Q: _. S: O+ t8 W
from PIL import Image,ImageTk 5 r1 V& Y0 k4 J4 T3 Q! N( t
, m" I: H4 n# B$ H' b9 }* X3 _% h0 wclassNames=[]/ |" Y3 X# j( N3 S, d
img_path='Picture'
8 z3 p% T. l, D7 Uimg_recognition_path='Recognition'
3 n! v4 h; R1 @; qexistsEncodeingList=[]
Q$ z$ y4 H t5 a8 D9 M& x#对人脸集合进行编码进行处理
, j/ P( X4 y' t3 ?; r/ Qdef findEncodeings(images):% R8 {0 H. x4 W6 p' \
for img in images:
% m- a- n+ ]0 _( v* h& \ #灰度处理
+ \" n0 O& D( Q0 |6 H$ i& q img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)' A( I/ L Y8 l# [
#face_encodings对图片对象a_images进行编码并返回数组0位置编码结果
4 M' t1 S9 ~% b- w/ A- W encode=face_recognition.face_encodings(img)[0]( B1 _8 |) I6 ^" U2 g- Y4 H
existsEncodeingList.append(encode), g5 l. G3 t# B s
1 t. I; L8 v/ x/ T* U
#获取当前存储的人脸编码集合" j7 h! i- @# {/ P
def findExistsEncodeingList(img_path):1 U! w r( A8 V, E: h8 s
images=[]
7 r8 g' Z/ B( U9 H, f( W #列出已经上传的所有图片! S5 t+ k5 q2 s0 W( Y
imgList=os.listdir(img_path)
' a q' z ]9 s2 A) O: H #处理存储的图片得到其人脸编码
# `% c) P2 p3 l# ]' E' H0 g" G for pic in imgList:/ ?, W+ \% w8 W: S( a
img=cv2.imread('{}/{}'.format(img_path,pic))/ A# z* u$ X9 ]6 [; o( q
images.append(img)9 a0 w N3 e6 r) C& B5 f
classNames.append(os.path.splitext(pic)[0])
& Y& j2 E, D+ x) G# M% p0 a0 r findEncodeings(images)4 j$ X0 M5 ]* |- F
+ ?3 _" S8 D2 {8 R6 I* E1 }#选择并对比图片
1 D; O6 S* B3 f* T2 a3 ddef choosepic():
: l: [# _; n) F0 P0 m) j/ O9 ~ choosepath = tkinter.filedialog.askopenfilename()
8 m8 r [6 [8 u: a* D: F9 U) O path.set(choosepath)
; g+ V a# ]! l, y1 m img_open = Image.open(entry.get()).resize((530,750))
( X5 k; _% G8 N" L& y0 Q3 } N img = ImageTk.PhotoImage(img_open)# }0 k- Y- a; a$ i s% v/ A3 ?
lableShowImage.config(image=img)
% p" R2 o8 S+ [ L- c+ |: X lableShowImage.image = img5 v* I% `! n$ _7 D
lableShowImage.place(x=30, y=70, width=530, height=750)) y5 H5 G3 m* C+ C' q
faceRecognition(choosepath)$ \' o: P1 H& j0 @! S/ B
9 a8 Z3 u2 s4 o& Qdef faceRecognition(choosepath):
' I+ g5 \* ^" P! F) C0 n+ |4 | frame=cv2.imread(choosepath)3 g% v3 ]3 D3 z/ ]* ]# v
frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB), M- e) X! ^/ I4 o% e6 p" Z
#对摄像头读取的检测人脸
6 q& Y% Z7 T9 i8 v1 a facesLocate=face_recognition.face_locations(frameRGB)% ~0 ^/ b2 ], @8 Q
#进行特征编码& d6 m) C: H+ X8 T+ Q6 q p1 B
faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)3 |" S! B5 h, d6 N5 R
#遍历检测的人脸和库中读取的图片进行对比,计算其相似度( z; w3 K. F# c, D7 ?. N. K
name='unknow'3 u2 L' s+ ^* t' K" ?4 h+ Z
for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):
2 P; U& i' \3 U: n/ o+ i i, A r# C6 f #进行匹配3 o. J; S1 p2 { P4 b; D
matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)
7 k# \# l- w2 U5 I5 v #计算相似度
9 W8 Q6 F: J: {% ~ distance=face_recognition.face_distance(existsEncodeingList,face_encoding)
" J4 {$ J! o9 a+ o, l lab='unknow', g' F& `) u) O& i" ^
for index, item in enumerate(distance):
, K: r& ]0 U4 v8 P' Z I; s4 Y if item<0.5:: L8 E# O9 f9 `5 B
if matchs[index]:5 E9 h1 h8 \! u
#得到匹配到的图片名称与相似度值
& g& B; t7 j5 h9 K# ` lab='name:{}; Similarity:{}'.format(classNames[index],item)
$ C2 m) {! D2 ` s& |' y" y name=classNames[index] B i% T- {8 k7 ?
break# \3 T0 H; `! o9 [5 ` s
#初始化面部捕捉框显示绿色
& A( g. B9 W4 q color1 =(0,255,0)
1 _2 C+ ^* |1 Q2 Z+ W# D" q' q if name =='unknow':
" x& q0 v) f2 |' Y9 o #未能识别的时候显示蓝色
" ]# G& p" f0 g6 e4 Q. J" Z color1 =(255,0,0)- T3 K3 o$ F/ X' v! C9 y+ A. M8 o
#画面部捕捉框8 }+ L' \4 ?3 F4 q$ y! g; D2 i
cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)" _6 W3 w7 T9 w# @; J
#在捕捉框上添加匹配到的图片信息
0 \, K3 M& _ m% Z! o% k- z6 V cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)
& @3 }7 x, U G" y, B cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)9 x O. x2 p0 p
img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))5 Q/ ?! g4 j1 A) \( z Z! Y; v/ K
img = ImageTk.PhotoImage(img_Recognition)/ W. x; Z( ]; g+ `' @, g: `
lableShowImage2.config(image=img)6 i& c2 B6 |! w3 r
lableShowImage2.image = img. z( v8 ~: s; Q# t
lableShowImage2.place(x=630, y=70, width=530, height=750)- G8 ^0 t( o3 |) J/ G; f
% U. E. y" R) r# cif __name__ == '__main__':( q. S2 i0 A8 X1 t3 ~" W+ z$ Y
findExistsEncodeingList(img_path)
( p8 [& }; |8 ]* s& ]% ?2 } #生成tk界面 app即主窗口+ e9 f# \. ]7 [8 N: y
app = tk.Tk()
5 A4 Y! ~2 S- @5 | #修改窗口titile
3 n) V7 i% U' k' [ t app.title("show pictue") " s: M$ Z- L+ @! r
#设置主窗口的大小和位置; C$ T' ^" G0 Z: q. j7 e# \) k
app.geometry("1200x900+200+50")
) L- ~4 t$ l1 d: g3 M #Entry widget which allows displaying simple text.
* Q. J4 {# N) A path = tk.StringVar()
' L; m" k: g4 {3 _ entry = tk.Entry(app, state='readonly', text=path,width = 100)
' Z' v- F, X" Y2 Y entry.pack()0 A5 r6 a/ X, g' G+ L) t
#使用Label显示图片
! m/ s1 @) x3 d lableShowImage = tk.Label(app)
! _7 z9 t. k: V( x/ _2 z8 M* F8 e lableShowImage.pack()
' {1 M/ [1 s) |( x; D. u z #使用Label2显示处理后的图片
2 f( K1 q( J7 _ lableShowImage2 = tk.Label(app)
3 J# r3 e8 y; G/ W" ]- y lableShowImage2.pack() D$ ]; T1 E0 \9 o+ n
#选择图片的按钮
! @6 s1 O/ _ O9 r& g6 I' d. J! R buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)
9 h9 ^4 c7 }: P5 B2 B buttonSelImage.pack()' U) `# \7 c, ~, o' H
app.mainloop()6 y( p* ~! J9 M, n1 A: V
/ R# c. P. O5 e$ I0 i1 H, J. X3.说明
3 e6 r* s9 y2 p" V6 H$ c$ S) ]首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。: p; T6 m/ E. N% O- M
" s' H0 x+ M' B4 U! g. P
7 `+ K3 D3 {: W) e! f7 m
3 C. y& o& }. |. X8 P9 }+ o$ J 其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片
. {9 ~; m& j0 Q0 i, J4 ^ Q$ v; B6 g. x" S+ }; z
3 y. A! }* F8 U, z z+ B0 i w
- c' n( B& q* A1 u: ]
但是效果会存在色彩的失真,效果如下:
& g. ^" _: w3 x! W7 H
5 G/ ~5 c' q! @* E& n1 D
2 n, D9 v2 q$ b; \4 s* k; E s) G6 D5 w
也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。
' x! o! j$ K" X8 n, n: I+ |+ ?+ M6 z) c/ A+ I4 t. H9 N' M/ `% s
这里简单提下PIL的九种不同图片模式:
; V8 A, E: c, B/ Y* ]. `* o
8 ~% F6 V3 B% c$ y ?* }6 z2 _modes 描述# ?' I) Q& I1 Y+ v
1 1位像素,黑和白,存成8位的像素
# e* x6 Q$ p: P" T' z- b: iL 8位像素,黑白
& n! Q) |0 ~2 U) T8 pP 8位像素,使用调色板映射到任何其他模式: i' f1 o8 M& Q6 h' G7 Q
RGB 3× 8位像素,真彩
; S* D; j" C% M" f0 {0 K, k& QRGBA 4×8位像素,真彩+透明通道
5 x/ A9 H( A1 Y$ n. |+ ~CMYK 4×8位像素,颜色隔离1 @7 h" y0 A; h; o c
YCbCr 3×8位像素,彩色视频格式' M9 y h5 d& b7 G' D% M/ `3 w
I 32位整型像素
4 `3 J: K- p2 I# h* f; A0 F( ]7 d: eF 32位浮点型像素) ?2 R, A" X) e$ I# u* y9 h0 b
4.实现效果; `$ @3 T; c9 F6 {
: w2 q+ \, r- T, @
0 g& w3 B2 {6 Z1 H/ I# k/ d) L+ |) L1 h: b, z) S
" D9 D( K5 p% c3 z2 N, j: e
可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。7 p: [& i5 a3 s
————————————————
. F7 o2 n4 i' Y6 U4 ]版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
/ k( W* x9 S( D5 g原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288/ {, A* [$ `8 v+ e. N# l
8 N$ \! [9 Y7 f9 ~( U7 W5 z4 S7 Y( ?
|
zan
|