- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 566251 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 175098
- 相册
- 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实现人脸捕捉与人脸识别(照片对比)) T4 \" m l2 H: I
, N# P. C: o' @. B" o% L! p; g
1.安装包依赖
; T/ p/ t' k* U; `* H与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。
" s4 I3 \( k# Y8 g% |1 N7 E7 h4 N
$ p O) z& _; ~% E0 v6 G0 Z在python 3以上版本tkinter是环境自带的,所以这里不需要安装. R! E2 ~1 }, ` O) k' A2 d
/ t* V5 ?5 z' w
2.代码示例
+ B# ?9 G) o7 v4 simport os4 l) s8 V) q* y- F5 k
import cv2
( f. `& S- ]; fimport numpy as np
% s5 a! j* h/ B6 M: f+ n0 timport face_recognition
8 e }; K% V. L, x" R! P/ uimport tkinter as tk
$ M3 a M2 D3 g+ {: | Cimport tkinter.filedialog, X+ e( M0 G/ I. {" }' |# X, g+ A
from PIL import Image,ImageTk $ F. ^2 w# N7 M" b* C" l& F: F
( s" m) D% M) q+ `" F+ V6 Z& CclassNames=[]
! @' X- [& f. ~4 l5 kimg_path='Picture'
: o; @( h1 S7 u% d+ F3 fimg_recognition_path='Recognition'
3 }# K! `* _9 q$ HexistsEncodeingList=[]
* v, `' B4 }4 X0 {" ]: a6 `& q: B; j#对人脸集合进行编码进行处理3 I2 \$ ?* [( G, Z' g! R8 u
def findEncodeings(images):: h* z! Y+ C: |3 O" Y0 R1 x
for img in images:9 F. w" ]8 J- Z R: m
#灰度处理
. W s6 H8 P G6 j, S img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)
, \' X) ~- f) Y; z& m% p- D, o7 p #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果 W9 z& I; O* N' n0 J
encode=face_recognition.face_encodings(img)[0]
6 X$ v* n" U8 f" Y. H# ~0 L5 T2 ^ existsEncodeingList.append(encode)% q6 y' H4 L/ G t
- _$ f7 \, K/ H, c) }#获取当前存储的人脸编码集合
3 f2 x( g8 ]! mdef findExistsEncodeingList(img_path):
]5 C7 `/ C* A8 X7 ^6 P images=[]4 }) n0 r) [4 K
#列出已经上传的所有图片& S; R0 K) K' ?8 A' Q% i
imgList=os.listdir(img_path)
# L4 v5 {! u8 z" n* F* E #处理存储的图片得到其人脸编码
* W) B3 v$ n# i! t3 |3 R; g$ F( G for pic in imgList:$ V: y2 {1 y- I) b
img=cv2.imread('{}/{}'.format(img_path,pic))/ I4 I( ]+ X9 N' J8 }/ Z
images.append(img)8 M% \+ `/ @* h( N8 ^8 U( V% \
classNames.append(os.path.splitext(pic)[0])
) t. N- j; I7 ` findEncodeings(images). B" |- _/ U; S A. Q- D8 G! m; Y& Z
4 \5 u, b0 } H& S' M' Y1 k6 [ Y
#选择并对比图片( L6 Y. D* n8 J- s# M2 u
def choosepic():, Z; ~! x. l0 }+ T
choosepath = tkinter.filedialog.askopenfilename(): n, s; `1 l6 A H& i
path.set(choosepath)1 R+ w( ~6 T% d# |
img_open = Image.open(entry.get()).resize((530,750))
6 d: v6 x S( C8 p% N img = ImageTk.PhotoImage(img_open)
, T" F' s6 o Y/ T3 z lableShowImage.config(image=img)
# c; m% m* W$ ?8 V! E3 l lableShowImage.image = img% W# _. {. H e: D5 d3 I, Q
lableShowImage.place(x=30, y=70, width=530, height=750)1 M% S% E' d0 T
faceRecognition(choosepath)
/ e0 S$ E' ] \" [ x5 D7 o
( b& u- B- n! l- P A3 idef faceRecognition(choosepath):
" o9 k1 n) e6 i/ f# ]- y frame=cv2.imread(choosepath)
* t" H$ B6 C# |0 { frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
1 O8 @" w" ~" o# ~ _ #对摄像头读取的检测人脸. A1 |3 ^9 W; ^5 g* l6 ~
facesLocate=face_recognition.face_locations(frameRGB)
5 q% r' T; Y9 H( ]# P #进行特征编码% V3 B, w: S& g6 j( y
faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)+ P' ]8 ]7 }& E5 [$ ^9 ?4 N
#遍历检测的人脸和库中读取的图片进行对比,计算其相似度, ?( ]' @2 W8 P: ^. m
name='unknow'$ b& v/ ]# K* \% D; z4 l2 ^ I
for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):6 y j3 P6 w; _+ t5 b" c4 z
#进行匹配: i, v% U1 i) \$ F/ w
matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)
# U, U$ M, J) a( e1 O( D #计算相似度
% t: Q: ~$ Q7 G% e: Z0 U distance=face_recognition.face_distance(existsEncodeingList,face_encoding)" `, s+ V: o7 V. _
lab='unknow'
) Z* g7 Z9 }; u1 E& l8 p for index, item in enumerate(distance):
' S+ W/ Y, \( W( x' S if item<0.5:$ }+ w; z9 g$ g
if matchs[index]:
+ g( a3 ~1 B8 M+ C, Y) f$ b #得到匹配到的图片名称与相似度值+ u- O' o' P7 t
lab='name:{}; Similarity:{}'.format(classNames[index],item)* C+ [# @; k6 k" i0 K
name=classNames[index]' F, ~, {# S9 r+ J! T( z9 p8 l( z+ W) [( D
break7 i- V7 h' P6 y. l$ w; O6 s
#初始化面部捕捉框显示绿色
+ |# k" A9 s/ F. y" u color1 =(0,255,0)
# u) ?8 [- [! g5 T. q if name =='unknow':
1 o6 H9 b9 ]7 N' `+ W2 i$ b& c7 E #未能识别的时候显示蓝色7 `, i- T; U9 X. l9 L7 s: r1 [
color1 =(255,0,0)
W* ?& k- |1 S6 x: w& G #画面部捕捉框
T9 C- o' q4 [& X) c$ Q. } cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)
r0 A( Q. |3 W3 o( Z #在捕捉框上添加匹配到的图片信息
8 v- s7 I! F; z# ?# B4 S8 A% a+ @ cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2); h! `, M0 B0 f
cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)
! j0 m; C: o( `5 |& B/ j( m img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750)), t: S7 g6 d) I
img = ImageTk.PhotoImage(img_Recognition)
+ e' r @" X4 g9 a lableShowImage2.config(image=img)
4 x) _0 Y7 I4 E- X" ^2 c lableShowImage2.image = img8 P3 I& a' @) y/ M- _3 H
lableShowImage2.place(x=630, y=70, width=530, height=750)
! u2 A. W4 z- D7 b/ a4 V" K- c8 b8 `6 `" R9 a; }6 q. G
if __name__ == '__main__':: ]# d8 f; Z/ v9 G! F1 Q
findExistsEncodeingList(img_path)
6 f9 |; @4 v6 {! a$ j5 k #生成tk界面 app即主窗口
/ R6 {- S1 w: ?: x* ~* [ app = tk.Tk()
" d+ B! F8 x5 e. u' R, O2 z. I #修改窗口titile
# g3 B9 ^7 \6 z } app.title("show pictue") , h b3 N% x/ r, l
#设置主窗口的大小和位置5 }$ P' w; b% V6 f# z8 G0 B4 S( A
app.geometry("1200x900+200+50")9 _! g: E/ n2 K" o
#Entry widget which allows displaying simple text.
+ k7 E C4 V5 Y7 _ path = tk.StringVar()
9 a+ k* B3 ^0 F6 h entry = tk.Entry(app, state='readonly', text=path,width = 100)
8 N+ z3 h4 x# s* m entry.pack()
7 O* f& j3 u/ D, A #使用Label显示图片
7 A4 f7 D9 w4 a- e0 ?& \% A2 U s9 o lableShowImage = tk.Label(app)1 m, W8 X. R3 ?& T7 R
lableShowImage.pack()2 K) ^0 Z1 n6 s6 x7 {: |6 Z/ k6 k# Q: _
#使用Label2显示处理后的图片
, @: f- ]6 u) U lableShowImage2 = tk.Label(app); _5 ~! [- I+ ` o( D
lableShowImage2.pack()
7 R# B/ \% C% G2 k #选择图片的按钮
6 z# a9 N0 R" \5 w buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)7 P( y; K5 \2 Z6 d A5 ~
buttonSelImage.pack(): l$ E4 i5 F" }2 c, N' }
app.mainloop()0 k! l( f. \5 D2 u# w8 |
- w% }4 b) N0 Z3 Z; ?$ j
3.说明, K3 j+ N$ w- R# }( X/ y r
首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。8 `9 s, ]0 _! j# w& y. N* ^
* n7 W+ i" \8 H7 n
1 Y9 N" Y- `' z0 F* r' p$ { R* C7 @
其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片
- D8 @5 K/ J' c1 O' X
( ? n; @4 E! @/ U
! ]$ N+ J5 O; h- k" c' @( f2 p+ @. q9 n. ?% s
但是效果会存在色彩的失真,效果如下:+ Z5 ~: G: O6 B4 G6 i
. |* |" G% t1 k* E( S1 {- v5 m/ g9 x9 X6 M
) b7 o* J" N5 o F5 O" l
也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。* @% W' w2 V* u5 G& C! M9 g
; y& @' U, |) G5 X0 e6 i8 t% n
这里简单提下PIL的九种不同图片模式:
k) t6 F5 ^: t6 M/ q1 G/ G w1 \8 ?# G. f6 B, |' M
modes 描述8 L7 ]/ c: B) j, c' I- F3 h
1 1位像素,黑和白,存成8位的像素
+ S' w0 R6 [* K) L! qL 8位像素,黑白( Z2 J1 Q, c; } M" J9 f
P 8位像素,使用调色板映射到任何其他模式# D. Q: N! y% c Y$ @9 l/ k. g3 q
RGB 3× 8位像素,真彩0 Q: P/ b0 {% d0 b
RGBA 4×8位像素,真彩+透明通道; u( R; L$ X8 z3 v4 A+ e
CMYK 4×8位像素,颜色隔离
6 S" Y) ^, U% Q0 H$ LYCbCr 3×8位像素,彩色视频格式6 p7 K- s) N. H0 P7 M
I 32位整型像素
I. V9 S) D8 B# I: L# W7 Y7 g# V, FF 32位浮点型像素. z! t; X9 ^$ ?, f6 s' g5 y2 @
4.实现效果
( _, W4 p! |0 X- d8 b, _3 ~
3 Q# X0 f0 `3 c" y3 }0 v- X+ V) t2 H e* b* R2 s
& Q) y! ^5 h4 C7 ?, X9 e
( Q/ e6 e j7 @ 可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。
* G! Y9 F- J- s, r9 u p4 a7 v————————————————
6 J, M6 x3 [/ p& Q' p版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
X2 j; |2 K6 ?7 b# s& N原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288
5 s$ @7 } H0 U) t8 b* k# X9 @2 ~
j7 @$ o$ ]9 T( @/ F) X2 S& M* F) G/ y5 m
|
zan
|