- 在线时间
- 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实现人脸捕捉与人脸识别(照片对比)$ C. {; l G {
& s- ?' v3 f6 h3 N6 `
1.安装包依赖+ E; \6 m* K. O [5 M5 D
与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。
[5 J c% ?- ^' w J! P& k9 ]; k9 M, F
在python 3以上版本tkinter是环境自带的,所以这里不需要安装
* j6 v( v! y8 g1 ~ E: q- A& F% T- R+ m
2.代码示例1 I( z0 A" A6 @. D, M, W
import os q' s9 Y- b& I1 y3 y; C
import cv2
: ]2 E: q- z" V/ \import numpy as np
, ~0 i# O9 G) x) |$ l. Z2 ~import face_recognition E5 t. }- [, u; U# ?7 F
import tkinter as tk ( x2 d9 A+ h F y0 G+ E# G k
import tkinter.filedialog$ Z; X0 D4 L' Y( h. v+ b+ T, h9 j1 N
from PIL import Image,ImageTk
) P7 j& `0 k% Q
- D1 C I; x K4 C$ WclassNames=[]9 ]3 S! N' L; {
img_path='Picture'3 e" _6 r7 o) I( N. o( P: ^
img_recognition_path='Recognition'& ]/ O3 U1 R' ^" J! H
existsEncodeingList=[]
! ~% x9 r! K1 B- j' U/ L3 k# m#对人脸集合进行编码进行处理
$ T8 @( V- L$ g6 h1 gdef findEncodeings(images):
8 |* c! h. Z5 g for img in images:
# E, D2 ~" _$ L6 c6 O# B4 m #灰度处理
/ ^6 ?; [+ k+ f/ j2 [2 ~# \ img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)
$ ?+ M0 s. m; a( E, u #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果2 r- ^9 @7 G; [. b0 E; X
encode=face_recognition.face_encodings(img)[0]$ i0 C( ^* `" n' E3 H( y
existsEncodeingList.append(encode)
8 T1 l2 a Z+ |( r. p2 @& Q: U' F
* ?8 \3 _: ~+ A$ N9 u0 \#获取当前存储的人脸编码集合
6 g6 N% n% ?5 L1 U( X0 [8 Udef findExistsEncodeingList(img_path):
, u0 ]+ r. s* b8 W: ]0 o images=[]
3 A+ j2 d' @6 v# h* b6 V, d6 \ #列出已经上传的所有图片
/ a! D& R& g: |, y imgList=os.listdir(img_path)3 a* V+ l0 h2 _$ ]
#处理存储的图片得到其人脸编码
/ t0 S) ]/ P. \. @5 g1 B' E for pic in imgList:4 K; S( Q7 }- D2 c* N: ~( k5 F
img=cv2.imread('{}/{}'.format(img_path,pic))
4 b( L- N! c$ D( I8 e1 I- c% I7 j1 ? images.append(img); a9 ~4 ?0 x. T1 |2 c
classNames.append(os.path.splitext(pic)[0])
' E7 |8 y2 V- d* O# P a findEncodeings(images)! e: t c- H+ s7 e' t! a, J8 x% Y& p
3 ^; T _: I* Y- y' W, t" ?
#选择并对比图片
: t# d! v% G( E: p2 @" x7 Fdef choosepic():
: z" U! t5 j$ r* c7 D& W8 X choosepath = tkinter.filedialog.askopenfilename()
! Y6 c0 I3 I. a$ V path.set(choosepath)
. z- W! d- v. A7 Q% J9 C$ K* U img_open = Image.open(entry.get()).resize((530,750)): y5 S: }5 }% m# Q8 f3 i7 e) l
img = ImageTk.PhotoImage(img_open)& Z( ]. i/ k& E9 ]
lableShowImage.config(image=img)" h* o( Q* H9 v, o- F8 j9 v
lableShowImage.image = img3 [* A; P4 f/ W8 `1 l( L. x. w
lableShowImage.place(x=30, y=70, width=530, height=750)7 b+ m/ D$ Y" l1 A4 J$ P
faceRecognition(choosepath)
]5 Z2 `5 f" y: @% S# P. ^, }3 c9 S- t4 w( M" m% f
def faceRecognition(choosepath): j. X" R* g: r9 c u$ f- [0 P
frame=cv2.imread(choosepath)
2 w) d3 ^- B+ e) l2 w9 M4 M! { frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
# [2 U8 i8 Y$ v+ L- x; K( a #对摄像头读取的检测人脸) v) {* W1 z% w/ p" D* G
facesLocate=face_recognition.face_locations(frameRGB)( ]. V! L. o- e
#进行特征编码9 v% \( c, c' w" P" W* F
faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)
: T' B+ ^0 F5 _$ N #遍历检测的人脸和库中读取的图片进行对比,计算其相似度6 J D! t, _, @3 s: X4 _& L4 B' `
name='unknow', g/ h8 F6 }. x# g, _& c# ^" g
for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):
9 f7 J% k; f2 Y4 y, H$ P9 ^ #进行匹配: H+ S0 E/ `5 n+ h0 f
matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)2 P6 V p" e0 z( N, D
#计算相似度
" R" g" K6 w9 C" z- g4 Z distance=face_recognition.face_distance(existsEncodeingList,face_encoding)
: C2 X/ Y/ ?8 x* P# {( O: H lab='unknow'& N, [$ T* `1 ~ ?% N2 g
for index, item in enumerate(distance):/ }2 L4 D6 B9 |) {7 N
if item<0.5:
* x+ m6 m0 P" Q8 ^ if matchs[index]:0 w$ X' c- z8 ~; M$ s; Y7 O$ \
#得到匹配到的图片名称与相似度值
( @9 X: V' z$ b6 m lab='name:{}; Similarity:{}'.format(classNames[index],item)! X8 Z/ \# S: q2 \0 O% c
name=classNames[index]- E9 r/ c9 w, o, _" r; @
break
6 m' ?- s( p( b: Y: j( w #初始化面部捕捉框显示绿色# D# ~2 ~, i/ Y6 ?% {$ Z
color1 =(0,255,0)' F& s7 o' l! G( X
if name =='unknow':' d }+ s2 a$ v! O% h) m
#未能识别的时候显示蓝色
" E+ Q& |' G9 S; a! p color1 =(255,0,0), x8 _: G, r/ y, H$ T J' y4 M
#画面部捕捉框8 m3 v; V7 y1 X: `
cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3): r/ }8 } ^$ L; P8 n$ X2 H0 d8 B
#在捕捉框上添加匹配到的图片信息
7 ?' {, f' G6 D cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)
& Y2 s t9 f7 c5 u! X2 F3 E, T cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)3 U# h5 W7 G5 u) H0 m4 o) t
img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))2 A, d& h6 E A' \
img = ImageTk.PhotoImage(img_Recognition)0 G4 c+ b2 O0 Y: _
lableShowImage2.config(image=img)
2 h5 h2 [6 _5 d5 y) a& a lableShowImage2.image = img
, Y' Z7 p5 ^3 c& M. J) \4 K lableShowImage2.place(x=630, y=70, width=530, height=750)' W0 t! U+ y7 f/ X
& n( Q4 c: p! i$ F) g+ X. F# n" m
if __name__ == '__main__':- u& ? B/ J. ~
findExistsEncodeingList(img_path)3 S# \& k5 z- A4 |& t
#生成tk界面 app即主窗口3 \& l0 _4 R6 C6 Y) C% M: q* K7 z3 B
app = tk.Tk()
. k& K) j) A9 |' a; m$ R# i+ Y% }6 v #修改窗口titile V5 m2 d9 S. X) O. y. ^9 e% @8 t7 }
app.title("show pictue") 7 V1 G/ r% }4 R* p) M
#设置主窗口的大小和位置
/ ~+ D1 i, ~' M' q0 i( `- r; D app.geometry("1200x900+200+50")) l3 K) } t: G) {! }( f% v4 \. I5 b
#Entry widget which allows displaying simple text.) B8 u# \4 O% I
path = tk.StringVar()
6 V# t* c* S, i* R8 [5 u entry = tk.Entry(app, state='readonly', text=path,width = 100)
) P6 @- ` b) A/ Y) Q entry.pack()* h8 d/ d M% r3 d
#使用Label显示图片9 G+ e* b( F4 o/ \) x+ N
lableShowImage = tk.Label(app)
" ^ g" P' m5 S h lableShowImage.pack()
! R& ]. _5 d A H6 Z% W( H #使用Label2显示处理后的图片7 I1 k' k f `: A1 Q- o
lableShowImage2 = tk.Label(app)
. t$ K* A' S" ` lableShowImage2.pack()) v! @/ I2 A3 `9 U, z
#选择图片的按钮
' w" a& h' `) }3 `7 }! [" q buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)" M3 K. e3 F& m8 i
buttonSelImage.pack() H$ Q0 M8 T4 T
app.mainloop()
" n7 l4 E' Q/ `. I* ]/ I
# h* w- H1 d- ^9 E/ c) F3.说明3 A# y0 `1 g' O4 { z
首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。
O6 [3 u4 g& Y* _6 d
! X4 P3 P# C/ u0 R* h- n! X$ L1 u+ X N7 e
, u, w4 {8 R( r6 Z! b0 T 其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片
# S# W( l$ D6 H [8 m+ \9 r, J# \% k
* z, j0 k& e3 n, I/ J, Z5 W, t! J
* ~% ~! ^" w. p J 但是效果会存在色彩的失真,效果如下:, ^8 d; ^; A$ A8 |
; z1 [6 ^. q+ ]0 D4 w% b
; z" g$ p$ Z8 I/ k( q! E* A2 X
1 T, q8 m4 u1 R也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。2 I. v- f) p2 o! ?# b+ A
( X# y4 [' |! z. A( @8 V2 p
这里简单提下PIL的九种不同图片模式:2 `" A: u/ F) @+ d& z: [
& |- ]- x- x) N hmodes 描述$ E1 q8 v9 S5 U9 C) @
1 1位像素,黑和白,存成8位的像素
3 Q% V! @3 J$ x, r# R1 s* S0 PL 8位像素,黑白; j; s/ [" ]7 \& y. C0 J2 [
P 8位像素,使用调色板映射到任何其他模式
* b& [7 h( v% I) R$ s/ TRGB 3× 8位像素,真彩
3 K3 o6 i$ j( G, ~0 m5 @RGBA 4×8位像素,真彩+透明通道/ V$ S# e+ ^2 A& e. F
CMYK 4×8位像素,颜色隔离
, x; T4 {# D9 {9 N& SYCbCr 3×8位像素,彩色视频格式& b- g {2 @% |' e9 @4 c
I 32位整型像素6 K* r, o: {2 o* N. J& d
F 32位浮点型像素
1 m; u% |, z5 m7 m S7 U4.实现效果2 J3 f6 {) i9 a6 E, o6 C: v# @7 F0 Q
]5 C; j) H) Q }$ `& o: u1 V. s! N8 X4 G: m( M; q& }
" j& J1 I3 r! F% H# K; O( f8 a/ J0 T
可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。
! a- l0 w4 D9 ?5 K———————————————— J# w! e t* m' S
版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。9 P; T- N, J: U6 L0 u
原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288
u; P) t* O! P: j+ I3 r7 G0 z7 f) \6 J
$ C* n1 B2 G9 _9 o1 s |
zan
|