- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 564460 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 174561
- 相册
- 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实现人脸捕捉与人脸识别(照片对比), h3 c5 u" t) Q
* V0 m! q t: |" a/ D1.安装包依赖% y6 b5 r+ F" F5 J' `3 {9 [% B
与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。$ N7 u" }2 l! `! w) x: i" x7 ^
- ]6 Z* V1 k4 i7 J8 x& B* n0 |在python 3以上版本tkinter是环境自带的,所以这里不需要安装: u+ x) k1 ~$ ~0 P* ?5 Y- J
( I3 W8 j$ Y0 e I2.代码示例
+ ^9 W1 Y1 i8 r) K- x' yimport os
; S6 M+ v# v9 [import cv2
* g& I8 J# Y3 eimport numpy as np
4 H" b& ]3 ~" H; eimport face_recognition
* A& i. B& ?& a$ Vimport tkinter as tk
x) K) S/ w0 f" r2 r/ aimport tkinter.filedialog5 q4 L( `. |4 `$ u2 C7 p
from PIL import Image,ImageTk ) f. R$ |/ E! r* |1 m5 c
0 H: ]% ?# ?& W& S/ L& i8 D
classNames=[]
' J% D3 J$ R0 U( g& S1 D2 _( Y3 iimg_path='Picture'
3 Q4 b: ~/ X+ Y* u3 [img_recognition_path='Recognition'
$ N" n/ _5 i2 I' ]7 V( iexistsEncodeingList=[]
8 [7 x3 D6 G* b& S6 N( Y# ]9 }#对人脸集合进行编码进行处理
$ G; u) v, | }. ^0 k" O) Ydef findEncodeings(images):
2 @& b+ N6 J! e" ]# j6 V for img in images:2 O9 {) C0 v) o" z T2 F+ ?5 U' J
#灰度处理
. G' _0 s2 G: H# F4 i' R img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)2 `* Q# W. }) U+ h7 t% Z2 q
#face_encodings对图片对象a_images进行编码并返回数组0位置编码结果
, E; u9 o9 o1 n encode=face_recognition.face_encodings(img)[0]
, o/ C+ v8 V; ]+ w existsEncodeingList.append(encode)
( y) q! q) C: x% N6 t- M4 p0 b* A+ P/ n, G ^
#获取当前存储的人脸编码集合0 s! N, m$ ~0 i( k2 ~: B
def findExistsEncodeingList(img_path):% F% `$ f8 \, @6 A9 \
images=[]& O C/ p3 V! F1 c
#列出已经上传的所有图片: l+ U, h! W0 s1 i" f
imgList=os.listdir(img_path)8 J, e Q) J$ ~. S0 Y' T
#处理存储的图片得到其人脸编码
2 {- Z. a$ F& K$ T7 Q" J, H5 R for pic in imgList:) J* G8 c- ?$ y/ I6 m( m
img=cv2.imread('{}/{}'.format(img_path,pic))0 S! p5 T0 p; `7 X: S9 S
images.append(img)
# |/ z2 ~" c/ f classNames.append(os.path.splitext(pic)[0])
8 ]! ?. s* ]1 m findEncodeings(images)
( f0 O# F, p* x5 J* t
2 _& ~9 P3 q; A f) u5 n2 x#选择并对比图片
3 t3 ?9 K9 U& q8 edef choosepic():+ i8 v0 ?6 g. c6 v. A: \
choosepath = tkinter.filedialog.askopenfilename()/ P4 N6 m0 J5 Q/ _6 a7 d
path.set(choosepath), x. T, y; }6 P! [3 e; G$ Z
img_open = Image.open(entry.get()).resize((530,750))
. m# l r* R' G; ~1 L img = ImageTk.PhotoImage(img_open)
( J1 T$ n; d" z2 {4 c4 Q- f lableShowImage.config(image=img)! m3 N6 w9 G8 e' h; ^
lableShowImage.image = img
! N% K+ F0 \( V) q+ k9 y$ X lableShowImage.place(x=30, y=70, width=530, height=750)! B. w' ^: h5 |, H& d
faceRecognition(choosepath)
5 S, J" V- j8 j$ o/ \' D! J% F- \" O' f: l) o) H. P
def faceRecognition(choosepath):; b1 o1 {$ H9 w7 w8 h' O
frame=cv2.imread(choosepath)
: ^1 u" O0 r. r% z$ x6 K6 S' k5 u frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
$ k Y0 [) G& K #对摄像头读取的检测人脸
; [; O; ~/ _; T0 e6 U1 V) Z$ @ facesLocate=face_recognition.face_locations(frameRGB)6 u; R6 d' ?1 e3 e- R- Z- V& ^
#进行特征编码
" n6 s8 K* x% O% e faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)2 s, l9 P, B( ^0 O0 V
#遍历检测的人脸和库中读取的图片进行对比,计算其相似度1 Z" k4 |( |1 \: _8 d
name='unknow') Q* v, e7 _3 [# t
for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):) R4 ]* @8 `; Y4 p0 z6 q9 k
#进行匹配5 R$ Q+ W A2 ~: c; y
matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)
5 W3 D' _: M9 J #计算相似度
) b- s4 G+ U! x. c9 p$ v! J- p5 d distance=face_recognition.face_distance(existsEncodeingList,face_encoding)
$ v8 n Z3 x/ g- @) s) p lab='unknow'3 q% N5 F! k" C; B2 X' l* v
for index, item in enumerate(distance):" F" [7 M& z9 B; y. Q2 }( }& m
if item<0.5:) m, X# ^; @1 N9 P
if matchs[index]:1 T1 \$ e6 g- H. }3 H4 `5 g4 w2 _
#得到匹配到的图片名称与相似度值5 Y; y8 i0 ?2 s) g$ ?9 C
lab='name:{}; Similarity:{}'.format(classNames[index],item)
! |. Y5 Z+ _3 G! a name=classNames[index]
: C* [! v6 j% P. M( a break
' y) j* F% n/ m6 _. k. U #初始化面部捕捉框显示绿色
" r+ c4 J, _ v- K color1 =(0,255,0)& ^: X. v% m6 ?* D- q( l
if name =='unknow':* u8 d; ^; r+ e4 i
#未能识别的时候显示蓝色! i6 _. C# k8 W; Q( c
color1 =(255,0,0)
/ J6 f3 U- d1 G8 h6 U( ? #画面部捕捉框 h" W- o( Z, q4 w, F! G2 N
cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)
1 A' A6 [3 }3 F9 b- b #在捕捉框上添加匹配到的图片信息 O# \3 w+ ~% } t5 F% z- c y
cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)4 I) Z0 d3 J* A: {2 q) |9 W$ A
cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)
' I1 c; e. H& U. H2 p; ~7 I$ C img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))
7 {, g3 I" R4 w5 @8 L img = ImageTk.PhotoImage(img_Recognition)
3 o6 n9 \" z4 W) a0 W2 U; {9 x n lableShowImage2.config(image=img)
% o4 R0 C( Z1 e: a' d lableShowImage2.image = img: Z7 i1 t1 x! n& h) b7 u
lableShowImage2.place(x=630, y=70, width=530, height=750)
* `6 a3 d, O9 ^: |0 p5 e( @+ m4 R1 l& J; K1 E- F
if __name__ == '__main__':0 k" ?! t- i1 @
findExistsEncodeingList(img_path)- \/ W5 p" t/ P% W
#生成tk界面 app即主窗口
* L8 Q7 I- H4 V" z' u! B- p& g9 N app = tk.Tk() 1 p4 Q5 q, k6 W& q: i8 l/ g7 f
#修改窗口titile8 R! \9 m4 W/ q
app.title("show pictue")
" F8 r" m0 K! ~7 s #设置主窗口的大小和位置/ H0 t5 \, b6 W3 n3 R
app.geometry("1200x900+200+50")
; N: V. v2 n2 D #Entry widget which allows displaying simple text.+ j; z& P& S! k1 X
path = tk.StringVar() k( n3 M& J a0 n+ D% F
entry = tk.Entry(app, state='readonly', text=path,width = 100)8 X5 d8 K' P4 \* g' l4 ?
entry.pack()8 s! _6 @& m2 D* ~# O/ N2 T
#使用Label显示图片6 k: ?! @5 j2 p/ {' P! F: T
lableShowImage = tk.Label(app)7 t5 J, t3 X) z3 r
lableShowImage.pack()! Q) u2 t! r* S. `- {
#使用Label2显示处理后的图片+ a5 Q5 B8 b# j& `( z8 n
lableShowImage2 = tk.Label(app)
1 T* B) W6 j; {! K! |- f' N lableShowImage2.pack() l3 N. g8 r, E; Y/ T; O. I
#选择图片的按钮4 Y% ^5 ?6 I: S! v3 Q! O( I
buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)9 f0 n4 H4 x5 b8 Q/ c" K& o
buttonSelImage.pack()# d5 ~+ i; v, ^" [
app.mainloop()5 ~9 `: ?. z; E
. x: I3 @3 ^, [0 w+ m1 q3.说明) t: p- w% o; Y7 G- k. R& M2 Y
首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。$ Z: n' [; N t& _9 E
7 S( R) [# B/ Z) o* I9 |; x* D7 @* b8 Y* O, y* m
$ r$ ]: Z7 P b: @2 _# h3 {; J9 B
其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片7 T' s& N( R# x) j% V( J
& d3 X7 l) h: E. o& V
8 \! p2 x$ l/ H3 v: H& U
/ t, V/ J3 l T& l+ ]. B1 N$ L 但是效果会存在色彩的失真,效果如下:
# V2 L; q/ X y' m( x* d9 X+ B5 X+ t; e" L6 _" B( J3 {
& ]- P# E8 A/ \) j2 i: |/ {, ^- v9 @3 Q0 I# U) Y
也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。
' V' H( I% u7 i
, f [2 t/ H" y# D8 K这里简单提下PIL的九种不同图片模式:
- m, ^9 g/ @1 P, l- v, |) c+ g) G3 X, w* Y9 Y* I ?- i& \1 B
modes 描述 Y! O5 B9 ^2 j N0 A$ v
1 1位像素,黑和白,存成8位的像素
% p: T7 |0 j" ]0 D Q6 eL 8位像素,黑白) ~1 _% z" ] v& w+ M' q
P 8位像素,使用调色板映射到任何其他模式
: F! D) d2 b4 x/ bRGB 3× 8位像素,真彩
$ K5 z" z9 M% P3 G. P, f; zRGBA 4×8位像素,真彩+透明通道0 m+ ]" H$ y- v3 z& G) }. {2 A
CMYK 4×8位像素,颜色隔离
/ S$ k2 C! M/ n$ J5 n, B3 K0 YYCbCr 3×8位像素,彩色视频格式. z0 v& ]$ s" x& [# B
I 32位整型像素
$ m0 u( Y3 f$ uF 32位浮点型像素- b- }( o8 r _* W2 d4 h2 _4 b
4.实现效果
1 a+ c) ~; G' h7 E* [, k& ?* ?6 l
0 u9 C$ H% A" y' w& K' r
4 l6 r; Y \ b: C* |" e* q
) K1 X6 g- G- {2 W; f6 c2 g3 h: r& W7 {" l! |8 |6 @
可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。
& X, t$ P6 y |4 c4 D- h$ U————————————————
9 U* t, I; m! i2 ?% W* ?8 \1 }版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
: R e$ d# c b2 _原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288
$ S6 L) k5 i+ P' O* ^0 n1 A1 |: o4 e% D4 d+ d7 R1 A' O- M5 K
/ @( C0 f0 V2 e5 e; O
|
zan
|