- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 564444 点
- 威望
- 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实现人脸捕捉与人脸识别(照片对比)0 l0 _4 p) p1 O4 \- n- R- k: s
* Z( I+ g6 J) K, S+ l1.安装包依赖$ t; N& k4 Z2 o: i( _
与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。+ p, \3 ^- ], \& o Q; ]! l" c5 g
6 X- F* Z" S$ t+ I4 ]5 n# B在python 3以上版本tkinter是环境自带的,所以这里不需要安装
1 ~8 G2 }0 a/ e0 j) ?, h8 l \) g* Q& B/ K. P, U
2.代码示例
! U6 W; c: [: d ~9 h9 ` Wimport os" e$ Z" d. I0 K9 I+ R# o
import cv2
4 j' Q- }# o, I7 N2 C' R7 L2 \import numpy as np' ?% ^6 s) a; M' Q
import face_recognition* X; n( a' J/ S+ v I
import tkinter as tk 2 _! U0 [: q; E
import tkinter.filedialog
! p. c, J) j# K# Jfrom PIL import Image,ImageTk + q8 M4 H- S+ n) w `& ?1 d4 j( r
B1 X, o: J$ S* N6 l+ w- ?! M
classNames=[], t) U4 T' v0 X8 }( S, o9 ?
img_path='Picture'4 ^: T) @ m, [$ |% M8 ^- E
img_recognition_path='Recognition' x8 r* B, t9 n8 h, J5 ]' X2 M; n
existsEncodeingList=[]$ s5 |1 o8 F P' H$ w! W9 y; X
#对人脸集合进行编码进行处理' A3 n+ r# m' z1 f% o
def findEncodeings(images):
' l+ G4 E$ o, B* s1 w, n for img in images:' ]/ u6 V! U4 j
#灰度处理
& t7 F u& v/ h1 z img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)
R. c4 N2 W; a2 S #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果 t" H* j8 S: Q' \$ R9 s8 Q
encode=face_recognition.face_encodings(img)[0]+ B) Z* u' M7 |8 S: m) S, ~7 O
existsEncodeingList.append(encode)6 e# o- X! U, v ]1 f
% c+ P) Q% P: n
#获取当前存储的人脸编码集合6 o. w x8 v! \) V" y6 `. J
def findExistsEncodeingList(img_path):
3 w0 }; V: n/ c images=[]
4 L+ N. v1 R+ t' v. T #列出已经上传的所有图片
( e* X( O1 U7 |) ?4 z imgList=os.listdir(img_path)
3 u) s4 x- e4 P* V' K' j #处理存储的图片得到其人脸编码
7 N: C8 @* p* y& l3 u) f) |" p for pic in imgList:
1 x. E1 _2 u6 G2 t1 h+ @9 ? img=cv2.imread('{}/{}'.format(img_path,pic))
, G3 z) c8 h1 |$ M* d6 Q, z images.append(img)9 f9 g" l$ j1 {; z" ^8 L
classNames.append(os.path.splitext(pic)[0])+ y5 r6 t2 X% ^1 u; f6 k+ V
findEncodeings(images)
$ p0 S& z: G9 x! y O9 u" ~. v* Z! G$ g. S; t
#选择并对比图片) d1 i3 N7 U3 N3 @8 F
def choosepic():! c$ b- r9 q4 h/ r8 C9 u8 { y
choosepath = tkinter.filedialog.askopenfilename()
: i8 a2 @1 B7 z. E path.set(choosepath)8 P5 |# s9 u* g# b4 @
img_open = Image.open(entry.get()).resize((530,750))9 Q$ d# z9 F O2 z- F2 V) W
img = ImageTk.PhotoImage(img_open)
& Q2 D7 K4 }2 C R1 L( c& X% | lableShowImage.config(image=img)+ w u/ T% k) r/ Y1 i) ^
lableShowImage.image = img4 P) u8 V# B2 m3 L( Z
lableShowImage.place(x=30, y=70, width=530, height=750)
; d4 O8 t, e3 Z7 Q- ` faceRecognition(choosepath)
$ _0 ?6 |2 a% \3 u1 ^3 o& U4 j, E9 [7 b+ L% T
def faceRecognition(choosepath):
5 b; O* j& k% ^# u I" }/ O4 i frame=cv2.imread(choosepath)
( a' E3 z8 [# {2 z+ G! L frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
3 T9 D3 c) ~' a* g, l+ c #对摄像头读取的检测人脸$ o9 x5 ~3 D4 g
facesLocate=face_recognition.face_locations(frameRGB)
5 i: F+ H( c U7 o #进行特征编码
& T$ p* p. K5 W' i3 @3 w7 Y1 W faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)% s6 D/ D3 M* @
#遍历检测的人脸和库中读取的图片进行对比,计算其相似度
- C6 p1 e( {/ u. g+ i, R1 n2 @ name='unknow'
% u+ ~+ y, f. H* h" @ for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):- w( z {6 r0 `) ]
#进行匹配9 y/ q$ \. r- R" G
matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)7 l/ ^' S2 @& {+ q& @2 H
#计算相似度
9 y: V8 P3 Y; C1 z, u distance=face_recognition.face_distance(existsEncodeingList,face_encoding)
( }1 Q1 M3 c% ?+ t! `, ?" L lab='unknow'
5 i; C5 R8 P }) z6 M4 I for index, item in enumerate(distance):
$ \, y" ~ ^: `- \3 u if item<0.5:) D0 L, }+ |$ v' I
if matchs[index]:
9 c0 Z- ~% g' N; }( L8 ^' m5 j #得到匹配到的图片名称与相似度值9 i- M0 I X+ Q4 u& ]
lab='name:{}; Similarity:{}'.format(classNames[index],item)
* ?$ x8 H7 g. F name=classNames[index]
7 g" [' V5 t4 g/ Z* t j( C/ n$ A break
- x. [9 ^- ~ s- ]# S# ` #初始化面部捕捉框显示绿色1 T( c! k. r' Q6 ]9 D: ]
color1 =(0,255,0)
* Y$ `; Q8 f* R3 U$ v if name =='unknow':
! a& k2 `7 \' g! X* c! x6 u #未能识别的时候显示蓝色
( F' m- U- t* R color1 =(255,0,0)
9 V% \" p% g) [$ }! u* T #画面部捕捉框
7 q, f) U* w, F( T+ j/ _ cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)9 I) M4 [: @' C$ J2 S n3 C
#在捕捉框上添加匹配到的图片信息
; {1 \* C: ^( w cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)8 i4 w( v: g7 P/ k0 H; H
cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)$ u& } l5 K+ M/ ?3 d( U7 v
img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))
; ~" X7 D. f& u+ \ img = ImageTk.PhotoImage(img_Recognition)1 v* U( K, D( }. O# E. p
lableShowImage2.config(image=img)
: Q9 Q1 P2 C3 X1 E lableShowImage2.image = img& i* }1 ] N7 b2 q: L
lableShowImage2.place(x=630, y=70, width=530, height=750)8 S4 w# n r" o- G" k: K
, P2 V8 h% ?% Dif __name__ == '__main__':' y* {! A8 V$ ?8 Q+ {! H5 c0 p
findExistsEncodeingList(img_path)
. m; H$ A$ g6 w2 { #生成tk界面 app即主窗口( i- m6 V7 l3 M) a! S2 D+ V. N$ W8 f
app = tk.Tk() * E: e V7 q9 ^) l1 `
#修改窗口titile
' P) n3 X, |/ A app.title("show pictue") - @3 \) I- T( c" Y3 A
#设置主窗口的大小和位置
! k2 k5 F( f$ ^$ D2 h" c9 s8 J app.geometry("1200x900+200+50")
! G+ p6 L/ k- J0 P* _+ c( [% ~ #Entry widget which allows displaying simple text.4 C; N9 E5 \* j, {- R p
path = tk.StringVar()+ }3 G3 o- k6 C/ z) A% e' T# Y
entry = tk.Entry(app, state='readonly', text=path,width = 100)) W. V! ]1 Q ?- B
entry.pack()5 X" I9 i6 c" l5 q2 t
#使用Label显示图片( z$ Y) n1 D( @# T6 U+ p" J8 x$ U$ A
lableShowImage = tk.Label(app)" b3 Q* f/ s1 w e2 l/ Z: F
lableShowImage.pack()
4 D" p7 q8 Z! b9 p$ e) l" K1 ~& q #使用Label2显示处理后的图片; w8 S) |, @" [+ _& L
lableShowImage2 = tk.Label(app)
$ z& ?: ~" P! \8 u5 t) @; V lableShowImage2.pack()4 x/ v! ?/ `( f5 i: N
#选择图片的按钮
$ H' y1 I! ?0 A4 z Z* { buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)0 K5 @- j3 I$ a0 Q% j" p- P5 t
buttonSelImage.pack(). q1 @/ L+ u" D/ J+ C# O+ [
app.mainloop()! a: l3 c. W% r
) }# K# j/ f; X! _" ]( v3.说明% x/ U1 F1 p7 U, n# I" `: L
首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。$ b$ l, o4 A& Z, u, ?/ }: b
* M( i) Z( b9 f' f1 o( ?) b- M
5 c6 d8 r0 x$ O% E \7 y) v% i" r
2 t* F! f# s8 c 其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片
4 k; T. l; ?7 b% }, d2 [+ S/ U* L P/ V% B. x" r: r$ g. }3 [ ?
: j. A2 @) ^! K3 ]! u7 T8 V
, q( N- u* T9 B p 但是效果会存在色彩的失真,效果如下:
$ ]7 Z# n+ ?1 w: ? U0 j$ B8 Q0 q+ F$ F; W8 {) Y i2 q
8 |, v/ q8 e9 N' ]! R7 ?5 n0 Q$ c4 L+ D) k+ q+ w
也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。
: H8 U y1 ?: @8 i" L
, _; I7 g" Z% K, E' ^% m) {; F这里简单提下PIL的九种不同图片模式:8 j8 \0 |0 k9 `! }
% s) l2 U' k7 B* n5 Bmodes 描述
8 e- Z0 I5 F) t. M, B1 1位像素,黑和白,存成8位的像素2 y% v* Y: N3 {" B4 m' c
L 8位像素,黑白
. n1 a4 v, a" o' D/ l! W+ G8 kP 8位像素,使用调色板映射到任何其他模式
{4 [8 {0 s' W ?+ dRGB 3× 8位像素,真彩
7 R; U5 E3 C+ Q$ C* B: ~RGBA 4×8位像素,真彩+透明通道4 }- \3 T }# C* E# t$ \. T
CMYK 4×8位像素,颜色隔离; Q9 s: |, F3 F1 `& D# F9 O
YCbCr 3×8位像素,彩色视频格式2 u5 X& J9 f I, R& r8 k/ t
I 32位整型像素
8 }- o1 M0 }# d/ d8 v: RF 32位浮点型像素
3 @" ], W5 x' @9 h0 m" @4.实现效果* r% N% k x* O: S \
4 {0 _4 ?, d, r8 [ b- q9 `' f
$ T' s# o, K/ ?
. O/ I& c, n* b0 M+ i3 ~, S1 o2 B
, N# ?" |" _) B, C, ?6 d 可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。
+ J5 q, g" e4 R0 q; t7 f3 w————————————————- l6 e- A- ^ T w7 x3 t! i
版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
: |# E" d0 t3 ]7 c. S# N3 g原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288
( u6 q# i: c, j
, K2 v# _6 j( g2 {! C; }( ?
: A8 y8 {$ ]9 U, z8 p" A |
zan
|