- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 565163 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 174772
- 相册
- 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实现人脸捕捉与人脸识别(照片对比)
7 F! ?1 b& m) H' g7 L
' _: a' r6 [( b' j- N1.安装包依赖
3 n% P- k0 A" E# I! Z# y2 c与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。7 P: z7 D2 ?+ Y# p, b; Z$ V
7 r! n! `5 M, [. j8 t0 U9 v2 ^' B: V
在python 3以上版本tkinter是环境自带的,所以这里不需要安装0 }$ I& I& m( {: g8 Z
4 g" E1 i; ~! c; m; ~' A) ^2.代码示例/ c; J& ]" T0 P, j' c
import os$ P# V$ v# q x. x. I, v7 h
import cv2' M7 m0 Y' m) y4 i
import numpy as np* P5 Y2 }: d% I$ e
import face_recognition; Z4 ?7 v9 @8 @1 ^ k) e; V! N, R
import tkinter as tk
& [+ z+ o/ I! O; L$ @0 a }; Yimport tkinter.filedialog# A' k0 k- z: E' o S
from PIL import Image,ImageTk : q9 r& e2 _* R4 T h$ ^6 N
* y; w- ?# V6 W: \* u. k( Y0 M
classNames=[]& R( w; C( {- ~5 w. Y
img_path='Picture'% p: K$ i1 G3 U
img_recognition_path='Recognition'
+ S, n# A8 I5 d9 o7 c3 o @existsEncodeingList=[]
" u' i" E F' ~' q. d0 U#对人脸集合进行编码进行处理( w. n$ q2 U4 y# q/ f
def findEncodeings(images):
: s- Q: ?/ V4 ] for img in images:0 n) ]9 K. R# _ X! O: m4 }
#灰度处理
. d$ v( e6 n4 \! W img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)
) P- h: F/ d c9 L3 m/ ]: p #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果
. g- x1 j7 K6 M' r a encode=face_recognition.face_encodings(img)[0]: J1 p- Y1 d0 s" ?9 Z$ o
existsEncodeingList.append(encode)
; k! K+ O) ?: r/ i3 {1 v0 n$ ^6 h7 ?/ [- z0 d; q6 A _
#获取当前存储的人脸编码集合
, c4 A0 e- }( \def findExistsEncodeingList(img_path):
7 M, O3 N) `9 K6 j) g1 t; |4 b9 \ images=[]7 o$ I- Z( I0 Q$ f2 E
#列出已经上传的所有图片 l$ R& D$ v6 w" ^1 ^! L
imgList=os.listdir(img_path)
+ o. ]7 Y+ ^/ W6 x, y7 z2 X+ d #处理存储的图片得到其人脸编码' G# }( u. Y$ ?0 Y6 {
for pic in imgList:
6 i: B3 z( G4 w$ B# O img=cv2.imread('{}/{}'.format(img_path,pic))9 x) B. z; o; c f' p4 J
images.append(img) X) _( @! t+ h* Z
classNames.append(os.path.splitext(pic)[0])
; w- X! S+ t. h8 I8 W" z8 F findEncodeings(images)
! ^; {( B% |2 i+ z2 e/ t: l' _7 x6 ^( `( k
#选择并对比图片
! b9 L1 q# y2 udef choosepic(): ~ N7 D. r7 c
choosepath = tkinter.filedialog.askopenfilename()
/ B ]. P& b4 Q, A6 S& S: }# t7 b path.set(choosepath)
( S+ f6 b- t5 X) j/ x img_open = Image.open(entry.get()).resize((530,750))
( }' \# f5 R9 V, g# w) t; t img = ImageTk.PhotoImage(img_open)/ k1 I: }7 H3 q9 Z# A( }
lableShowImage.config(image=img)
7 x6 M/ z/ U4 j1 s) q$ f' R n lableShowImage.image = img$ s9 r; H2 o" S9 }$ G* r
lableShowImage.place(x=30, y=70, width=530, height=750)7 k1 Y; X2 v Z) y' L5 J# \
faceRecognition(choosepath)& @/ R5 D- D3 D1 S4 O, U
% ]9 j+ s: l4 \
def faceRecognition(choosepath):2 D* g( K- ]2 I: B. _4 N
frame=cv2.imread(choosepath)2 y, h6 u1 s2 A
frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)6 @' Z0 I; V/ c1 c$ s
#对摄像头读取的检测人脸) d& k; n# T+ F
facesLocate=face_recognition.face_locations(frameRGB)& o0 a3 p9 B7 q% b; X, L8 t8 u# N; Q
#进行特征编码
# V" G; @4 X/ q faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)& f$ I4 o" o" Y) c6 R& C
#遍历检测的人脸和库中读取的图片进行对比,计算其相似度
: T5 @: o0 e6 e$ H name='unknow'3 C! K, P u& @! W- r d
for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):
7 z0 G$ x. i2 r4 z8 W' c4 ?8 J #进行匹配
/ n1 O. b; R2 [, U9 V: F, C7 d matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)
8 I2 G" |" o" \; z #计算相似度
# {+ E; }# n( g$ h1 _" u. |3 F1 M distance=face_recognition.face_distance(existsEncodeingList,face_encoding)
# n2 C/ H: w }3 j lab='unknow'
7 e# q' S% x! C, q0 B8 Y6 K for index, item in enumerate(distance):0 c$ N+ l# o, U0 s6 f% n( P9 O% ?9 V
if item<0.5:
& Y9 y9 k. _5 x, l8 Q/ S; ] if matchs[index]:! A6 f+ w1 T( V- E% M2 `) n
#得到匹配到的图片名称与相似度值
; n. ?! v+ q! w r8 w* \: q lab='name:{}; Similarity:{}'.format(classNames[index],item)- j% v2 G- j; U8 a
name=classNames[index]
# J0 J/ [) G4 N" f5 f7 f2 u break! n% B( p# o# V2 H/ k
#初始化面部捕捉框显示绿色
" R! Q# x8 o& ~/ | color1 =(0,255,0)
6 r& r, c! Q( @ if name =='unknow': L W, D/ L, ]9 P
#未能识别的时候显示蓝色
; e$ O. X# T$ U X& l color1 =(255,0,0)
i% p7 X% h1 O" J1 s #画面部捕捉框
: L8 L" X9 q8 r' L% a. l6 { cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)
1 ?* c' \% j/ Y2 z+ U #在捕捉框上添加匹配到的图片信息0 T$ D# f$ a! i; v1 |! }
cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)
( G8 Y4 r' u" j0 W cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame) W+ [ j4 k6 t- g* ~
img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))
2 a' ]3 ~9 r+ G. B* W. A+ I- {6 V img = ImageTk.PhotoImage(img_Recognition)
( S. n6 [2 Z& R2 h! x3 l/ s lableShowImage2.config(image=img)" M" F' M6 F/ p0 p2 U% B
lableShowImage2.image = img
/ h6 \/ O4 G1 G+ `/ ^ lableShowImage2.place(x=630, y=70, width=530, height=750)9 c7 m( x$ R2 u5 w8 ^
2 G! p7 f/ F/ R- W% \4 }; X# s3 z+ i
if __name__ == '__main__':
3 E6 }! p3 q3 j& x( {6 P; y findExistsEncodeingList(img_path)) |# z5 E: ~2 U
#生成tk界面 app即主窗口
2 i2 r; p: ^% [6 n) q app = tk.Tk()
4 q0 o* Z* q) ?# {5 r #修改窗口titile
7 ?6 X- H1 ~) z6 ]3 ]% S+ T app.title("show pictue")
) o e% t5 z. s0 \0 E* j) J/ } #设置主窗口的大小和位置$ D( u1 p8 D' Q2 R
app.geometry("1200x900+200+50")
% A! L) S$ ]: ^9 G4 E4 | #Entry widget which allows displaying simple text., s P3 {, ~/ o3 W @8 b
path = tk.StringVar()
5 m$ r* e' z, @; W entry = tk.Entry(app, state='readonly', text=path,width = 100)
' \5 u9 D: m. L. j" h6 v) | entry.pack()0 R$ t$ b4 d3 }/ ?; Y
#使用Label显示图片$ \. {& U( i1 V$ o7 p2 f4 D( h. }
lableShowImage = tk.Label(app), y# j# \% \ B A* `) ^* t
lableShowImage.pack()
3 o/ {8 Q, H" A4 X+ w #使用Label2显示处理后的图片2 C5 O0 {& d$ z, P) `$ u
lableShowImage2 = tk.Label(app)8 R7 H7 G) D1 z% i
lableShowImage2.pack()7 t5 c/ N" j8 g" v" B, |' x
#选择图片的按钮
2 C6 I* l) F! s4 h6 j buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)$ o! C5 H) N1 R2 @
buttonSelImage.pack()
9 g- \( \' X+ _) y. B app.mainloop()
U* @' m: y/ A- f4 S. f4 f, @( c
% W6 F5 p: p# H' g) ~ h! K" |2 N3.说明
7 ^2 H. ~! o4 u. d首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。
7 D( ]: ~# d8 e- Z F/ A$ }3 b; D0 [1 S' ?1 B
: }1 Z H( ?0 O
, p" ]# @$ l( e' y 其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片
' u" N7 f9 a3 [2 S. @# O
" i; g: s! f8 t. B' z1 o5 n9 q" `
+ e4 R& C+ l- m8 M: _, B
8 Z7 r9 r, X( i+ ~+ Z, K 但是效果会存在色彩的失真,效果如下:" }9 O" a( c# j; s
7 ]/ }* U$ C+ x: s3 ^/ F+ t
& r% |2 R, V7 M5 E1 q6 @
( K! M" w# }( @9 a2 c# Z% T
也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。2 [6 D ~4 @3 L5 [* K
& y7 z- l h" @- w& S这里简单提下PIL的九种不同图片模式:* M4 T! J3 m3 L, p2 T$ b
) s* ^9 q) @* k1 O# S
modes 描述
3 ]3 L. O1 j% n& ?4 u5 j1 1位像素,黑和白,存成8位的像素
# m' Q6 d. ]; \& wL 8位像素,黑白( ?1 `' e8 @+ h! U5 ]2 n
P 8位像素,使用调色板映射到任何其他模式$ A# k' c" o1 o3 @0 n1 A
RGB 3× 8位像素,真彩
7 @9 ~) P3 ]" z3 BRGBA 4×8位像素,真彩+透明通道. a6 L: R9 S! [0 j
CMYK 4×8位像素,颜色隔离
2 ]# u* ^' k, K& z/ s' O. i6 HYCbCr 3×8位像素,彩色视频格式, l' [$ ?& F( c( _- s
I 32位整型像素4 m/ r; ~9 Q" S$ U3 m1 v; `: m& t9 R
F 32位浮点型像素1 x/ G _# B# Y9 x. d! q: L
4.实现效果" H# R( _7 J, l' p9 k# _/ B7 P
: Q, ^$ u/ L# P5 @; f
. D y* p8 K1 \6 N F% w
) e! g' z& ]" z
: Y2 X8 ~* y* z; M 可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。
7 W( U5 z+ U6 H4 r————————————————7 b Y/ ?) o2 p. D
版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
5 e4 R6 t, w# F/ j原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288# E+ ^" u2 q' m# U5 f& W
' S& D8 p# H+ P' ~9 ~/ f& B) K. c$ s
# ~" R9 Z3 p9 T0 v! B$ B1 I |
zan
|