- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 564443 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 174556
- 相册
- 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实现人脸捕捉与人脸识别(照片对比)+ C7 _3 m% Z9 k. i$ n* D
1 a% ^' L/ j- k( k7 p$ ~5 f1.安装包依赖
) x# G8 W2 b- @# X& v3 B与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。: y7 W" F! R6 `4 Y2 {8 j4 U3 o R
; C! t6 D8 d0 p* G( s+ F, A在python 3以上版本tkinter是环境自带的,所以这里不需要安装+ s5 p$ A. s" Z" J; R! V
& r: ^& i g. i1 d9 p2.代码示例+ o7 R' b$ E6 l3 D1 r
import os3 y) `& J, _& U2 A
import cv2
' ^1 N8 g! u' v8 i- `% Eimport numpy as np- r" Z6 A; T, K( {- w, ^
import face_recognition
5 o: D+ ]( ]) a Aimport tkinter as tk
a; S J0 C6 I! R! w7 z6 }import tkinter.filedialog! X* H8 z6 }; Q
from PIL import Image,ImageTk
$ m( x7 o& |- n3 G6 u. u
6 k0 f8 {7 d1 H! }classNames=[]/ g- T5 [ f1 x8 I- \% ~; V$ ^
img_path='Picture'" U7 M! K6 W* n2 L
img_recognition_path='Recognition'
8 a3 M; h: W) c* j1 H GexistsEncodeingList=[]
# W# G' ~3 m! N) D+ x0 T#对人脸集合进行编码进行处理' J3 O/ h4 h% t/ A7 y5 z
def findEncodeings(images):
: O3 u8 Z6 X3 W: ?: g0 P' U [. E+ l for img in images:
# i8 X6 B) q; V$ K; F #灰度处理- @$ I1 i& r4 l% ~( q0 S
img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)$ @$ r5 X# [5 v% x+ b
#face_encodings对图片对象a_images进行编码并返回数组0位置编码结果
+ ]8 ^9 {6 Q/ [9 E( S5 H( B encode=face_recognition.face_encodings(img)[0]
' W+ K Y$ h( W existsEncodeingList.append(encode)
( A# X5 q8 r! I$ n5 g; C, N0 ]. P3 N! Z, d
#获取当前存储的人脸编码集合1 [! z8 v L' a, [
def findExistsEncodeingList(img_path):
$ Q$ G9 [) Z. r/ B% P- e images=[]2 C8 N3 t. ^( r. Y2 p; C3 Y7 x( |
#列出已经上传的所有图片
6 \ ~# a4 M4 Y/ e5 ~! ~ imgList=os.listdir(img_path)
9 O- y5 E8 V/ [ X! c! s# H& x1 G #处理存储的图片得到其人脸编码 Y% `$ B& j# P: m2 y( O& [+ ]
for pic in imgList:; Y3 ~* Z, h5 ~; {
img=cv2.imread('{}/{}'.format(img_path,pic))0 {1 _& W/ p1 ^% C" e8 S
images.append(img)
) t3 D; }) P( S classNames.append(os.path.splitext(pic)[0])
5 Z2 z. E6 y# @2 y5 @ findEncodeings(images)
, j0 K) r$ E% r8 w: X
5 }+ e7 H- T& R! h6 |7 T" ~#选择并对比图片
2 X5 [' r4 k: k) ddef choosepic():
! y! u& ?" r( a- P { choosepath = tkinter.filedialog.askopenfilename()" |' a' v' g* H8 _6 a) e0 W' X
path.set(choosepath)
! R a/ l, `0 H' N, i# m4 N8 _* w img_open = Image.open(entry.get()).resize((530,750))
; n" [' H' \; {5 _ K& f img = ImageTk.PhotoImage(img_open)8 ?! `9 x# v( e0 V$ Y) ]8 _ ?
lableShowImage.config(image=img)
9 I. {% X1 Y( s. R% s lableShowImage.image = img
( g# n6 V5 [: X) K3 J8 \) U# J lableShowImage.place(x=30, y=70, width=530, height=750)6 v* ]- K S1 l$ z9 m5 Y8 d5 k- u
faceRecognition(choosepath)" x( R: N9 V8 o9 D" ^4 d7 c4 I% I
- P! c ^- C9 k) Y8 O) wdef faceRecognition(choosepath):! K. B, h5 K4 u4 X& C3 M( O, X. e/ C
frame=cv2.imread(choosepath)
+ N# G- E3 ]- P: h! y& j" q$ ] frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
- e& W+ E5 |# V& L6 N #对摄像头读取的检测人脸
, V: v. E; z0 ]0 d- d' M+ A facesLocate=face_recognition.face_locations(frameRGB)
+ f4 p2 e$ u. G' P; c #进行特征编码
! K0 P+ E$ o$ W9 ^ faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)5 h$ m. V4 B# G& R
#遍历检测的人脸和库中读取的图片进行对比,计算其相似度* |! Y% d5 y# Y' n2 h S3 d
name='unknow'' i) o/ U- Q- J
for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):
1 w: |$ _% c5 {7 H6 o #进行匹配
* |+ n. W+ G$ O8 T+ \' ? matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)
2 Q* z2 f$ z( G9 }7 u #计算相似度% f" ^* }4 I- I7 G
distance=face_recognition.face_distance(existsEncodeingList,face_encoding)
9 d9 {! I7 h" B. F' e; o" u. B lab='unknow'3 |6 Y: G( A& i& { U2 h) o
for index, item in enumerate(distance):
+ p% h g+ L" y4 F/ w: Y& `! w$ y if item<0.5:& e1 E% h, M0 P- |
if matchs[index]:
: ~# K+ j; s2 D3 T #得到匹配到的图片名称与相似度值
2 l; H4 D( {4 e( l+ B lab='name:{}; Similarity:{}'.format(classNames[index],item)& e9 q; _5 H. L7 B
name=classNames[index]
: x5 g$ @% W+ ]) f9 b4 i break
9 P- D) T$ N g6 o8 c9 C) @8 \; b #初始化面部捕捉框显示绿色
0 D( S! L) }4 M: n9 C color1 =(0,255,0)- y# P1 S% U! m4 m6 D* X
if name =='unknow':
% j: ?7 M$ o9 {( m4 M #未能识别的时候显示蓝色
) t) W3 A4 n1 y" P color1 =(255,0,0)2 S7 k7 r$ l3 w2 A* B
#画面部捕捉框! t k0 N4 |9 G- Z, K
cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3): s% L* m9 i, {
#在捕捉框上添加匹配到的图片信息% B) ]- ]( `. b& b/ N. m
cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)
; M' Z8 S6 a% T' w cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)
$ f/ L- k& u9 E% F( F img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))
1 Q6 H+ E1 G* t8 k/ K: C img = ImageTk.PhotoImage(img_Recognition)4 \) w( e( G }3 {5 J- T
lableShowImage2.config(image=img)
& w' j6 k1 k+ a/ ^1 L1 l9 E" y lableShowImage2.image = img
; X, Z8 i5 A6 l$ ~, m lableShowImage2.place(x=630, y=70, width=530, height=750)$ ]6 H; Y% C* G$ C2 u* q
, q$ O2 ?' K1 n- X! i ~- \" ^if __name__ == '__main__':
) z, F3 n9 Z* K( n) H, a7 o/ C findExistsEncodeingList(img_path)
# @. ]" |. J# a& P0 u* M9 d #生成tk界面 app即主窗口) ]& L0 O+ ~5 X$ y
app = tk.Tk()
$ U; |: P1 \7 Q% _2 j #修改窗口titile0 B( [$ L! _* R- U( k9 t2 n
app.title("show pictue")
6 V9 C. {: h Z2 Y' t, Q. H% v #设置主窗口的大小和位置
# ?& h* j8 T6 P app.geometry("1200x900+200+50")
) Q0 B( i$ v3 D. O1 n L! g8 U+ T #Entry widget which allows displaying simple text.7 Y, i- u1 w- V5 w
path = tk.StringVar()
$ J8 F4 G# q% b. `. o+ h; R entry = tk.Entry(app, state='readonly', text=path,width = 100)5 ~# S$ q9 N6 G5 I$ R' \/ i/ B
entry.pack()% g: y; z7 `1 y
#使用Label显示图片; ~8 u( _$ h/ ~% a- u; v t
lableShowImage = tk.Label(app)3 _' {; A$ f( W! f- V; ]* w
lableShowImage.pack()3 E: I! {* E( o. i- ^
#使用Label2显示处理后的图片
: o5 c5 s+ o$ m lableShowImage2 = tk.Label(app)( D5 i4 z# L6 G9 O
lableShowImage2.pack()
% q& M4 O. ^- b9 W% O #选择图片的按钮! F3 N/ P' x+ g
buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)& q4 a/ R: {( A4 q1 K
buttonSelImage.pack()* V1 S* V3 o4 s: M
app.mainloop()
" E( {' X: c# ^- E+ b' D P) d) I; }- d/ u# o
3.说明) R" D, N9 ]! n0 A2 x7 R2 a4 O
首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。
( [- ]) b6 }/ l. u
% ~) J: _4 m3 \0 `4 X
2 k% k5 R; k7 B$ F1 q* Q/ ?1 z6 U9 {# \, M/ l- ~
其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片
9 t# U2 C& V/ A& Z$ L( U) W
; N" e, ]0 }" I
& h) v( ~1 |6 @$ t7 t0 K* D8 q) @" a/ Y& t* V" d) C
但是效果会存在色彩的失真,效果如下:
$ p8 F$ f8 R, [8 ^* h4 e6 G
' `2 x0 ]" |1 k5 z1 k, o( i( k8 c( _% V @* B: e) e7 u8 J6 c4 w
$ @# | {$ Y/ r; \- b8 {9 H) i也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。
) f# Y* d& A! g# k5 L7 X
% I4 @6 C! Y* V5 U这里简单提下PIL的九种不同图片模式:0 S/ x+ l5 r9 U. _+ ?# u" o
% r# m2 G& T" s. b4 X8 ]
modes 描述
. g8 M6 n5 \/ g: ?1 1位像素,黑和白,存成8位的像素
8 Z2 }2 d. P$ L( UL 8位像素,黑白
8 ?& E+ _' Q5 r. pP 8位像素,使用调色板映射到任何其他模式9 Q0 Z8 I, p" O9 F, A( S
RGB 3× 8位像素,真彩
" g: M0 F1 Z/ I6 VRGBA 4×8位像素,真彩+透明通道
( o" X5 G# y- z- o" V4 z+ J) uCMYK 4×8位像素,颜色隔离% ]" m0 B8 o' ` N5 u& q S8 I* D( c3 J
YCbCr 3×8位像素,彩色视频格式9 j2 g4 F& @8 H2 D% V& P" Y$ r- j
I 32位整型像素4 ?2 ]+ i9 m4 c. V
F 32位浮点型像素
& Y$ x$ g2 `" [7 J4.实现效果
( t) P8 p( h$ M3 n+ O5 V8 H# [$ A8 R0 t: X- [
$ M O% d: k: d$ [
/ ^; j- L/ i/ o# i1 y! K- g9 ` R& L/ e c i5 F5 d
可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。
/ R4 t6 o, D8 g- {" ?( t————————————————
7 ]- }, Z$ V3 B& U$ c版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
' q0 F, D G/ H, Z' O, o原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288
, p7 B) V/ q- K7 G( X5 v0 P' Q/ U! F/ n/ C; A* K7 M
" e( m4 C& C" F* \- Y# }7 Q |
zan
|