- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 563425 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 174250
- 相册
- 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实现人脸捕捉与人脸识别(照片对比)9 |' Y7 D' j' r' _" h8 g3 X0 ~4 H. [
" f. j/ g; F3 s1.安装包依赖
" L8 K5 X6 p* F; b- u {与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。
- d# [# ^' A4 Z# p* `, o# Q. K' z( [4 G4 C9 e3 K
在python 3以上版本tkinter是环境自带的,所以这里不需要安装& x# `5 `4 J3 O) K" Y( w' x
" z7 W2 o `# N
2.代码示例9 ] j7 Z1 L+ _! e+ ]; c$ J
import os
! R" E5 V7 Q3 B4 U2 ^import cv2
* g; Q, K& l3 h, F6 j& ]/ ?import numpy as np
& P5 j1 Q9 {& z$ \+ D3 himport face_recognition
4 D2 Z" x6 Y0 J( c) Y# Bimport tkinter as tk 3 Y1 I( S b5 k5 t L( s0 M$ ?
import tkinter.filedialog
6 |' p6 B3 ]/ W/ y% g: z7 U0 f9 I5 N: Zfrom PIL import Image,ImageTk
& S' f. t6 M" Y! \8 U# k) y2 `1 E* k- X+ m& X' h
classNames=[]) E9 ^% w8 [# b& |3 T
img_path='Picture'
) |9 M8 G1 z' ?& U; L8 Vimg_recognition_path='Recognition'
/ ]" n3 v' d- w# c- _0 x% mexistsEncodeingList=[]
7 O) X1 A4 E0 Q; \#对人脸集合进行编码进行处理6 _/ ?, n) x/ m" O+ I2 |! S: d
def findEncodeings(images):
, o% L4 T; E! j for img in images:
. r; y; Y- x) }) ?# k% a9 Y #灰度处理8 u& Q$ F8 h# M5 {7 Z' N, \: ~
img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)
9 I8 c: S4 G3 \# M" D+ }+ Z #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果; h& L: ?2 n/ P. b! H( _2 H
encode=face_recognition.face_encodings(img)[0]3 f8 D! ]* ~) _
existsEncodeingList.append(encode)5 X; A, f% g4 Z- I
$ s; J, o7 T( O" A
#获取当前存储的人脸编码集合! R$ s' w5 t* V' B* L4 I* S
def findExistsEncodeingList(img_path):
3 P9 m0 a% O2 k# V images=[]( g6 _( {1 s( c
#列出已经上传的所有图片" o. y3 p3 j, Y# G1 ?2 V O
imgList=os.listdir(img_path)1 q: {: L9 g% T' _. \* D
#处理存储的图片得到其人脸编码& O) |6 D) n% x" g& O' _* y6 p
for pic in imgList:
) o% ?& f5 A( o! \5 Q8 Y1 v img=cv2.imread('{}/{}'.format(img_path,pic))
4 b) y/ \/ ]) K; D( @+ S6 C( {$ t images.append(img)
1 n! z; N7 |8 \! g- V8 S/ S) R8 d classNames.append(os.path.splitext(pic)[0])
# |$ K. j8 _7 \ findEncodeings(images)
* t- R% F; `1 H# L, m% m: ^& R7 m- o) ?# ]7 `
#选择并对比图片 o% m) j2 r1 g/ N
def choosepic(): e7 ]7 E$ g" |. l8 Q6 X
choosepath = tkinter.filedialog.askopenfilename()
( |, D7 U7 n# n" C% C path.set(choosepath)
) p- e- ?. A" Q9 u8 Q7 I img_open = Image.open(entry.get()).resize((530,750))
$ Y0 ]/ W. o% K+ Q img = ImageTk.PhotoImage(img_open)/ i# {" `! k/ ` R
lableShowImage.config(image=img)6 M( @0 D) x/ D1 R$ j$ k. Y" ?$ p
lableShowImage.image = img! M3 C4 w# m7 g( i2 b4 ~8 ]
lableShowImage.place(x=30, y=70, width=530, height=750); k ^) O/ g( @' y, p( @
faceRecognition(choosepath)9 x. }2 ]7 f6 x& P2 t( r* e
+ W, \8 b7 W, G; W) Bdef faceRecognition(choosepath):5 O* c$ I5 ]; E9 d
frame=cv2.imread(choosepath)2 x5 @5 \: m: u N8 N
frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
4 ] m4 Q) K; i3 a #对摄像头读取的检测人脸
3 I/ B1 G2 |. R( m facesLocate=face_recognition.face_locations(frameRGB)* g |7 S" d) z1 \
#进行特征编码
8 F0 w. M4 ~" n% d$ K faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)/ x* f5 h9 g& g+ z8 z# I
#遍历检测的人脸和库中读取的图片进行对比,计算其相似度
: l. r: W" N- M/ C name='unknow'
) A' b' w/ Q! I for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):& o7 ^: Z% ^6 x) u% ]( @0 `
#进行匹配
9 B( _8 d& B0 L) ]/ _" D4 z matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding); {2 P$ z8 {; r+ D: w" e
#计算相似度
8 Q- K% |1 [8 |6 _3 W; a. N distance=face_recognition.face_distance(existsEncodeingList,face_encoding)
: a: h9 n6 f. r: `5 J lab='unknow' V" I- R8 z; ?- @
for index, item in enumerate(distance):& ^# r' f. O/ f; S0 k1 k3 _" C
if item<0.5:
% p0 m% e9 q4 `9 n if matchs[index]:
# W' q0 `+ `; D( Q3 t: D #得到匹配到的图片名称与相似度值
6 d& Q' k$ D2 I2 c* t lab='name:{}; Similarity:{}'.format(classNames[index],item); v1 g/ s% s% l3 o3 g
name=classNames[index]
# }( T. Q% L- Y break3 h* H0 V8 ?$ w" `
#初始化面部捕捉框显示绿色2 x( G5 [3 p" U" _$ y
color1 =(0,255,0)4 s) P. H$ W8 B" o- V' \0 r' h
if name =='unknow':9 x5 r+ H" t/ Z8 s
#未能识别的时候显示蓝色9 D) X% z8 J- H) S# z6 r% r2 P
color1 =(255,0,0)/ f ?4 \( u) r9 d0 z/ O
#画面部捕捉框
& V/ i! ]( O+ }" v8 X cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)
$ |) y. `% |% U( m: ? #在捕捉框上添加匹配到的图片信息 |; z3 I) i: _ s0 \& X
cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)
" r; a" f8 d) Q cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)8 h+ V) y, p9 B3 P- F
img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))2 C% m) I/ Z5 B
img = ImageTk.PhotoImage(img_Recognition)
* K5 O: Y' q: B lableShowImage2.config(image=img)
, ^$ X( T) S0 i lableShowImage2.image = img
3 V D- h# N0 ?: L6 m6 O- R2 R; u lableShowImage2.place(x=630, y=70, width=530, height=750)% B1 q3 d+ K7 q% c" }; G
1 {5 A) R, u$ d g( V3 b6 Tif __name__ == '__main__':
C: t/ O( Q( u" D findExistsEncodeingList(img_path)/ k$ ]7 ], ]0 [
#生成tk界面 app即主窗口
# O# A$ y$ g1 q) Y( N app = tk.Tk() $ |0 J* w( t! T
#修改窗口titile
0 z2 Z& G+ I, \: R app.title("show pictue")
- \2 v- U# ]9 d' e! J5 N" y5 D; M #设置主窗口的大小和位置: C/ C4 m8 s7 }# P+ j' u! w7 H
app.geometry("1200x900+200+50")
q" B: U3 p% t8 A# `5 \$ x) Y #Entry widget which allows displaying simple text.
+ S$ t' Q4 c' B; H! H. i7 ^ path = tk.StringVar()
& I0 V. q& e: j1 z; Y; ? entry = tk.Entry(app, state='readonly', text=path,width = 100)
+ h9 h8 E* H' Q3 u+ l' [ a5 G entry.pack()
4 c K; t4 a/ n" r" z! J, U) v #使用Label显示图片
& s! h: q, p! ]4 B b, ^, I# t lableShowImage = tk.Label(app)
: G/ s9 m/ S6 C; p9 e lableShowImage.pack()
8 o. X5 g3 Z/ [" f2 o; n! i #使用Label2显示处理后的图片7 ?( l4 @' ?. {- ?
lableShowImage2 = tk.Label(app)
/ @6 b9 k8 r1 e+ w3 p" y! z1 W lableShowImage2.pack()
) A( P' N4 {( l# d% {- ]- k& u; V6 s #选择图片的按钮
% P+ k; x$ T+ Q7 L4 r+ ~. p* _& z buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)
* j. V. g' H% W5 R9 i buttonSelImage.pack()# n7 k O4 |" E0 T5 ~- v( w
app.mainloop()/ T8 L3 J4 h2 J2 N, V
8 }9 j; F' M# Y2 _+ f( N+ Z3.说明
+ Q4 U; I6 Z8 ?9 Z* D! e+ v首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。
+ ^* ?/ K G% H; G2 e9 q4 i2 J) L/ z I9 d/ X- f7 ~4 _8 ~" q& M
0 i; D W7 {; S! N+ J( w$ m1 L' H% J1 G) V) s6 C a
其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片$ ^8 T. f8 b" D' |8 V1 k/ f* P6 ~
1 C' |, {' z# K# w, d1 d0 d
: Y9 O9 Y) g/ T1 Z; \ g
2 e& d7 T# R; F* s- p. x
但是效果会存在色彩的失真,效果如下:
& E( _; o& G/ n6 E* Q6 K5 a: \8 | r% `2 T
* r, H" M8 T6 l+ X; {$ ?' u
5 `. X& w: ]0 g5 f o/ {; S' P- J
也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。' ^8 m/ R, s; G+ c Q" {
\ o4 w) O5 h) W
这里简单提下PIL的九种不同图片模式:
/ k1 }( k" B5 ?7 p# m& ] C( r
modes 描述
2 O9 K/ Z0 V6 b6 d% z3 h8 d- C1 1位像素,黑和白,存成8位的像素+ O0 `. c" K N! k$ b8 E
L 8位像素,黑白7 p& G7 x) [( }+ R6 y" X* o
P 8位像素,使用调色板映射到任何其他模式/ O; d% ]" \' ] `. q: B9 C# w4 l
RGB 3× 8位像素,真彩
" R! E, |5 m! V( U6 {, p" mRGBA 4×8位像素,真彩+透明通道
9 g" W! w$ [$ _8 v3 `% B+ r7 kCMYK 4×8位像素,颜色隔离6 r% y2 \% G2 X
YCbCr 3×8位像素,彩色视频格式
) v& p* A) F e4 p8 xI 32位整型像素8 f3 m9 Y/ Z: C, r- ?- q0 X
F 32位浮点型像素7 r) W" ^) a: W! b# p, Y0 g& }1 B
4.实现效果/ R5 L' D, r" @- D- W3 R& Y
1 j( Z! y* i- ~1 m4 p P" ]) N. V5 I! i- T; j" N
* l1 L, o. d/ K) w6 D0 N, Q1 B8 h+ y" x4 w' |& I% |
可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。
' f1 ~8 s! d0 T- }' S# Y1 W————————————————( r- ], T5 I8 `5 A$ R4 H4 N
版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
; F# A3 `$ h) n3 w+ a原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288/ D y3 n4 x$ n8 G
# Q, Y& d$ m, e( E2 ~- `; T; ]
9 M1 c9 Y- k8 ~% g |
zan
|