- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 569639 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 176115
- 相册
- 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实现人脸捕捉与人脸识别(照片对比)
' V+ L& y- ~9 o5 j1 B
" D1 O" r' y: q1.安装包依赖1 Z( O w6 `# Z9 [/ c2 [# d
与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。
8 t1 S6 h5 O; U- k5 v: t3 Y+ u/ E3 f( ^3 F
在python 3以上版本tkinter是环境自带的,所以这里不需要安装
" Z# d4 I/ P4 j0 Y) F2 l( J- D4 y X$ ?. S" b3 k8 E6 @5 W
2.代码示例9 R# c( e2 C9 w9 x f5 R) H
import os
- E7 S. P- O. V) bimport cv2
4 P2 O: Y0 N. |+ X6 bimport numpy as np- T7 Q# g! e9 [! K2 g
import face_recognition4 q" M8 W8 C; e& Y+ ^* a* g, x1 V
import tkinter as tk
- f8 K: L2 {7 ?. N8 [import tkinter.filedialog
% F( v: F0 Q# U) t5 q. Kfrom PIL import Image,ImageTk
! r0 p& E' h# @, x( O& S# U6 t5 n" n6 C- M& J2 b9 C' s: r
classNames=[]
" _/ k7 F* |7 p2 @; Z9 w0 k1 t# kimg_path='Picture'1 t5 L; P6 g" b5 U
img_recognition_path='Recognition'+ L& w! T# K- Z: A) f. }; a9 R
existsEncodeingList=[]$ Y9 G! ^# S3 K0 R1 \: b3 [4 A
#对人脸集合进行编码进行处理( }9 x2 W! Z/ }& ?
def findEncodeings(images):
' m3 y1 K- {, c/ l; p# \/ M for img in images:' V; a! D* p) U
#灰度处理0 ^( i$ f @" W0 r, K
img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)
" d2 ]( P: K* G# Z5 u8 D+ s8 U #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果
( u/ ]& t) [) K% I encode=face_recognition.face_encodings(img)[0]: d6 _' M* n6 ?, R g" D
existsEncodeingList.append(encode)
, k" v: w6 A- O7 q( n; d. M# [
+ o! \3 z$ t+ q- P# k#获取当前存储的人脸编码集合
8 V6 V; R: W2 w: cdef findExistsEncodeingList(img_path):+ O6 s" L" M8 n6 J2 j6 g
images=[]
5 {: [) N2 ^ Q1 V1 ^, C* a9 K #列出已经上传的所有图片) t: T7 e- H( I$ E/ s
imgList=os.listdir(img_path)- ^4 a' P @- Y5 `5 n* ^* _+ f% B% d
#处理存储的图片得到其人脸编码6 w- t. K( P( t, C1 ?% u- i. l0 J
for pic in imgList:
3 e; e& _4 B3 [, o* I t5 @ img=cv2.imread('{}/{}'.format(img_path,pic))
3 \6 `3 v/ @ t images.append(img)
* J$ I3 Z2 I- r6 W( Y4 A classNames.append(os.path.splitext(pic)[0]): _' Y6 H' O$ }! G ~' @
findEncodeings(images)9 ], v' Q2 b( }9 I! \; D
* n4 n `/ w! } C' t* u4 e
#选择并对比图片/ @( h. @- B0 T3 Z# p9 S" [
def choosepic():
+ A8 V$ O V2 E! B choosepath = tkinter.filedialog.askopenfilename()# u9 F& G3 ?) D+ X+ L
path.set(choosepath)
5 F% U& e8 M+ d: C$ W' \: W img_open = Image.open(entry.get()).resize((530,750))
: |1 q3 V- C/ X' {% W img = ImageTk.PhotoImage(img_open)' w5 v5 L3 z; Q3 a1 e
lableShowImage.config(image=img)
# f4 @/ T8 p: B) Y/ Y' x lableShowImage.image = img
$ w1 ^4 h3 Q# [ lableShowImage.place(x=30, y=70, width=530, height=750)/ @5 w& r, R+ I. @5 b: ]
faceRecognition(choosepath)
1 E H7 Q+ D# i+ Z e
, h- X2 D, l/ x3 c( h% gdef faceRecognition(choosepath):. p; K5 T+ w' ?5 x
frame=cv2.imread(choosepath)
K+ \6 d% C- U# j& _6 k. [( U2 [ frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
$ m$ S( Y( N7 d/ v5 t #对摄像头读取的检测人脸
4 Z3 s+ ?& q$ b3 ^ \: \* f: S facesLocate=face_recognition.face_locations(frameRGB)% }1 F s% V g- b, o3 r
#进行特征编码5 ^# ^- m- _ w& ]
faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)( Q5 v2 C) a8 z, a! l+ J) k
#遍历检测的人脸和库中读取的图片进行对比,计算其相似度
9 O- f/ f1 K9 l, x" m' s" \, @ name='unknow'
, ]& X B; K q* x q for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):
: _4 V3 E9 `& d1 k X$ \3 p" l #进行匹配; c7 [3 s6 B- v: l; d6 G5 e6 ~
matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding): b9 Z" P) j: w5 h5 P/ n& ?2 ?6 ~
#计算相似度4 v/ `' T: M9 Y8 }7 A
distance=face_recognition.face_distance(existsEncodeingList,face_encoding)
' t0 y# g. L. L C. q4 T9 s lab='unknow'0 n- ?; G8 \; @
for index, item in enumerate(distance):
4 \/ F( k9 N3 M8 `2 I! Y if item<0.5:8 w3 _) u0 K% v s7 y! V) t8 c2 i
if matchs[index]:
. ~9 `8 S% Y9 K #得到匹配到的图片名称与相似度值
: w9 N/ S9 o4 q5 ^$ R% ` lab='name:{}; Similarity:{}'.format(classNames[index],item)
0 i4 y' v* W# @' h* y6 F name=classNames[index]. R+ j3 D+ X- [; x6 P
break
. v* i' T. }. F, V2 U V+ Y" W7 H* [- w# v #初始化面部捕捉框显示绿色
) Z1 P; }0 D! x; H color1 =(0,255,0)
: n Z1 P; L/ M/ _8 I* D" b3 J if name =='unknow':7 T7 ]* M$ B: m7 ~2 j" y! t/ ]0 K4 P
#未能识别的时候显示蓝色
, x2 G9 Y2 W" l! Y color1 =(255,0,0)
7 j( Z) B: P, R/ j. k #画面部捕捉框( `' {! u( E6 |; b7 \" i
cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3) g/ u9 S; A- z# O. K
#在捕捉框上添加匹配到的图片信息- i# n2 I d( K# o. X3 e7 k! g
cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)
4 H9 i' d+ R# T' u% x# x) Z1 t# X cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)
4 _0 ^$ g* w8 z1 |5 S! S img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))' I+ ]! O2 x a0 X
img = ImageTk.PhotoImage(img_Recognition)1 T3 \( W4 Q b$ o. t
lableShowImage2.config(image=img)
& g" U; H+ N1 W9 _% D lableShowImage2.image = img; Q& k" v, f+ W8 m
lableShowImage2.place(x=630, y=70, width=530, height=750)8 c: W: \& U U7 v! _0 Y- e( L' @
7 g+ t6 V; b3 l" m5 b% bif __name__ == '__main__':
1 d& r3 P) ^1 R( ~0 K' b( p findExistsEncodeingList(img_path)
8 F; C+ S- q, | #生成tk界面 app即主窗口
; ?( u" a) P5 ]4 X! x% n app = tk.Tk()
! P$ D4 c4 F; x; B" [ #修改窗口titile; I1 i) |9 Y9 J8 g! t
app.title("show pictue")
7 A. y( z: @# {! W' Y& s! o- Z #设置主窗口的大小和位置
& e: b- {: D L- Q W* r app.geometry("1200x900+200+50")
7 c0 W# m h3 u1 y( M #Entry widget which allows displaying simple text.' k, N, G$ ^% s6 E- `8 \9 [4 q
path = tk.StringVar()
9 C4 z& e5 @, K6 l! a entry = tk.Entry(app, state='readonly', text=path,width = 100)
$ X- I! G3 u$ N2 B5 H' ` entry.pack()
; e9 ^& s' Z' Q #使用Label显示图片
/ ~5 o( l/ A% j1 m% z. p$ A" m lableShowImage = tk.Label(app)
5 ^/ D+ _, b6 [ lableShowImage.pack()
' O- g# |* e6 @ #使用Label2显示处理后的图片" `# y0 l; c- f8 P
lableShowImage2 = tk.Label(app)
4 y# G- H2 n2 N4 Y4 b4 U6 H L& M' n lableShowImage2.pack()
0 L) y$ {9 m$ ] C #选择图片的按钮' C( ~% b- p5 v& f. M4 }4 e
buttonSelImage = tk.Button(app, text='choose picture', command=choosepic) {5 }1 v: E' ?) _# b+ U0 w
buttonSelImage.pack()
3 I/ G* V* u# w8 E app.mainloop()
. Z6 j8 i/ e# ]3 P( `; i
7 V5 U. X' B4 H3.说明
: p3 i- }) _$ M. h7 k; O首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。
/ K" u1 V: A; N
$ X% G( _) E) S1 x4 {! _/ H7 t" [% q% w0 {) r8 O6 a$ j% |
2 I- a5 l; }1 H+ y. v5 w; E8 @
其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片
/ V* q$ e- J6 N) [1 u! T4 s; X/ S4 Z+ `- t$ B5 c/ F
! Q q! a: G/ \
0 u0 D) c. T8 y0 C4 s3 X 但是效果会存在色彩的失真,效果如下:
! S7 _" D6 U0 W
. P% W, t2 P7 r3 | J0 ]+ J2 |) u2 w3 _$ D. B0 V* m( j6 b3 L& O( f( U
: x# ?( f( J4 |% M
也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。( j; H. f0 r4 ~
' P' v- k- P1 n. ~
这里简单提下PIL的九种不同图片模式: i( \' ?0 J7 o+ g( O
2 J# z# F6 X% | Ymodes 描述 U4 K x3 k. m" x4 x
1 1位像素,黑和白,存成8位的像素
: t- W( w* R9 H- O2 gL 8位像素,黑白
# f9 f$ @" @* y; A* uP 8位像素,使用调色板映射到任何其他模式+ O4 y2 h& ^$ |( X; P% b2 m4 l
RGB 3× 8位像素,真彩
- i6 p) W) I% W; O* G0 [RGBA 4×8位像素,真彩+透明通道5 p9 @3 S! f7 j, }) J
CMYK 4×8位像素,颜色隔离8 X$ Y: K+ {3 }9 {% ]3 z" @
YCbCr 3×8位像素,彩色视频格式
1 d+ Z2 d: p2 t; O0 c- f) eI 32位整型像素! N. p' H* r+ i+ d! X: C4 B
F 32位浮点型像素
( l$ S$ v" E" z7 ?7 M! ?4.实现效果" j; w, U* D( t
( n9 k6 i* p) P# Z# @' w9 t' ~8 Y
3 R2 ?' s$ c3 R) O" x
9 g/ C/ X$ x1 i/ ]% y/ f( _. w( @7 F" `! A5 n
可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。/ E; t8 S4 X5 [, Z! C% d! {
———————————————— _0 {/ W" H! N4 v' z) y7 T+ k
版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
! U% j$ C3 x0 h: a: o$ f+ N1 W原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288
+ D" H8 v; Y+ }# C9 ` j) W
' k/ b/ v: u+ M
) Y; N# J# _' w, Y |
zan
|