- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 562731 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 174192
- 相册
- 1
- 日志
- 0
- 记录
- 0
- 帖子
- 5313
- 主题
- 5273
- 精华
- 18
- 分享
- 0
- 好友
- 163
TA的每日心情 | 开心 2021-8-11 17:59 |
|---|
签到天数: 17 天 [LV.4]偶尔看看III 网络挑战赛参赛者 网络挑战赛参赛者 - 自我介绍
- 本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。
 群组: 2018美赛大象算法课程 群组: 2018美赛护航培训课程 群组: 2019年 数学中国站长建 群组: 2019年数据分析师课程 群组: 2018年大象老师国赛优 |
Python 基于OpenCV+face_recognition实现人脸捕捉与人脸识别(照片对比)$ G" w3 _- U; O, D9 ?' |0 }" B- z
2 G7 H6 |" c' P$ z* p6 O: Z& A
1.安装包依赖) s& D8 i( j/ ^% L% H$ y0 N+ u
与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。
4 u3 x9 q- @! n" F2 f4 w D/ A8 h0 Q: j- U1 \ F5 @
在python 3以上版本tkinter是环境自带的,所以这里不需要安装2 S( E1 E* t- G! I8 q
& L8 u8 Q% y$ k! U
2.代码示例3 f1 M2 L I+ K* f
import os) { e# f7 x5 O$ k1 Q- k
import cv2
0 w8 M8 y! g4 \8 Timport numpy as np* D7 }- N% {- q( \7 k6 R4 n
import face_recognition
) }( D9 v2 l; m- Z( Wimport tkinter as tk - |5 ~2 m8 p5 h/ t/ l# Q" X
import tkinter.filedialog+ n7 b$ h4 _& v8 y- M Z, V+ f
from PIL import Image,ImageTk 8 Z0 [- Q$ H3 g
+ b5 ], M* d) @1 v3 d3 HclassNames=[]
7 k) k* v+ s3 X% W2 uimg_path='Picture'+ r. Y6 ]- N2 H9 }0 \! g% t3 B
img_recognition_path='Recognition'
5 h! f$ P4 C4 e( h0 X% LexistsEncodeingList=[]8 f0 T$ r8 r2 w' j2 {, C3 ~ I
#对人脸集合进行编码进行处理
; k Y9 P A8 Hdef findEncodeings(images):. C1 X7 u3 \" o: j) B* ?
for img in images:6 G6 ~* A; e' ]/ n; B
#灰度处理3 F( a5 w6 N- n. T6 M$ W" b/ ~
img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)6 @. X$ j5 G4 b5 [ ^
#face_encodings对图片对象a_images进行编码并返回数组0位置编码结果. E7 o' K, I7 Z8 m
encode=face_recognition.face_encodings(img)[0]
6 u6 `4 x6 c; W. h! P' X existsEncodeingList.append(encode)# R* C+ ], i: I, }. V
1 n% y% F1 j) s% j# R1 R3 {4 j
#获取当前存储的人脸编码集合
7 V: f# m' L) Bdef findExistsEncodeingList(img_path):8 ~& T2 @0 K7 T% R" l2 g
images=[]
: k5 q$ y! s; E! q) v. p #列出已经上传的所有图片; @- M" W0 z" c# j6 }; r8 n {7 A
imgList=os.listdir(img_path)* a" p- K: |. ?% Y: N8 j' n8 @
#处理存储的图片得到其人脸编码
$ i! {3 D l8 C for pic in imgList:
5 [% G9 \7 S5 ?! s img=cv2.imread('{}/{}'.format(img_path,pic))) e, z) g9 M+ w- s L1 }% O' A
images.append(img), x0 J% v: ?( \8 D
classNames.append(os.path.splitext(pic)[0])/ x- Q6 O4 b7 ^) w
findEncodeings(images)
+ H8 G9 l5 O) i3 A) @; f5 V! s) L7 n e, g3 _: ^
#选择并对比图片
+ y3 H3 p# s2 Kdef choosepic():! A0 W4 h" U. m0 t& v( S
choosepath = tkinter.filedialog.askopenfilename()" J& Y8 j/ f+ R/ A+ l& e; s8 o
path.set(choosepath)
2 K9 u; P( ^* A; c T img_open = Image.open(entry.get()).resize((530,750))5 _ z; u* I) `
img = ImageTk.PhotoImage(img_open)
8 X: @/ u5 b [) \ lableShowImage.config(image=img), @4 [- ?: x& S/ g
lableShowImage.image = img
% k& H d$ W% r7 p4 D; q lableShowImage.place(x=30, y=70, width=530, height=750)
1 B I2 X$ Y1 f faceRecognition(choosepath)+ }: |: O- f7 u9 Q/ Y, \
/ G# _7 c3 ?8 A8 u$ D% d
def faceRecognition(choosepath):: N5 V I$ i& I2 {1 U& e
frame=cv2.imread(choosepath)
! d( `! j6 R% O p frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)/ Z4 {6 u1 Z; _2 P/ g
#对摄像头读取的检测人脸
" b" z3 v X$ b E; t L7 w6 b: ? facesLocate=face_recognition.face_locations(frameRGB)& ?2 R/ i0 T( b* X( _5 y1 U
#进行特征编码' A' s: B' v, O; g4 n
faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)
: f9 ?# r! F& W9 Y# c* T #遍历检测的人脸和库中读取的图片进行对比,计算其相似度, E- [3 ^0 q0 G! c6 G+ ]4 d5 J, w
name='unknow'
% n3 D2 r$ W0 A! i7 k' P for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):' y, f' f& d8 |5 t8 G' S# |
#进行匹配
( T, [6 B% W/ d3 k% S+ d matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)& o0 \+ r+ h+ C: ]7 j2 ]& ^& @
#计算相似度
, y/ a3 j# j( E* F& a. D distance=face_recognition.face_distance(existsEncodeingList,face_encoding). J5 B$ p% x4 J3 \ x
lab='unknow'$ v; o' k3 H$ y
for index, item in enumerate(distance):" O1 o! E1 T0 [) A& {
if item<0.5:
5 A' T s3 Y6 ^8 E8 k/ W- P if matchs[index]:
0 S% k3 y- q+ y% x) ?8 f. C4 w0 G( n/ l #得到匹配到的图片名称与相似度值; F% z' |2 a4 w8 o8 \; p8 p
lab='name:{}; Similarity:{}'.format(classNames[index],item)5 |' {8 A" A0 K
name=classNames[index]% o! w0 ]4 D0 z* K
break. k3 r% P5 L" `8 n& J5 l0 B
#初始化面部捕捉框显示绿色. v; \9 {& H! N: a6 q
color1 =(0,255,0)
4 l* C$ v4 }! Q/ r( J3 Q if name =='unknow':
7 m4 c7 W5 v( L& i% v, b #未能识别的时候显示蓝色
0 ]- c ?% o6 b1 X/ ?- k color1 =(255,0,0)
1 U. k- K5 ]9 j #画面部捕捉框
4 p$ a3 `! w* U cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)
9 { P/ f3 C7 x4 f& F' Y l: q #在捕捉框上添加匹配到的图片信息
x6 j% l, g) E- N) }4 Q+ p cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)
5 W& M# [5 ]2 G: V cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)
' C# S( m2 j2 k- ` img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))( B' P8 b9 [$ T8 D# j; v3 u
img = ImageTk.PhotoImage(img_Recognition)
5 `0 O: i5 y' s/ y/ m; f lableShowImage2.config(image=img)! O% n8 z. ?7 c1 A) J
lableShowImage2.image = img
7 u. y" v5 t0 U" R/ O- O3 h- [/ o lableShowImage2.place(x=630, y=70, width=530, height=750)
, x7 l% I3 e5 d1 `7 I% c+ g( |5 J/ Q7 @1 N1 d7 J
if __name__ == '__main__':
. H" H/ u. y( D, x findExistsEncodeingList(img_path)2 y! i, w, B* X5 L1 J7 @
#生成tk界面 app即主窗口
. H6 ~% i& w: f( T; f) { app = tk.Tk() , @ P, ?" h/ M7 }6 }6 }' O, j
#修改窗口titile
" H9 P8 L" q# k9 t3 } app.title("show pictue")
6 l! R5 ]- ~, N; _7 k) `5 c #设置主窗口的大小和位置# v: h$ [* F, Z; z6 ~4 ]
app.geometry("1200x900+200+50")" b2 d- O, ?1 W: B1 l( g6 |
#Entry widget which allows displaying simple text.4 O: t( d, m8 h3 c6 H
path = tk.StringVar()
2 s; H0 J) K9 A& O1 _9 ~8 q entry = tk.Entry(app, state='readonly', text=path,width = 100)
" R1 a! D q3 w9 W, h; e+ Z' Q. Y entry.pack()1 d0 W {8 G/ N" b9 v
#使用Label显示图片
+ U7 i8 T7 a! b, I3 Z0 \2 P2 v lableShowImage = tk.Label(app)) V4 M# a2 E" Z+ ~) [: Z
lableShowImage.pack(), O% t2 D* j* z4 m: ]* p! e" v
#使用Label2显示处理后的图片. W- r ?. ]7 e" k d1 `9 h
lableShowImage2 = tk.Label(app)
+ x9 V2 E9 s8 j7 E( A lableShowImage2.pack()
' @ T7 n# [. C1 t7 G #选择图片的按钮# K$ @- F/ ]4 X; w& [
buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)
9 l3 x4 y z2 i z/ @ buttonSelImage.pack()
* y; _% V1 g. Z8 f# _ app.mainloop()
; M m% l, j4 ~
# U! p' I2 W/ }) @0 |3.说明' ^+ a9 `( u. {; `8 i1 \
首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。
3 `( e |* N' N/ f$ k* G$ z9 U2 F, x) f) ^
' m! W0 I. [9 D7 T1 T: |( o6 B! @% A1 r' |* v8 U, M, L0 o
其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片
" E# n( F7 R. I3 k# ~1 y$ d* N* x D( b
" B# ~6 g4 \* V/ f/ |
% m9 J! ~! ^6 R4 r% U& A) l! S4 C 但是效果会存在色彩的失真,效果如下:# V0 C0 O8 T- P( ~1 E# K
0 V7 ^' A& |3 _
- {7 Y5 s. v3 E! V2 ?
! H" {# ~9 q* A- z2 @也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。
$ M$ N/ V9 W4 [4 k% n8 ~" k8 N, b% B: T4 J* a; N' L
这里简单提下PIL的九种不同图片模式:
3 l: q# @- w4 O- {. L3 r- N# T
6 [0 M8 p- T% Mmodes 描述
2 _4 l& b, o7 z. D' F% e1 1位像素,黑和白,存成8位的像素 a6 r( h4 n5 O( Y( U# ^+ e
L 8位像素,黑白
9 \3 T! S* R4 z- u. nP 8位像素,使用调色板映射到任何其他模式" U" y" [5 \. c0 R5 _9 g
RGB 3× 8位像素,真彩) u$ A5 ^6 T, t8 x, a
RGBA 4×8位像素,真彩+透明通道
5 L0 I5 e* k( o% A5 kCMYK 4×8位像素,颜色隔离
$ I, c: _- g$ ]7 C/ w) U/ J1 R+ jYCbCr 3×8位像素,彩色视频格式
1 y- i0 \7 W* A. b6 v- n6 EI 32位整型像素
3 V8 a6 o4 U9 G X2 EF 32位浮点型像素
. ]8 f+ y" Y; i4.实现效果
4 m X) W7 F$ Y& |1 H$ @% X8 W/ i" \# l2 U- p: |
9 H2 y( n: T5 y( ?5 i
$ C( j" T# Y% m
' }4 |" s* s$ k+ e3 R3 _- ?, Q 可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。
D* F% ]9 w; M————————————————
+ m4 C6 u: h* s7 C版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。. R- {. a; V2 D. j
原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288
( Y* C; l/ _6 d. T1 t% S$ w% m4 Q3 t. |3 M
. w4 \* J8 z* O% ]6 u |
zan
|