- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 566440 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 175155
- 相册
- 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实现人脸捕捉与人脸识别(照片对比): C" A6 F* K7 c6 P) w6 Y6 M+ K
, J9 t- y& P" n6 B, x7 {
1.安装包依赖
2 C7 a* v2 r) I J3 {6 G与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。
4 d" c8 J# @# B8 |' h: U4 h% k1 @
在python 3以上版本tkinter是环境自带的,所以这里不需要安装, U: |$ D: {; o, X' }& n+ x
+ L7 N6 Z0 h0 l! i3 [' ?' b4 s5 ?
2.代码示例
! x: k# ~6 V. ]% c8 Simport os/ r- h7 G1 D: v O2 {/ Z! u
import cv26 Z' X; E9 q8 }% J' h9 H
import numpy as np
/ C5 t3 u* b. ]4 nimport face_recognition
( {& v3 q& F c, o& r' Gimport tkinter as tk
3 t7 q6 |0 I4 V2 simport tkinter.filedialog8 f2 G7 I; @ t+ y, t( d4 x! D
from PIL import Image,ImageTk
9 `. P! Q! _9 @% y* h- I' S+ n4 h- B) l1 C/ A" K
classNames=[]
7 D" N4 [* c/ C, L/ d# ~0 gimg_path='Picture'
; G: ^) G2 [9 q7 r" ?img_recognition_path='Recognition'( r3 C0 i$ N; K4 \
existsEncodeingList=[], c& |/ v' C/ B! Z4 _( r
#对人脸集合进行编码进行处理9 b' s6 y4 y( p5 m9 c: e% J. @
def findEncodeings(images):
) T. n- m& W I9 b: R: X for img in images:
# G c& P$ v, } N' L #灰度处理
- E% M! A" [+ J; T6 b' N img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)+ U4 T0 S* t) f6 z
#face_encodings对图片对象a_images进行编码并返回数组0位置编码结果& {4 W( v6 L7 H
encode=face_recognition.face_encodings(img)[0], y9 A# h4 O' D4 i- e0 j& @! G
existsEncodeingList.append(encode)& T$ m! R* j9 g% J% b
# `# j9 w; ^" o3 ]#获取当前存储的人脸编码集合 z4 U' A& G0 b9 D- h
def findExistsEncodeingList(img_path):
1 f$ x. B3 k- T+ a* ^" q7 ? images=[]
. ?5 W- X5 M% T) @, _4 k #列出已经上传的所有图片* G6 |, B5 Z. u! N
imgList=os.listdir(img_path)
$ m9 g5 d+ l8 V7 S" P" I #处理存储的图片得到其人脸编码
7 h3 F0 u d' D' i) }& E) R: T for pic in imgList:
: R4 F9 a, P _+ w( S$ @9 ~ img=cv2.imread('{}/{}'.format(img_path,pic))
7 H) A, D3 t, l+ Q7 \: m images.append(img)
/ V$ g, M# H: U% X2 ~9 ]. P5 U/ y( E classNames.append(os.path.splitext(pic)[0])
# F- E: m: ~4 Y$ e& i findEncodeings(images)
9 V+ Q: M- B- I, Q; X+ w0 D) I. Q/ k8 N& i* Q
#选择并对比图片
# }- W0 U; _1 D6 sdef choosepic():
4 w' l6 R7 E5 R0 }, ^" o choosepath = tkinter.filedialog.askopenfilename()9 i; u9 W' g- E$ K v" X5 ?% t1 b+ z( {% C
path.set(choosepath). j Y+ u/ {- k3 O" O" G
img_open = Image.open(entry.get()).resize((530,750))) c1 p$ H6 C+ Q
img = ImageTk.PhotoImage(img_open)" W8 L3 U) I! e2 k: p
lableShowImage.config(image=img)1 z7 q0 {1 V; a' u* D5 k( k
lableShowImage.image = img
5 X5 t' J1 n4 _ lableShowImage.place(x=30, y=70, width=530, height=750)
' m% w2 B' U2 ?1 |" G8 k faceRecognition(choosepath)$ y! t, V# I1 y1 |6 a# M
6 Z+ K% \: K. {2 V4 _8 p' gdef faceRecognition(choosepath):6 Y( q0 z( \4 M% @* L) J8 X- |# N
frame=cv2.imread(choosepath)4 f3 G. I+ C# n& n+ \2 _2 [
frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)$ _7 H* G6 }: {' Z
#对摄像头读取的检测人脸& d( r" n S; E) l$ m" _
facesLocate=face_recognition.face_locations(frameRGB)) o0 g% a, X% j. K6 w r- ^
#进行特征编码, S! Y: t* o) J6 y7 z8 c8 ^6 [
faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)9 d. m2 ^9 S2 p. k. Q
#遍历检测的人脸和库中读取的图片进行对比,计算其相似度' ^& X- n( U8 ?, F/ j/ @ h& N1 E
name='unknow'9 D. f! K! f& a8 J3 U
for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):
4 O v% }. m+ s. }6 P #进行匹配
" o: |* m' I7 u; `7 a matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding). | K+ K5 l- i; s# _9 E
#计算相似度% t( L. F/ u' h: D8 _8 V
distance=face_recognition.face_distance(existsEncodeingList,face_encoding)
; Q3 E0 y& ~; T+ U( a% }3 _- s# L lab='unknow'! |) F! |& H { a, J
for index, item in enumerate(distance):
8 `' a t3 _8 O( R2 } z. f( S if item<0.5:
: X+ S8 a- n3 R* A4 s if matchs[index]:7 i5 F" x* d$ L
#得到匹配到的图片名称与相似度值3 s' h: l7 I. V
lab='name:{}; Similarity:{}'.format(classNames[index],item)7 I2 n% E+ O2 L
name=classNames[index]+ \8 u* L# L* |6 k p/ D/ ~1 x; e$ C
break
; }9 U/ I' {7 ]9 B1 H% |( H #初始化面部捕捉框显示绿色0 T! L9 z! ^- L2 W
color1 =(0,255,0) m' e: h; w4 ^9 W# Z
if name =='unknow':
. A; F0 c% `9 F' C- s" s #未能识别的时候显示蓝色
! g' n; J4 L* y8 s/ M color1 =(255,0,0)
+ `$ L ?6 e! x! y( m, @ #画面部捕捉框, c0 _: f Q$ B# R
cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)! n7 r* G: o/ i V
#在捕捉框上添加匹配到的图片信息. @0 y V) ~. i) g# c6 Q+ j
cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)* X# j, X7 z ?# X1 h6 f% E0 V
cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)
& m6 [% e' o- W img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))5 A; Z8 V$ x" U+ R$ ?3 @
img = ImageTk.PhotoImage(img_Recognition)# @! |: V+ e. ^2 C& F$ B! h# w2 S
lableShowImage2.config(image=img)
6 B, N u1 L& v z9 j lableShowImage2.image = img" t- F S" J6 p- N
lableShowImage2.place(x=630, y=70, width=530, height=750)
3 \% d( o4 \- |' ]- U% p: H9 ~8 `! U" P- w; C, ^3 M7 S1 W
if __name__ == '__main__':
- L! K! U/ Z! Q: y2 J8 R findExistsEncodeingList(img_path)6 P+ d1 y' q+ G$ P. f
#生成tk界面 app即主窗口7 z$ o3 z& h3 b- ~/ ^# `
app = tk.Tk()
4 G) D0 X2 s5 N2 A" j7 Y) S #修改窗口titile! ^) J6 `- ?+ o9 ~& y
app.title("show pictue") 9 w/ [7 Q3 z6 c2 \9 V1 |
#设置主窗口的大小和位置
$ a% a0 e; P- u! }' d app.geometry("1200x900+200+50")8 U" l6 U" P4 `# D$ c$ N
#Entry widget which allows displaying simple text.
: g# z6 o5 I) n$ @% C' Y2 Y H5 y: | path = tk.StringVar()
( \1 x; R. w2 T entry = tk.Entry(app, state='readonly', text=path,width = 100)
1 g- q8 `) ]% q1 z$ ~" q2 ~ entry.pack()
( a/ C) I6 ~# K7 t5 ?' a #使用Label显示图片
( s" K) r% O, u$ \! w lableShowImage = tk.Label(app)8 a2 O9 L& Y( b; W6 S3 W
lableShowImage.pack()
/ d; W7 Q! U* }, m& A2 g1 _ #使用Label2显示处理后的图片3 u2 d- W2 h! Q" Q
lableShowImage2 = tk.Label(app): l4 e, ~: ]2 J6 ]2 f4 M* m0 m
lableShowImage2.pack()
9 I. l1 c& L/ h! L2 G #选择图片的按钮
5 N3 j$ X$ N1 I/ A7 _ buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)8 Z4 J- y) \3 h
buttonSelImage.pack()& h6 h+ o6 g+ v
app.mainloop()$ I7 G- t$ F( V3 I8 T, c) y5 B6 k1 I
7 C, L5 X; t6 U; \3 n; q3.说明' O4 P$ q- P) r- v0 `4 s: I8 X
首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。
, g* C7 Q" ?# p4 z8 j
5 G3 g- V# p! \* H8 W5 G8 e+ B+ W# e: T6 Z3 d
! y- E0 B/ Y1 o a0 ~6 ~" y! y 其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片
$ A+ v A1 j+ G7 V% i9 V' A5 B7 y! l5 u2 v; T5 M# z% ~3 x3 j
9 L& a' r8 ?: Q5 T1 v8 ]; q
% e S; v: a3 L6 v1 z$ } 但是效果会存在色彩的失真,效果如下:/ ~) q8 ~% X# O" q7 @6 s
; f; Q ]4 K: d
: E" A0 ]. S% f- d& y! C
9 M) M* {4 ^& y# p5 } i也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。* K) W3 [2 g, V* T/ O# v' _
5 U8 P: R( A2 a这里简单提下PIL的九种不同图片模式:, U/ d9 M( q5 q
" V( \& X3 X6 p; F) e$ `( j% Wmodes 描述
: V( Y( E. C! u1 1位像素,黑和白,存成8位的像素
1 t+ B3 [" y% s& V4 L @( tL 8位像素,黑白0 ?4 s, D m) M: [
P 8位像素,使用调色板映射到任何其他模式
* s* `- y) ~' @8 Z pRGB 3× 8位像素,真彩. M4 ]* [8 U, w5 ~5 f, |
RGBA 4×8位像素,真彩+透明通道
9 Q1 X0 k# U4 [& W: M. a/ {CMYK 4×8位像素,颜色隔离
5 d3 |9 c# a1 z4 R: D Q7 |YCbCr 3×8位像素,彩色视频格式
& L u4 N% q. _; _! z8 oI 32位整型像素
* A! ~0 Y; U; x5 g+ x- Q) FF 32位浮点型像素
3 \6 I4 Z) h; G2 b* K8 n4.实现效果' `$ I/ C" i( ^/ l" l- M
' Y) T9 V+ T- A2 E( {! U4 P1 } q
6 P; t3 }, o% Q) t, @, {
( J7 ~5 L9 U- r3 M/ e6 @( W/ L6 O) S! T' G- f2 p* [. Z
可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。. \& p u" }5 u: m$ }8 I5 |
————————————————
2 N$ C% i0 V8 K" `0 H3 q版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
& A2 F* G# m/ v8 w原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288$ g% w6 r3 F, u+ z4 j5 B9 J2 G0 Q
( P- g# k) ]$ n1 ]# u
1 X1 ?3 J, H8 ]- ^ |
zan
|