- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 563240 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 174195
- 相册
- 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实现人脸捕捉与人脸识别(照片对比)/ p. I3 j# q# q3 A2 i
: s( c3 M& y5 f9 R3 l+ Y$ u1.安装包依赖
5 m: B( D5 x, j+ D7 k与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。! S( f+ a1 @* b
# W1 w6 H* c6 p9 E# [# i
在python 3以上版本tkinter是环境自带的,所以这里不需要安装" M ]7 Y& z6 A+ \
2 a' ~2 J" P' _' [2.代码示例
% j; y+ }0 h4 X" m* Iimport os: \; T6 X- A+ F# h% p
import cv2' b K+ Z! I) _/ j5 Y2 Q5 H, G6 s
import numpy as np# g& G4 b* z8 M) x( B; _! s. Q
import face_recognition/ q% |$ |; |! G; k& I+ M9 B( u
import tkinter as tk - N$ i6 m/ o4 K
import tkinter.filedialog
& G7 Z' M/ X5 H% a5 n( Gfrom PIL import Image,ImageTk : p+ | B5 a! {* [8 V5 r
; ?/ J2 w- a, i' f
classNames=[]
2 D# h4 E z) A+ J+ m; Z* c7 nimg_path='Picture'
" | Z( u4 B' {, U3 G' Eimg_recognition_path='Recognition'& D! N) d' E0 \8 [+ }! ?
existsEncodeingList=[]
" n) b' v+ E% ?6 H c9 c# G#对人脸集合进行编码进行处理2 i# \2 X, @# ^& c: y
def findEncodeings(images):
- q5 \) N8 N& Q8 [+ O: [! { for img in images:
* B* ?4 S8 u) A" p/ [. j #灰度处理
; s$ C" I* Z* ]5 t img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)
& o9 h2 R% b' z, f5 R$ R$ E #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果/ Q6 k& S4 @5 |3 K* T: s* h
encode=face_recognition.face_encodings(img)[0]
1 C6 n) {" z6 Q# e existsEncodeingList.append(encode)+ ^6 y$ I$ j/ Q6 V- A
% \- N9 c0 K$ y2 u0 U#获取当前存储的人脸编码集合
9 L" J9 a' A( w2 K9 pdef findExistsEncodeingList(img_path):/ J. d8 w A/ a
images=[]3 _7 M/ D( Q9 F b: [+ i7 B u
#列出已经上传的所有图片( w, V! s1 ~) r8 g+ ]
imgList=os.listdir(img_path)
) R" H4 g2 M% |% j5 [ l) S& O6 @ #处理存储的图片得到其人脸编码
; B9 G3 s0 a' w. ^) M7 r for pic in imgList:4 }" M+ T Q2 \2 h! j
img=cv2.imread('{}/{}'.format(img_path,pic))
# X! L' t8 f6 N( L7 [. l0 H images.append(img)
& h( C0 k. o. m' j" p; j& l+ N9 T classNames.append(os.path.splitext(pic)[0])
! o- e0 Y9 a1 n5 j% B, L findEncodeings(images)3 r* E: n# G( K5 Z3 q/ d0 S6 ~( y
$ b) X+ l! ^( {4 A( P
#选择并对比图片
* h; F5 ~8 ]2 h& f( x0 V' N4 ~def choosepic():
- `1 K) Z }. `! U( U! W6 a choosepath = tkinter.filedialog.askopenfilename()) M. B$ |; f2 a6 q4 E }/ `# \
path.set(choosepath)2 K/ Z; T) u* j7 R2 J/ G
img_open = Image.open(entry.get()).resize((530,750))
4 _: [, r/ k. a2 C6 d img = ImageTk.PhotoImage(img_open)
- b" Z' \. P' k% {# @/ o' l3 ? lableShowImage.config(image=img)% Y: I+ q% O9 z2 G9 D
lableShowImage.image = img6 _" F& ^4 B8 U k3 k* }
lableShowImage.place(x=30, y=70, width=530, height=750)
J( d, t% m8 g' k faceRecognition(choosepath)
6 C M* }1 g( r' n& b2 w
1 i0 u1 U# A! h% v i2 y ^def faceRecognition(choosepath):
- r1 x: H( e" b" r. r frame=cv2.imread(choosepath)) d5 l! C: x0 i% |1 a! _
frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)- `" q$ P% ?- n8 O6 F! p
#对摄像头读取的检测人脸9 W" a$ p8 A% ^9 f
facesLocate=face_recognition.face_locations(frameRGB)" ]: P- h5 f- D% ^- ]2 ] ~$ ~; m
#进行特征编码5 a1 k) L ~7 `2 B
faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)8 J" E0 R b3 x
#遍历检测的人脸和库中读取的图片进行对比,计算其相似度
* b- H" ^% b. ~1 @ name='unknow'
: B. H3 M7 C& l5 X for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):4 A0 n- f l3 B$ }- u8 k) h, U! W
#进行匹配
, K/ T, f5 ?' M6 t o& a7 |2 R& |; L matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)
( q* h' c2 L+ e' U3 j #计算相似度
# J# j$ o3 J, P* M* B distance=face_recognition.face_distance(existsEncodeingList,face_encoding)+ ~& B! n/ E% C3 h9 h8 ]2 I" h
lab='unknow'
; H8 b) M4 _! W1 u for index, item in enumerate(distance):
9 f4 F0 [6 M* F5 s3 C1 v if item<0.5:
* n6 _% C' W/ m; R, I' o4 _6 A$ P if matchs[index]:
) P" u! ^5 d, s! T, k A t. y #得到匹配到的图片名称与相似度值7 c9 {7 d3 b0 u5 }. O
lab='name:{}; Similarity:{}'.format(classNames[index],item)' i d* k# u- f. U# W% }
name=classNames[index]
: [6 P" ~' d" w break
/ u7 e4 @3 A7 L" G #初始化面部捕捉框显示绿色1 W, z) P' z/ t9 e# P
color1 =(0,255,0)1 s/ y6 h t# k* x
if name =='unknow':
1 R. p8 [& t+ s9 ` #未能识别的时候显示蓝色% b% s" B: W6 ~$ W+ @
color1 =(255,0,0)
! h6 g; y+ x' z5 d6 |7 Y# l* | #画面部捕捉框$ Z1 |% X- y1 `; G4 O
cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)$ A" S) ~) V, y* R, ~, p' ^
#在捕捉框上添加匹配到的图片信息
: F# C/ W, W* C cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)
% ]8 M+ w7 n2 I I9 z) f: t# A) l cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)8 Z; o& i. q) o, Q/ ~# n# [, w
img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))
7 V4 [, B* b7 ~9 U, u# ~ img = ImageTk.PhotoImage(img_Recognition)
+ d7 ` J' m! Q lableShowImage2.config(image=img) m. C7 i) C4 y& }: F+ m
lableShowImage2.image = img
* _3 J4 p( \5 d( P lableShowImage2.place(x=630, y=70, width=530, height=750)
- L9 o7 P. L8 n F
; L& r9 \5 f$ v! _4 H9 Yif __name__ == '__main__':8 R, d7 g" ^) Q. i! w5 \, F+ }8 i
findExistsEncodeingList(img_path)6 R) R( h$ t/ z3 U4 L3 w
#生成tk界面 app即主窗口
/ K7 }6 c+ [2 ]; A ] app = tk.Tk()
A9 o X0 C7 O, a #修改窗口titile
) ?) I, I- d8 |; R- l; N app.title("show pictue")
/ j" c5 C9 B4 N/ [ #设置主窗口的大小和位置
3 F0 Y/ a' J* o8 [% B. |5 i& c% x" l app.geometry("1200x900+200+50")
6 c, F8 Z, J9 v* y. E" `6 S2 g #Entry widget which allows displaying simple text.
9 H, k6 }$ m" N" V' b3 x. ` path = tk.StringVar() Z) h& q& M3 b; H, A* _$ ~
entry = tk.Entry(app, state='readonly', text=path,width = 100)
2 V! G. Q4 d, q2 ~! N# y" P entry.pack()0 c' |+ h! p. H" A
#使用Label显示图片5 a* ~) ]# {" ?- S4 o
lableShowImage = tk.Label(app)
, M) h4 m# [' P: H: v* R lableShowImage.pack()) K4 n0 d i( L$ J4 D: c( x
#使用Label2显示处理后的图片# d/ `9 V1 s/ a/ s8 b4 l
lableShowImage2 = tk.Label(app)- h, g% }7 `3 g' `
lableShowImage2.pack()+ b/ k* d2 x+ l2 {+ C8 _7 ]
#选择图片的按钮, i# |: j0 H9 y) {; j* p' i
buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)
7 B3 H% \$ H& | buttonSelImage.pack()
) G& `4 \( ~: E3 A4 }4 S app.mainloop(); ^. s _+ a; I5 A5 _3 @) Z% k6 e
/ z2 Q w$ S, r: g5 h( \7 i% N- m
3.说明
9 N' L3 ]5 i; D$ J: @, V) L首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。' l% s/ N. L0 `
# R. a7 U5 `2 N3 |5 F9 U
: d9 n5 Z5 ~, X" c1 C. Y4 o# M: \- F6 r5 J- c: h- m
其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片' u0 s6 g u8 N3 T; a+ U
2 h9 W) W+ P/ h; m p* v% K# @1 `
' l8 f. z: \9 L! l) j3 q* n
! O8 p! ~# i9 ^3 y. z) I 但是效果会存在色彩的失真,效果如下:
- F6 E2 N( A) l: l# }6 f; x' a6 D( g+ J; B0 c& p/ A& H
- L) T+ E' e! O6 h0 S( _* _
# m: c3 }& A( p也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。- ]6 k* }6 v& a* q, q
6 V' ~! T) T; y7 k4 \4 Y2 p, ~这里简单提下PIL的九种不同图片模式:$ Y5 k8 B, P( I6 s& D! K. \
8 t% E% P. w& M5 {modes 描述
+ X* u9 k0 a1 i, [8 w$ f! M4 ]& f1 1位像素,黑和白,存成8位的像素' B. D& _4 K$ R7 l
L 8位像素,黑白
& A* j5 s2 k+ {7 l. s HP 8位像素,使用调色板映射到任何其他模式
_8 r0 T' Y* U. n: d& LRGB 3× 8位像素,真彩/ }% e- h% x V
RGBA 4×8位像素,真彩+透明通道
2 _4 f8 |5 B7 Y) Z! S$ ~8 o, d1 GCMYK 4×8位像素,颜色隔离+ C* T; o0 J6 P4 T
YCbCr 3×8位像素,彩色视频格式/ \ f" O. _ U2 ^+ H- v9 N
I 32位整型像素
9 H/ ]) q# W' ^' j2 A* W5 l$ @3 ?F 32位浮点型像素; _8 n+ k9 u& d% q
4.实现效果
( ~) g6 I7 \; O8 f; q# K! X0 d# [& {" x2 k! s7 K* A
2 g6 Z) T- u6 I; [5 U% [, V1 G6 y V; o0 A3 Q
3 a8 O1 k' ^5 D7 d! h+ }5 c' w 可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。- G& P- [& t* l% _) v
————————————————
+ Q- m7 Q& T: L; F/ `版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
. S5 U7 Z/ H" W原文链接:https://blog.csdn.net/qq_17486399/article/details/1266292884 n5 A" J) H) \
! ~, ]7 M) `& W! I6 k0 d% Y% n+ m" r9 }/ o
|
zan
|