- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 565162 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 174771
- 相册
- 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 a* p# |3 N5 j( Z! u- M+ z' c& E) r8 _7 G6 V
1.安装包依赖0 |. ]# K3 h) m, [& L% U+ a( t$ f" \
与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。2 q% \. Z. \" [. Z- ?8 k
! S5 r" _' k7 ?在python 3以上版本tkinter是环境自带的,所以这里不需要安装
7 O7 O8 B; z% G1 u
6 |# s! S. L' k2.代码示例4 | G. Y, {( o+ H1 x' Z
import os
/ C7 g6 W) R$ o; L, ]import cv2! J5 Q3 w4 m& h$ Q( Z0 L& x
import numpy as np: r6 G8 P, `/ E B
import face_recognition% L3 D6 ^1 Z# E) V2 Y* i
import tkinter as tk 0 q* w2 N" }' H( [' \1 @
import tkinter.filedialog
% c$ z$ [. q2 L6 n! S5 {) Tfrom PIL import Image,ImageTk
1 r* i8 z4 r1 Z: m8 |! {' b1 D3 T" K, v5 k# ?) C! P
classNames=[]
8 K, a5 ~- z$ K2 U, Iimg_path='Picture'
4 L% J5 }5 q( E. Ximg_recognition_path='Recognition'. Q! I6 `0 h, D; W; c0 `! K2 b6 k
existsEncodeingList=[]
( g& F v+ H1 i4 n8 n! F#对人脸集合进行编码进行处理
' q; V" t" T# x8 adef findEncodeings(images):) J( } }0 h$ _: y
for img in images:3 q8 N+ t' c7 y% `3 }( v7 o" e
#灰度处理; ` @6 R; f& t
img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)
* f& L r1 N( s9 R) X #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果
( ~$ k& ?- F) N. w% `1 y) c encode=face_recognition.face_encodings(img)[0]
$ Y0 r4 {/ [4 s) r: N; m existsEncodeingList.append(encode)
8 B% e/ A1 w3 K* l
! H* n- n9 {0 ?# L/ |#获取当前存储的人脸编码集合
# D! N# `* U/ i" cdef findExistsEncodeingList(img_path):- ], n c" s. L; d. G) H, C) _
images=[]
% A% k: ^& L7 ~9 b2 Q* ^7 B #列出已经上传的所有图片$ o" o5 o4 U ]2 T* t6 X
imgList=os.listdir(img_path)
+ n" I! c% [3 H; h #处理存储的图片得到其人脸编码
e- w$ I6 t* @3 H& I for pic in imgList:- p& g& s: [6 Y4 B+ X
img=cv2.imread('{}/{}'.format(img_path,pic))7 ]) T, u4 I: U8 ]# B6 a# \0 |$ B
images.append(img)
; X9 T4 }( h$ `9 P* I B, U9 Y" g classNames.append(os.path.splitext(pic)[0])# w+ J' E# r2 K, p) H! v& l
findEncodeings(images) u6 w' E( }& n8 d' T
( Z" x% l9 U" r* i; l#选择并对比图片
( D" g0 @1 O: f3 }% Y* [# zdef choosepic():
' A4 }/ U e9 d; h4 l; | choosepath = tkinter.filedialog.askopenfilename()
; J+ K7 e: h* N/ V% g path.set(choosepath)$ Z9 T/ X O- G( g8 G- S
img_open = Image.open(entry.get()).resize((530,750))
2 ^. m9 C$ r+ q+ E1 n) }' y img = ImageTk.PhotoImage(img_open)
* C, u( G( p" C3 U0 @ lableShowImage.config(image=img)
, \( S+ O' I! O6 Q lableShowImage.image = img8 k9 Y: T0 J7 p. n& \' |: F2 d
lableShowImage.place(x=30, y=70, width=530, height=750)
5 j, Y, o0 X o7 t( @6 Q faceRecognition(choosepath)3 o% Q1 Q) I. i: L# O( O
9 v! u( \1 b) ]+ d/ z* Cdef faceRecognition(choosepath):
4 N$ b, f# {2 n frame=cv2.imread(choosepath)" V, A: R, z# M# w9 j6 z
frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
! }/ e0 o% u. b. Q/ E3 V #对摄像头读取的检测人脸
& {) \3 |3 s8 w9 A1 s- T facesLocate=face_recognition.face_locations(frameRGB)1 s, R7 I9 H i+ }# c. A' j) s
#进行特征编码
, a8 k% c( h7 ^% s& n5 n- m! M faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)" P! \9 X5 }- `$ H& K9 u; O3 z
#遍历检测的人脸和库中读取的图片进行对比,计算其相似度- ^7 P" m* `1 ?! H
name='unknow'
7 Y6 s" \* x- \! A. Y6 S; o for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):
K; C; e' d# p9 q7 G: j #进行匹配
6 F" ^6 S Q2 j: }! {9 Q# c matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding): s' j( Y. F4 i% L
#计算相似度& T& H% ^4 h) g" g0 D$ i' M% S8 s
distance=face_recognition.face_distance(existsEncodeingList,face_encoding)
5 v! ~) h' F& A2 K$ v! Z lab='unknow'9 s C4 T3 @4 S, K2 f
for index, item in enumerate(distance):
- p- a- `" w1 L- A9 C if item<0.5:
: h- U9 c3 I3 k+ ~ if matchs[index]:" L& M& g( A) j e7 o
#得到匹配到的图片名称与相似度值
% T+ O+ G" j' e2 Z lab='name:{}; Similarity:{}'.format(classNames[index],item)5 H! ]( t& n n( g; m
name=classNames[index]
; @; O' u( h' a* {) I7 V4 ^. \ break
+ }2 f) i6 {9 ]9 q2 \$ {; S& ~* R9 c #初始化面部捕捉框显示绿色
9 v$ L- H( H! v0 ~0 }& N/ q color1 =(0,255,0)3 F# c9 R# x. g/ p( U
if name =='unknow':
. X$ |9 R% D# r. y #未能识别的时候显示蓝色
: `3 b: J0 R) E, y' e: ^# b color1 =(255,0,0)
/ q& U/ d) l: U+ H) K' z #画面部捕捉框
; R2 |7 e9 k" L6 C' X cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)3 a4 j) Z# |) ~2 ^. D* _! h
#在捕捉框上添加匹配到的图片信息
9 }$ @! `9 c7 u cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)
9 g3 |* Z# E @4 ^9 e# A cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)* u% v% f4 ?4 I/ o
img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))% \0 C0 |" q4 O1 B, v. S
img = ImageTk.PhotoImage(img_Recognition). a- y( b9 K' n% C6 n3 {, a
lableShowImage2.config(image=img)
0 t ?" _9 L# e/ N* d7 }5 S7 C lableShowImage2.image = img
0 f" Z |; R6 e( \ lableShowImage2.place(x=630, y=70, width=530, height=750)' {7 z3 H, R, {7 b
, x. c1 q/ p) e& uif __name__ == '__main__':5 |0 H# v8 z5 E' F* Z- x
findExistsEncodeingList(img_path)& K2 X* T5 j0 L, @ f" Q% o! ]
#生成tk界面 app即主窗口4 m; V' n5 M& G- |1 F. B
app = tk.Tk() 1 r: C* g* {' @( F5 L" c
#修改窗口titile
# `' k+ b5 q% h7 g: h8 ?* b( M; g app.title("show pictue") ' R/ z1 _* x$ Y
#设置主窗口的大小和位置
% |$ q- Y: n9 G' c# ] app.geometry("1200x900+200+50")6 F: f# z) _% o8 P7 r, H( J( P
#Entry widget which allows displaying simple text.
2 |1 V2 z7 V: h0 o path = tk.StringVar()# N3 r3 s9 M$ [) w1 W3 e, } \1 N
entry = tk.Entry(app, state='readonly', text=path,width = 100)
( G3 t9 P/ W3 ^' f entry.pack(): P6 Y# ^' p6 p1 L
#使用Label显示图片
# t \7 ?( l0 j lableShowImage = tk.Label(app)* Z* }' @' D* |1 L, |6 d% M' }% U
lableShowImage.pack()$ b, }4 F9 B- H# Q, X0 ?/ ~! Y
#使用Label2显示处理后的图片
& J6 @8 Y8 {5 W lableShowImage2 = tk.Label(app)
. } {1 l# m9 k3 D. b lableShowImage2.pack()* H, x) p" U8 w% M
#选择图片的按钮
R+ V2 K) u8 T* h1 p d- G buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)
- ^/ D' A n) f G, c2 G2 J buttonSelImage.pack()' F: @. |9 r U; L, I
app.mainloop()
& s" c, O* K. J6 j; @8 r
- C$ F G# e- t6 n0 m+ i; i' {3 Q3.说明: Z8 s0 B+ v+ u% q+ T
首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。( N- D8 L% |4 u5 N4 w" @
6 d& i- g# Q6 W4 u
, M% n/ p! Z$ U
3 D9 D; @/ d$ x4 y$ ^" v; R# S 其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片
' f( J# E# q% f1 [; x; s
+ @# Q! N$ l6 @4 B! ?5 L8 C: F
7 J2 ?9 g) `: A! X q& ?* `/ H# w& Y9 T
- g1 ]; K, s) X 但是效果会存在色彩的失真,效果如下:
( m, l+ p% D4 M2 m; p
; R8 t9 c4 D* u/ P$ ~$ ]& k( x5 n F) s+ K
& Q! x+ i. x& k1 ~# Z8 S也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。: T" U/ |" e! {, `; F
9 T" t" X0 F, p1 v' O
这里简单提下PIL的九种不同图片模式:$ P( w3 N# ?2 r7 X* k6 c
- V/ T3 O8 r( f' nmodes 描述
' q' ~2 G, V! w7 N" k# ~1 1位像素,黑和白,存成8位的像素
; r8 O6 V n, X0 F: _L 8位像素,黑白
+ Y7 F* B5 G% J4 ]2 g/ {P 8位像素,使用调色板映射到任何其他模式
: g" W' j! K$ G0 MRGB 3× 8位像素,真彩( G3 c/ ^' c( m; Z( |
RGBA 4×8位像素,真彩+透明通道; Q% p/ K2 p& M4 [4 G. S
CMYK 4×8位像素,颜色隔离. A9 y9 f+ [ a0 z) l
YCbCr 3×8位像素,彩色视频格式) ~5 W; D6 f7 J' L' P# K
I 32位整型像素
( b* k' L8 F+ _) Y9 CF 32位浮点型像素
$ v0 a2 c/ Z2 q4.实现效果
+ \/ M U2 T, J3 ~. d; J- k5 K- p: p0 n( R3 h. `6 [9 d
1 [ {1 R5 L0 f. ]
$ I1 n$ x' ~5 N; @7 k" a
/ @1 x! v* M: B# s+ ^
可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。
2 j4 R4 c$ p9 M( V————————————————5 v8 B1 s: [# u+ t# u
版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。: u( i) o' Q4 `7 I3 q/ p
原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288
1 Q; p& y" v- E+ ^ M* U: C, u/ E; m+ r( V
1 N# Y. H+ r; _, }1 ~1 ^) h% O' b5 S
|
zan
|