- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 566250 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 175098
- 相册
- 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实现人脸捕捉与人脸识别(照片对比)5 h7 ?6 j& @4 w9 E) e
" e2 t. M9 Y" V( ~3 B/ V
1.安装包依赖
4 O D' A* n; _. g# O }. {" b与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。. m+ m" @0 k- l, g
, v0 Y3 n7 ^# w% k% y' [( b
在python 3以上版本tkinter是环境自带的,所以这里不需要安装! Y# H3 n0 T9 \8 I I
: F9 z% y8 S- m9 |+ L2.代码示例- C2 ]) i, i# |( F/ ]5 P5 L
import os
4 y5 c% ?- G9 rimport cv2
. f' m+ c- J. eimport numpy as np) o" q4 Z/ b, y S; k7 |, D
import face_recognition% M; U4 S5 P2 i2 z% L# S1 p; q
import tkinter as tk k0 O1 k# k; F+ T
import tkinter.filedialog
# W/ b ^: U8 \8 V$ Q8 Jfrom PIL import Image,ImageTk 6 C: T% c$ H$ `/ d5 l. e2 t" ]
& f/ F p1 J7 v9 z# C; r0 W
classNames=[]
. W% R! }: M$ v1 J1 |4 `1 U" zimg_path='Picture'
- ]6 q/ @0 U* U) y$ _img_recognition_path='Recognition'
0 P- ^% X8 _7 w+ |4 D- SexistsEncodeingList=[] f% |6 v. {: V2 f
#对人脸集合进行编码进行处理' u4 c* Z0 L' L# g% z9 W6 W, y
def findEncodeings(images):
- L/ T3 @* L/ k: ^ for img in images:- X% Z8 u& w: ]8 e {
#灰度处理! |/ h2 I0 _, S$ N+ r
img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)+ G! l5 d$ v' x- e* ?' k; k, A
#face_encodings对图片对象a_images进行编码并返回数组0位置编码结果
6 w, u; r+ R, N8 T# m& P0 t encode=face_recognition.face_encodings(img)[0]% _" ^, ]! M% \8 q/ O! u2 J
existsEncodeingList.append(encode)3 ~3 {4 b" \# j4 {1 R; s
$ u% F# N+ [# `: c#获取当前存储的人脸编码集合, Y2 ^8 }9 T0 ]! k, i, B
def findExistsEncodeingList(img_path):3 D6 f: l8 e; u8 ^
images=[]
2 o9 N) g' @0 R$ s# H5 n% F6 ~( P #列出已经上传的所有图片% D1 m, [4 c1 ?: V2 d' R
imgList=os.listdir(img_path)2 R) z2 g6 J6 O& [( r* ^/ |
#处理存储的图片得到其人脸编码% o, g5 }& _' _4 }( O
for pic in imgList:" Q5 Q* G7 q5 h7 c8 h* s
img=cv2.imread('{}/{}'.format(img_path,pic))* F* b# O7 Q% X2 G
images.append(img)7 P# h6 d+ G0 u( J
classNames.append(os.path.splitext(pic)[0])4 e4 y3 |/ {: r# T/ o7 R
findEncodeings(images)$ h5 ~1 ~* e& W: G( X& B8 }3 a
w) G0 q1 @$ b, G+ o9 O5 ~# Q+ n$ J#选择并对比图片
+ x* l0 _5 ?2 P; j( ^def choosepic():
# s. n" h$ b F7 [- \ choosepath = tkinter.filedialog.askopenfilename()) F. p; t: g, w6 A
path.set(choosepath)# r- v8 U. O7 f! m
img_open = Image.open(entry.get()).resize((530,750))! G7 D) ]" v' Y, m* m
img = ImageTk.PhotoImage(img_open)
: c) m, `' h1 n" | lableShowImage.config(image=img)3 S2 N6 U; Y$ C/ y; `6 \
lableShowImage.image = img
' z6 b# L7 u- S3 [ lableShowImage.place(x=30, y=70, width=530, height=750)# S# [- S2 i. `
faceRecognition(choosepath)
" \, @5 \1 H- I& E# p7 L- j/ x( A
% X" C" q6 j. r Z- E9 ~- Wdef faceRecognition(choosepath):2 G! [) I6 V; F
frame=cv2.imread(choosepath)% t5 Q: i. c" b: V5 ?; T3 B
frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)% h! o& ]: N, r4 C; A5 z5 d
#对摄像头读取的检测人脸
3 M8 e2 T g; Y- f% j2 i facesLocate=face_recognition.face_locations(frameRGB)0 A8 M% s& j! R! J6 d. y6 W
#进行特征编码/ J* z& B& f* ]
faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)
2 Y; s1 H b! u) e# {, u( y #遍历检测的人脸和库中读取的图片进行对比,计算其相似度5 U% Z( o0 ~1 ]; e( q" h9 I3 @! ?2 u# E
name='unknow'
2 ~6 {. m9 Q" Q for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded): B- m5 U) `' E% w
#进行匹配
. R- h( H7 `3 s$ |- T# C matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)
. I+ u9 p. E7 y% H# `+ }" Q #计算相似度
1 O, ~4 L" p4 @/ w distance=face_recognition.face_distance(existsEncodeingList,face_encoding)
7 }' p/ [1 l0 `) Y% {5 \4 d lab='unknow'- q- R% _: v- x2 x6 g, U$ a1 X
for index, item in enumerate(distance):) T$ ]5 F' |/ ?$ h" [3 W! [2 k2 }
if item<0.5:2 g) d$ K# j5 A& c
if matchs[index]:
0 z* E- R0 k! }" V. z #得到匹配到的图片名称与相似度值1 D/ u4 N7 N$ |$ O
lab='name:{}; Similarity:{}'.format(classNames[index],item)
/ s3 h$ j' Y' n$ ^" d+ f name=classNames[index]- K, c2 D0 I I" i$ F
break
; c" W, |, K+ G3 @- A #初始化面部捕捉框显示绿色7 X$ ]% E$ ~9 l5 J' ` ~! y
color1 =(0,255,0)
1 b, Y% _# j( p5 ^, H5 {* ] if name =='unknow':! R; _2 e2 @% z( P' c
#未能识别的时候显示蓝色
2 D2 m0 @2 w3 [, {4 n color1 =(255,0,0)3 p4 e6 x# h" }4 J+ N) W
#画面部捕捉框
; G6 z5 a! M% ?* b cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3). G8 C& g7 x0 u6 C; o/ @0 Y5 J8 z
#在捕捉框上添加匹配到的图片信息
% ?8 x- Y; T2 b/ r: w! e& \ cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)2 x$ m) b. b: `3 D3 \9 C9 y
cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)
" j6 ]+ X. U( e% b img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))
4 d. k0 B0 {# k/ `1 |; C9 {. { img = ImageTk.PhotoImage(img_Recognition)' {' V* v6 `; r% T6 d8 F7 n
lableShowImage2.config(image=img)1 r* ?* T+ }! d ] K9 j5 e E
lableShowImage2.image = img
! z, |7 S# L- ?5 {/ e lableShowImage2.place(x=630, y=70, width=530, height=750)# k. y7 M5 }& x, }* }
/ Y* d" P2 j. ~! ?* c
if __name__ == '__main__':1 |4 A' x3 |7 S5 B8 x: s
findExistsEncodeingList(img_path)8 c7 R: H M% D8 R- f$ ^
#生成tk界面 app即主窗口/ I6 A6 D4 ~! }* |
app = tk.Tk() : H+ g! K5 M1 a: E2 J( s
#修改窗口titile
; ^) n9 `2 m; G9 F) t app.title("show pictue") - g+ `: B5 [5 f. `
#设置主窗口的大小和位置0 B+ M& Y* k* ~2 q; c1 h$ r
app.geometry("1200x900+200+50")
) g6 m: z7 o$ n* x0 {& U #Entry widget which allows displaying simple text.
+ [! c( z( ^) Q path = tk.StringVar()9 F: P1 b% F3 G" ^9 N8 h
entry = tk.Entry(app, state='readonly', text=path,width = 100)
; K4 l4 K! X B% l8 I& k entry.pack()
: B$ I* {1 @, z& Y z. O2 C2 @ #使用Label显示图片
+ _& d& Q( j v" _( K lableShowImage = tk.Label(app)
2 U& G5 Q( E) C lableShowImage.pack()4 m ?+ r$ w; k K. q; k
#使用Label2显示处理后的图片& ~) C' I! d; o
lableShowImage2 = tk.Label(app)" x9 a5 ~9 L- i+ F
lableShowImage2.pack()7 q- V, `0 c- V( x( R4 M: g, ~
#选择图片的按钮1 r) E! _. }% Z' h& R
buttonSelImage = tk.Button(app, text='choose picture', command=choosepic), K/ |/ `! Z1 n
buttonSelImage.pack() p5 g1 y$ r7 j- b
app.mainloop()
2 m1 n2 J* w5 Z) \- s; E v: T" |* Y; s) _6 `
3.说明 Y" q7 A& l0 S2 M3 c
首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。
A" D( I& d& t! h' R2 O4 c! w& h3 j b$ N$ T) A& m% ~
' @- |5 u* v8 {- _$ x& S; E$ c
% T' h8 ~& G, S4 R" G S& ~ 其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片$ g" }3 l( B. s+ G v" ? @+ \% A: Y
$ n* A% M* w# h ^+ }7 p1 z- s9 p1 Y& p& v O+ y4 I# b
' v( E- `1 S: v+ D9 n% X 但是效果会存在色彩的失真,效果如下:2 j5 b5 ?% U% `
# g) j3 q' S$ B) |
& u! o- }/ E1 O2 ~0 ^( B5 Q4 O
# C2 \2 O! v [: z也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。
& b) w/ _" E( p, m3 i5 q. t' p2 @$ c$ u# ?) n1 {$ T
这里简单提下PIL的九种不同图片模式:
/ O) N9 |# }1 j% c) \9 I* [" {4 m1 `. J# }# d
modes 描述/ J5 D3 v9 Z7 ]; G* z* {/ M
1 1位像素,黑和白,存成8位的像素
6 ]. h0 R, Y/ h) wL 8位像素,黑白
0 @# {' J0 y- u- e- `$ l( ^7 BP 8位像素,使用调色板映射到任何其他模式
+ O/ n" K" R _: |RGB 3× 8位像素,真彩
' J* }' b& l) J4 v. z5 }RGBA 4×8位像素,真彩+透明通道% T$ t# I7 ?$ B! {# H$ X
CMYK 4×8位像素,颜色隔离+ _+ }' h7 v) Q3 U
YCbCr 3×8位像素,彩色视频格式7 O/ m( \5 h2 h- f
I 32位整型像素
/ z& S# o0 _+ T9 e, v# f/ f% X: A) A9 fF 32位浮点型像素4 I7 m4 M) N$ U
4.实现效果1 Q& N- h: W" C. A. [- \% X
- l* b3 \) O+ U7 M5 \4 w5 k; h. z& ?
3 J v! d; g) ^4 N! W2 S* ~: I* y& S) V) _: R9 K4 m
可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。. p3 Q- N8 n" a( H
————————————————
6 a% o* ?. X& G: d |" a Q& Y版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。6 X, {3 V4 A/ V
原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288( E+ v, S. {4 Y0 P$ [) e0 e
3 f% I* h( ^' @) f
$ W* U3 i$ O C1 ^' | |
zan
|