- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 569618 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 176108
- 相册
- 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实现人脸捕捉与人脸识别(照片对比)
. K1 E. n/ m( {; h D/ P# q7 C5 G5 C; @
1.安装包依赖
V- i, C) G, z3 S与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。! {4 u5 _$ |: \# \2 h# G6 C
- H1 \) v K) x, D6 k5 X) Y$ ]
在python 3以上版本tkinter是环境自带的,所以这里不需要安装; }* g3 k& ^0 J/ C9 t
2 K% V' r" C: u' e4 N+ D
2.代码示例) |# t2 j8 J5 s7 c% E6 N: G; z! K6 o. p
import os
. d& i8 J& C& M {3 o# M$ Nimport cv2
2 F5 t5 i/ p# s' a0 b2 ?8 Zimport numpy as np9 P# y w& x8 T# S& A
import face_recognition
- D1 H: g3 V$ ~1 |8 H& ]+ i5 ]import tkinter as tk
7 M" u4 R3 Z& j# o# T1 yimport tkinter.filedialog; U$ o, t; m4 z$ W r7 o- I
from PIL import Image,ImageTk ) o7 |+ i! W/ H. P% c8 v
$ U. C" ?9 L/ k1 G, ~classNames=[]
1 m' R0 t* `& q1 l) f$ V, cimg_path='Picture'
# G4 K3 L" H1 w8 E8 J% cimg_recognition_path='Recognition'# k1 a. J' s) E" |( J* I3 T- H
existsEncodeingList=[]
% E6 Q! h P" x! ]9 A$ q, Q- h' l#对人脸集合进行编码进行处理
]3 J7 Q/ k$ x# n8 Z6 ]% s% I gdef findEncodeings(images):
9 D9 h4 x/ R, U for img in images:6 m! S& V" s1 i* t. i
#灰度处理4 R5 l& R, b0 p
img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)
8 |4 P3 L/ P) g* d #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果
8 r Y( T) H. R$ R5 t encode=face_recognition.face_encodings(img)[0]
) c# A f7 {9 a3 y existsEncodeingList.append(encode)3 q3 e- W8 ?1 N B# b" }
* e; H) _3 l: ]#获取当前存储的人脸编码集合" M3 ]5 t* z" m" c0 W3 W0 l! K
def findExistsEncodeingList(img_path):
% k! f2 q1 x0 O6 s% O+ K8 a images=[]
& W) r: V8 x+ e" G. m0 e #列出已经上传的所有图片4 E/ G& a; ~) @% f4 {3 I. l- ^; I
imgList=os.listdir(img_path)
" q. j7 w$ U4 N1 `* I7 O- {/ A1 F #处理存储的图片得到其人脸编码
% g6 ]+ U' Z1 q L6 Q9 T for pic in imgList:
( T, V5 M, a9 b1 I/ Z6 g4 }- J9 g img=cv2.imread('{}/{}'.format(img_path,pic)) U1 i% E$ p" l" U5 D0 G( ~
images.append(img)& l% u- [/ i& ~ A3 ^/ x
classNames.append(os.path.splitext(pic)[0])
3 k6 [% H( O3 J: U6 D( N% d findEncodeings(images)4 s2 |- [6 H* Y5 \$ N; N& u' }
5 D, Y' o; k2 m/ H' y! S! {#选择并对比图片. n& S/ y5 R5 S8 w5 j" L
def choosepic():
2 Y1 m5 u' T4 C4 B O, U choosepath = tkinter.filedialog.askopenfilename()
9 x- n8 B4 l, l% V% U8 \8 J- ^+ q path.set(choosepath)9 W3 H" B1 p! D: q% y
img_open = Image.open(entry.get()).resize((530,750)). m2 ?& e/ r9 L, A2 @
img = ImageTk.PhotoImage(img_open)/ a; U2 e/ p% T, U9 X4 I
lableShowImage.config(image=img)
1 Z. B) ], L8 y lableShowImage.image = img
) N9 a% _( m1 s0 ?5 n! E lableShowImage.place(x=30, y=70, width=530, height=750)5 _/ ^! c1 o. q! I0 w' V( e
faceRecognition(choosepath)
& ~$ b+ u" }" L3 ], c% ?
$ K( ?: J( c2 q+ H( ^def faceRecognition(choosepath):
! |$ W/ T6 y! L5 g frame=cv2.imread(choosepath)
1 Y3 @6 Y$ K2 b( c$ A5 }: f3 a( D frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
- l9 O5 _. Z4 Z/ q #对摄像头读取的检测人脸9 S5 j# K, _- m! T4 }% q9 n
facesLocate=face_recognition.face_locations(frameRGB)
) A: \1 U6 a. _+ @$ ~. a #进行特征编码
8 R$ e3 e$ n+ K# Q2 ^ faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)2 X1 h7 m$ ~' o* d
#遍历检测的人脸和库中读取的图片进行对比,计算其相似度: x# ^1 F; ]1 O+ t- q" a
name='unknow'
: v! R- A4 t- L7 Y% x for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):
6 a, O+ k N/ l7 c+ y" ]" N #进行匹配- u: {8 J( o7 o" a( x) g
matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)2 Z( Q+ B& G5 R! E' {' f
#计算相似度
( D# g- U* k5 g6 B: x7 W) _ distance=face_recognition.face_distance(existsEncodeingList,face_encoding)# _; \; s) H% m3 }
lab='unknow'
7 ]1 L1 w! }7 K% A for index, item in enumerate(distance):3 x4 o9 ]# g" [+ t& p
if item<0.5:
6 i" y2 {. l- ~( \, @ if matchs[index]:
* U& T" ^/ u; A$ d# Q- T! K2 C! T #得到匹配到的图片名称与相似度值8 f7 G- q+ p: U0 f! r( k
lab='name:{}; Similarity:{}'.format(classNames[index],item)
3 v4 T& ~3 b+ ?' ?( s: H0 | name=classNames[index]
7 i9 D. E7 r- f+ J) C7 Z# x break# z9 O+ W1 s9 j" o: ~0 }
#初始化面部捕捉框显示绿色
% t T9 a7 a$ U% S# I0 i6 k color1 =(0,255,0)
0 Y s! {& h+ ~; {& i# [7 N if name =='unknow':/ F$ u( J% I- L) }3 c0 H* W
#未能识别的时候显示蓝色
. K% B+ r/ G8 l6 C: u K/ D+ G: M color1 =(255,0,0)
) W7 z% y2 q' f2 j6 B$ V x #画面部捕捉框
+ G/ N7 Z6 J+ u% R" ~$ p' ^ cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)
% \ T5 L7 ^7 S #在捕捉框上添加匹配到的图片信息
$ }+ s5 I2 b ?9 ~ cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)
. R5 v5 M- [+ e8 h# r4 u cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)" j! d4 L; i; n/ y' l
img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750)); W( O. w [3 r: d: T E# J% d& t
img = ImageTk.PhotoImage(img_Recognition)
9 B, Y" f3 F4 |' m( W% [ lableShowImage2.config(image=img)
( ?: \+ p' P" e( p3 y. h9 U lableShowImage2.image = img
6 u( m/ `$ V& d lableShowImage2.place(x=630, y=70, width=530, height=750)
1 t, ^- ?! a6 B- l2 q4 m
4 j( U3 d1 \$ x/ o7 Mif __name__ == '__main__':0 E7 ?# a b& ^% b/ X$ w' G9 D* Y
findExistsEncodeingList(img_path)
$ @& e" Z, L; i, G. f4 a3 { #生成tk界面 app即主窗口
% x9 x% s4 V7 P- J, U app = tk.Tk() ' G' V, ]7 R" a) v
#修改窗口titile: b. O6 V; g3 r
app.title("show pictue") 5 u/ T+ v5 Y. Y( D
#设置主窗口的大小和位置7 t6 G. H8 P7 B, _6 P6 E
app.geometry("1200x900+200+50")
, h6 T$ k+ r8 U: S O #Entry widget which allows displaying simple text.0 l& U1 `- j9 v+ M8 v. R
path = tk.StringVar()
! e* @# ~! U7 G3 R: t2 W0 s( R entry = tk.Entry(app, state='readonly', text=path,width = 100)3 L% ]& l* f/ O2 ~ e
entry.pack()* ^5 \+ C0 P3 G t$ X1 k1 Y( A
#使用Label显示图片
. B& P# U4 \6 q! S lableShowImage = tk.Label(app)# `+ q9 v" ^4 r, L, g* `- S
lableShowImage.pack() [" z- J$ Z. B; L! @ t
#使用Label2显示处理后的图片
, w9 _5 N6 \& m/ U' N* B/ f H" s lableShowImage2 = tk.Label(app)
: W+ D6 i U" E. g lableShowImage2.pack()
1 a- r6 s2 V5 J7 k/ g #选择图片的按钮' O; E }' V- x: _
buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)- X# F1 e/ x( I9 S0 g# K) P/ y
buttonSelImage.pack(). d$ V% Q" @1 w/ n; Y/ K
app.mainloop()" |8 L/ r; Q5 |" Q" @! ^& H4 X, _
6 G7 W! c: e) }% o+ A/ m
3.说明/ i5 o. L- t5 G9 _$ D
首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。; N- d% T/ r: y) x: c$ @
/ I% _9 X' e4 ?) h/ q5 L+ z |
# l% S- r( K! U* w, E8 P: z) @. ]( T4 `/ L; D
其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片
7 Y3 Q8 Q* r$ z: {: {7 D) X1 i$ O* q; @. u
% ~1 [% T9 E" c5 {! c$ J f) `. o' A. G
) r' H. {; }+ D7 F2 O
但是效果会存在色彩的失真,效果如下:1 h$ q. |6 J/ a2 L. q* B8 D6 p
' Z9 r$ F! a) |9 e9 i8 l+ W0 b5 h
1 _7 \ L; M' s/ \
/ @7 O8 R8 c% h, [5 R- c
也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。
P9 C+ C1 S2 t/ i* I0 ?$ p( F. A \ s3 ?% r
这里简单提下PIL的九种不同图片模式:
0 g! [9 \. S' J3 e! W7 p1 T7 d
- _( v4 P6 j: ^- E2 [modes 描述
/ @- U( {+ q7 z; I1 1位像素,黑和白,存成8位的像素
( i; @: b& N5 Y3 t! sL 8位像素,黑白# p4 e* k0 M8 q7 s% M
P 8位像素,使用调色板映射到任何其他模式
0 R( ~4 R+ U. [7 zRGB 3× 8位像素,真彩
6 t- v+ ?, h2 ~7 |$ cRGBA 4×8位像素,真彩+透明通道
/ q8 x; `+ f$ J6 }CMYK 4×8位像素,颜色隔离& J. d ?4 h" I. R( g0 e# ~) p# \: }4 y
YCbCr 3×8位像素,彩色视频格式
) I ^3 C0 N8 ^5 m1 w9 S) Z. eI 32位整型像素 h1 M( t- R- h7 h& D' w
F 32位浮点型像素
# w! h+ ~" Z( v4.实现效果
' S5 h. s. c! n! U! o( R5 A6 M; O/ y% ^ ~
+ U4 u f5 l8 ] F9 p
' E- E- X% |. S+ Y7 [ o7 O
/ t3 C; |/ g0 V! c) J) J/ p) G 可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。
6 | Z! m5 N; r# u————————————————
: B. J5 u% Y, L7 I: J+ k' @+ c版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
3 V) n9 G- _5 Y* b8 B) N/ i原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288+ c( C. [3 |* ]1 H
( r" f/ `8 S+ n5 t: q' F* U
& {/ a/ O, W8 u$ d b |
zan
|