- 在线时间
- 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实现人脸捕捉与人脸识别(照片对比)
1 Z& R& t2 O8 p3 p% T$ }& u4 y/ |0 {" M, t* v# C0 [! X+ }5 W4 s
1.安装包依赖
2 e u( R8 l% c- M4 g. w% e与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。& g" |; I }( P; x
, H$ u; f; A! Z0 B
在python 3以上版本tkinter是环境自带的,所以这里不需要安装
' b8 K, z, [) x/ Q( Y! ~: ?6 ]9 n3 t3 x! L# Z
2.代码示例
0 l- [. x* m7 y- G% b% h. Z. t6 jimport os
3 L: g( s5 Q& T2 n1 z2 U/ u; Pimport cv2
! ?# U2 |, ` o8 R, n6 qimport numpy as np
: K7 p8 l- ]/ f3 T" fimport face_recognition. m% `" w) U5 ~, B6 X$ G
import tkinter as tk
" e0 s' `3 t) d* l% S& @7 aimport tkinter.filedialog2 `8 q" ~! m5 N! t& V' Q, D
from PIL import Image,ImageTk ! K: Y/ m) ^0 Y$ N+ z1 S/ R1 g
0 ~4 {: u. m5 L" W* t4 t2 ]
classNames=[]
, K' O1 Z% J$ q9 Y" ~, ^. R- nimg_path='Picture'" b- \6 ^ t) R5 a4 Q
img_recognition_path='Recognition'. n* W! M5 C. H" d1 o
existsEncodeingList=[]
6 h l) J5 c( A) C#对人脸集合进行编码进行处理4 P* l. N' @2 Y; [
def findEncodeings(images):
" D# x4 ~' b) g N0 z4 z) ^! h) } for img in images:
: @. j( L e' f: R3 u2 f #灰度处理
* t7 P9 t z" v2 \* E0 z img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)5 T1 y2 ~4 _- h+ c. e; K
#face_encodings对图片对象a_images进行编码并返回数组0位置编码结果% d6 g: ]) z# }( O$ I# ?& k
encode=face_recognition.face_encodings(img)[0]% ?' s$ L4 _! ?/ v2 O5 j l
existsEncodeingList.append(encode)- ~% l7 `+ c W
S1 {9 C% R: E4 _7 J' j#获取当前存储的人脸编码集合1 N+ t/ _1 N+ j, U9 w7 l$ w
def findExistsEncodeingList(img_path):
' T& s7 H4 |, m1 D1 |& \& b9 v images=[]( [8 y. |- F- n# N5 E1 b/ S
#列出已经上传的所有图片/ j4 v5 o" E" T- C2 @
imgList=os.listdir(img_path); B" U7 c" B2 `: k, h9 M
#处理存储的图片得到其人脸编码
8 W% j# t+ l. q! w \* k for pic in imgList:+ X5 a; A# }& A/ m) B* m
img=cv2.imread('{}/{}'.format(img_path,pic))
0 x: k2 J5 S) A" X* R, s! o images.append(img)/ I, t' x7 l& |) z9 B
classNames.append(os.path.splitext(pic)[0])# Y( T) w5 W& c" X2 W* N: r8 G
findEncodeings(images)
2 {8 q- E' j2 ^1 u7 F. l' j6 L% o' l8 [9 s" A
#选择并对比图片( D9 k4 F- W! C+ N+ J
def choosepic():
/ ^4 v) o$ i L* f, O& Y" o' _6 ~. y choosepath = tkinter.filedialog.askopenfilename()
1 E7 j+ P& c- ~ path.set(choosepath)
/ y) D( h. N/ c img_open = Image.open(entry.get()).resize((530,750))% U( t! B4 {; N) w) Z* H* b
img = ImageTk.PhotoImage(img_open)
O. W, Z; { C2 f/ ?- _+ ^ lableShowImage.config(image=img)3 J' p9 {6 N& l
lableShowImage.image = img
5 H! q3 `( L3 |3 D# P5 R3 z lableShowImage.place(x=30, y=70, width=530, height=750)
2 h5 `1 I& k: n4 R faceRecognition(choosepath)& U n4 R* _0 t
( w/ _( _: K2 Q$ m% W. W. adef faceRecognition(choosepath):
' O9 h" r) a. d. n- Q' [ frame=cv2.imread(choosepath)$ l; R( z( _3 C' {) [: t
frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
8 P' D7 E+ i0 n! Z9 ^, i; {2 x% c #对摄像头读取的检测人脸
2 w4 H2 b( q. e: w _, y3 @ facesLocate=face_recognition.face_locations(frameRGB)
U0 W) {$ R+ a( U! j& r# p #进行特征编码. ]9 g. {2 ?8 ~6 x$ e% W
faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)
( @+ O# t$ @' v c/ h& ` #遍历检测的人脸和库中读取的图片进行对比,计算其相似度9 w! S% |( |1 p( }# h0 w. N
name='unknow'
! b1 ~' S4 _# k1 z for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):; ^) a# H$ c: i: d7 N8 S0 P
#进行匹配 y$ ~8 V$ G0 ^3 W4 l9 b
matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)5 L% r- b- B: O9 N
#计算相似度6 y0 N7 M3 v7 o) F
distance=face_recognition.face_distance(existsEncodeingList,face_encoding)
# q! i- _0 m& O# h0 J lab='unknow'
) j+ G- J- [; a, r: C+ C1 R$ l* w for index, item in enumerate(distance):4 M4 K) v( I8 v/ Y; N
if item<0.5:$ c: D' T' B& z' y8 G
if matchs[index]:
" t4 c+ t% ?* w# B #得到匹配到的图片名称与相似度值6 \* l% a' q6 n: j0 i+ ^
lab='name:{}; Similarity:{}'.format(classNames[index],item)7 ~7 ~* k) x" [" N+ I) N6 I9 W7 t
name=classNames[index]& b1 |9 p+ }6 f# s P
break5 W7 [( X; t2 G5 c- t/ @( O
#初始化面部捕捉框显示绿色5 J1 Z6 O0 h0 o2 ^
color1 =(0,255,0)
: Y8 d5 x4 ?" H7 ^3 ^+ k/ \ ] if name =='unknow':1 g7 D/ x$ n, E1 c/ T# A, u
#未能识别的时候显示蓝色
. r) |, u5 E+ h" h color1 =(255,0,0)
0 k# H5 ?5 r L, F! \) k #画面部捕捉框1 w+ q K9 B, p3 }1 B9 ?( E
cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3): ]2 b9 x0 P5 ~! N8 F0 y3 w3 H
#在捕捉框上添加匹配到的图片信息. R! F# g# M! N! i2 n
cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)% d! b: x: v$ B
cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)6 f' Q9 |; P2 ^8 d/ C( C
img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))+ y% {7 q M, i. A* ^
img = ImageTk.PhotoImage(img_Recognition)1 L8 j- R8 s& B6 F
lableShowImage2.config(image=img)
8 C3 X, f$ Q V' r( U$ ~ lableShowImage2.image = img2 I. p7 Z7 \* h. R
lableShowImage2.place(x=630, y=70, width=530, height=750)8 i7 [6 a2 @% L4 V2 S' f; @) A
" d' A& h7 U5 ~" Q* Rif __name__ == '__main__':+ L- x- A- }+ V A; ^
findExistsEncodeingList(img_path)/ H) H0 C9 ~6 e4 r
#生成tk界面 app即主窗口
, M% D- e/ N+ p/ X( ] app = tk.Tk() , [3 |2 A9 G( P t
#修改窗口titile* O3 S6 a9 m6 `+ L" b/ H0 L7 _
app.title("show pictue")
" v/ p. G) P& } #设置主窗口的大小和位置
# q* n' P) _1 x! O7 W1 ~% t app.geometry("1200x900+200+50")2 E. R* I8 U) H2 q! u$ C/ j v; Y2 R
#Entry widget which allows displaying simple text.
7 d% ]7 q0 ?4 } path = tk.StringVar(), `. S$ T' p7 @, D% M" _
entry = tk.Entry(app, state='readonly', text=path,width = 100); N/ |/ O2 e* m8 ^7 v6 b+ ]
entry.pack() H1 j) e! h! z9 Q) a. |
#使用Label显示图片
6 A/ T3 T; s- X lableShowImage = tk.Label(app)) y) o" A' p6 |+ l) I& n u/ M
lableShowImage.pack()
4 T! x; `1 D. r, X- q1 @0 ` #使用Label2显示处理后的图片
. k z' R+ N1 k. K lableShowImage2 = tk.Label(app)% X7 G: }4 K' z$ ~4 B" Y
lableShowImage2.pack()
0 G a% X. U5 b) Q# `2 K #选择图片的按钮. X( g8 K4 s0 H8 x2 c! {. E
buttonSelImage = tk.Button(app, text='choose picture', command=choosepic), v1 l( L9 \0 C; O, Q k* R+ F
buttonSelImage.pack()! ~- r* n3 l# M0 p$ @" d+ @1 z
app.mainloop(), ~0 R" h1 P( Y- [- l% x
9 b" H- y2 H2 v2 z- g, j3.说明
; F& L" ?0 H0 E' U# N# f首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。
' R/ A2 V/ x1 Q- i R* p7 B7 E" M& j; m- L3 \* t
" L1 w. s- `% L/ e
. Y6 m) n( A: K* r- j 其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片
* R. W; s2 r1 l! `7 E5 f
. |7 j: C4 I2 D! d' D: l/ B( _# e( T8 u4 p- K+ D
8 z3 T: V; l! e, Y" | 但是效果会存在色彩的失真,效果如下:% B, Z/ N c9 S1 S) `7 R
8 b @9 E6 D Z; X" X
) h+ x+ D' ^' E" B1 N& f% t. W
3 m( ~4 D6 N8 j1 Y! p6 T也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。
6 H1 R4 @7 p+ I [" x
2 p1 w8 B! n1 ~3 w% l) t5 q3 ?1 q/ @这里简单提下PIL的九种不同图片模式:
* O* m; u8 ~9 ?, w; C* z" `8 c
* P+ C; I& x. t+ F3 N. [, Hmodes 描述: I. c1 T* ?: q7 z& J( a. C# _
1 1位像素,黑和白,存成8位的像素2 G. b8 r2 X' S0 z r; k
L 8位像素,黑白; e" E% \+ C- o% w9 n: z
P 8位像素,使用调色板映射到任何其他模式4 \0 y2 Y2 f& @8 O1 O; w
RGB 3× 8位像素,真彩
2 }: _' y5 M+ g" j& NRGBA 4×8位像素,真彩+透明通道
/ E7 `" X5 A9 fCMYK 4×8位像素,颜色隔离/ P4 u5 |/ N5 k2 I# Y! B" M r+ n
YCbCr 3×8位像素,彩色视频格式
' [# ^8 ]' E& A) t/ c. jI 32位整型像素3 Z2 q0 f2 k% |5 D- L
F 32位浮点型像素& A5 h! R P9 S0 z5 p, |' P4 O
4.实现效果
7 O4 x; c9 y; G# n7 c
' Y3 r- O/ n6 N6 Z9 W, O4 X% f; n. B5 x' U
- F' p9 `! l1 O. B: M# w$ L
% p$ ?6 U4 j+ X+ [
可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。. a# g. N. T5 V& ^, H$ B B8 m
————————————————
% ]9 e$ W3 X3 @9 a3 j9 O版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。8 p5 I* L6 v' y# W) ~5 j& w
原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288
0 S( r: B9 s$ c! T+ q3 ?9 E% {0 p8 G$ f( [+ E0 x( g
- t- H% R. i! e- T5 U/ T, { _ |
zan
|