- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 563241 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 174195
- 相册
- 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实现人脸捕捉与人脸识别(照片对比)
. z7 E+ P! O- J! w) ^* R/ x2 q1 g6 y O! J* G
1.安装包依赖$ x& G Y+ F8 p1 n$ p
与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。
* s1 V- J4 a2 y U, {( [" a: u. D8 o6 m' y) X7 h
在python 3以上版本tkinter是环境自带的,所以这里不需要安装) s" H0 } e0 D
- M' a% B$ e o! W0 b# o( [2.代码示例
2 I) j. v; r5 g/ Dimport os+ }) Y" V0 V% v. \$ J$ R
import cv20 Q( ]6 k# y6 ]! J( O8 U+ F+ o
import numpy as np5 d- t, ^4 N2 s& P' _/ K: T: w
import face_recognition
+ R, \& k6 Z5 B! ^- [- S6 eimport tkinter as tk
/ m( q) l4 s: F' [: n( limport tkinter.filedialog
8 }/ Z' U% O6 d" D5 y) Vfrom PIL import Image,ImageTk + w r o0 d' a
2 V/ I; W/ }( R, ]* P8 Q9 O
classNames=[]
+ m& J& o# q: Y4 {2 b5 P; ~! Bimg_path='Picture'/ C# |- D; |$ p2 @. K- u
img_recognition_path='Recognition'/ s1 H9 O$ P* l3 Z& }
existsEncodeingList=[]
" s; V. S* G9 @' X& G#对人脸集合进行编码进行处理 c* R' ~3 z% z. b! m
def findEncodeings(images):6 O4 L6 n/ s8 U) L
for img in images:. t: w# _: I) r- r) Q5 \
#灰度处理4 M- X, m. S: S* X( x9 x* N3 l/ b$ B
img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB). D$ V1 T$ r5 q& y+ h
#face_encodings对图片对象a_images进行编码并返回数组0位置编码结果8 U- L8 k$ |0 j3 d
encode=face_recognition.face_encodings(img)[0]
' H7 w% s9 |- Y, |6 T2 Y existsEncodeingList.append(encode)6 T: Y% H8 `) Z2 e# z* F6 F# t" Y
. O, ~1 x, y' Y#获取当前存储的人脸编码集合) \; ]- A- G# m- m- I6 d
def findExistsEncodeingList(img_path):6 c+ g: ?3 ?$ H! F4 Y4 ~/ f+ ^! I
images=[]
- ]% |( m, h! C8 u #列出已经上传的所有图片
& l6 @, u- h% ~/ I* e( @5 v+ \( u: _ imgList=os.listdir(img_path)
) ?% ~0 ?& s |4 b* T #处理存储的图片得到其人脸编码) \( c- i, K2 N+ a
for pic in imgList:
" j: n3 a I3 z s$ S img=cv2.imread('{}/{}'.format(img_path,pic))
! s. w% j( W9 q3 } images.append(img)2 ?. P+ a5 O, M, O- ~
classNames.append(os.path.splitext(pic)[0]): W( {7 U' V& `5 c: c2 J
findEncodeings(images)
1 {6 { U: D1 P1 v
/ K% z5 T6 Z& E#选择并对比图片4 v4 `+ ~1 c9 w. ^0 W; z# S$ I
def choosepic():
{$ g) W* k& e8 j9 @ choosepath = tkinter.filedialog.askopenfilename()) j8 S* L9 f5 U+ W: A' {4 r# i8 ?5 }
path.set(choosepath)# `. E q$ S& S, e) L
img_open = Image.open(entry.get()).resize((530,750))3 q: f8 K. t7 o3 W( {* w; Q
img = ImageTk.PhotoImage(img_open)
/ U+ e, Z# `" h lableShowImage.config(image=img)( k; H' |9 O4 ?! j+ R* W% A" {5 \
lableShowImage.image = img
6 r/ c& ]) A2 a7 z9 ] lableShowImage.place(x=30, y=70, width=530, height=750)
: J* p: u% P' m, G faceRecognition(choosepath)0 A0 Y1 |: ^ s8 _
$ I8 l- A/ ~1 Q" }def faceRecognition(choosepath):
$ ~9 c. p6 g5 ~1 A+ @+ e frame=cv2.imread(choosepath)
+ Z, r' \; }0 S frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)$ b. }2 |0 c& X- ?4 Q( I
#对摄像头读取的检测人脸
+ n; H+ R8 o( y4 _ facesLocate=face_recognition.face_locations(frameRGB)& X; F% D( a/ m0 x Y
#进行特征编码& z$ b7 q& E+ d9 s
faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)" t) K. ~0 h* f5 y
#遍历检测的人脸和库中读取的图片进行对比,计算其相似度
. R+ f# P9 l- `- V/ N name='unknow'
2 A4 v4 f2 Z: j0 I0 E! ?: u for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):4 |& s9 [/ ^- y: |2 c
#进行匹配
3 [& v! c( A8 T5 Q7 J matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)
# ]3 q9 D% ^' J. O1 m #计算相似度
$ H' P# _ g; y1 c6 z distance=face_recognition.face_distance(existsEncodeingList,face_encoding)
4 I& E1 L/ A* m* m lab='unknow'6 H, |) S9 X" \9 M, B7 [: u
for index, item in enumerate(distance):
% D5 @ h0 h1 j& i o+ z. w if item<0.5:
2 b! a4 n: {* S7 ?( w7 T% R if matchs[index]:7 B9 J( `8 k! N5 q- \8 b
#得到匹配到的图片名称与相似度值: r5 D3 j! c9 {7 r! c0 o
lab='name:{}; Similarity:{}'.format(classNames[index],item)
8 k0 I! h; q; E5 d! a, G& e name=classNames[index]
/ Q5 C, |+ n) C break
( r2 G7 E/ H6 \' o$ a- V! n #初始化面部捕捉框显示绿色' E' [0 ~2 G: h3 T9 L$ X1 t, I
color1 =(0,255,0)
: a$ p" R' \4 S if name =='unknow':
6 L1 W; [: ^8 k! o #未能识别的时候显示蓝色
. p6 c7 _6 I5 F# e color1 =(255,0,0)
F1 Y( w) Q9 Y" C- x+ S #画面部捕捉框
1 x, W I1 b. ^% J, G cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)
3 v7 ~% G2 o \& B #在捕捉框上添加匹配到的图片信息
+ T0 p# L/ s% t cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)
6 i- I3 ^8 [$ y' ]7 E+ f' P3 y% g& g cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)
C) l. U+ X3 @- \ img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))
) j2 e& ~. X' t! p img = ImageTk.PhotoImage(img_Recognition)
- y$ Q+ j& m: W7 M lableShowImage2.config(image=img)
- z# K" B5 l2 P+ m7 _7 S lableShowImage2.image = img
, Y/ A" f+ G4 G lableShowImage2.place(x=630, y=70, width=530, height=750)
0 q4 _8 V) U) F/ P* h
" @$ |- Y2 i8 o" ] S+ }if __name__ == '__main__':6 t* i/ j6 t& ^6 v
findExistsEncodeingList(img_path)
: ~- j9 v$ L, R0 Q2 ?* E #生成tk界面 app即主窗口
7 m' s% r2 T1 | app = tk.Tk()
9 a/ i( t. L. l #修改窗口titile- }# ^9 Q+ S8 j- C! I
app.title("show pictue")
+ y, U' Y7 Z! v3 s3 M6 [ #设置主窗口的大小和位置7 @2 A& T6 k$ g4 d
app.geometry("1200x900+200+50")
" @. D0 A1 j* f1 ~# D #Entry widget which allows displaying simple text., G9 J& l$ i2 x5 C( U
path = tk.StringVar()
) @2 P7 m$ y$ J6 }: P entry = tk.Entry(app, state='readonly', text=path,width = 100)4 P" v a W. |9 P7 x$ P) D
entry.pack()
& a, V* V# _. x #使用Label显示图片7 e- Y' p i+ m L4 R- H$ v+ ?8 D+ U0 \8 o
lableShowImage = tk.Label(app)% @5 b# J* w- P/ Q6 U& x* U
lableShowImage.pack()
; W' f% ?; r& g3 E #使用Label2显示处理后的图片
( b1 b8 Z T8 J& | B) I1 J' x lableShowImage2 = tk.Label(app)
- Q# [4 E; Y% Y0 n8 j, f lableShowImage2.pack()
/ v. X& g7 a7 L+ V1 p5 l" o #选择图片的按钮
; I/ z/ D1 g# H4 \4 w; P% g6 _ buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)
) e* Z+ x- _ b6 ?+ S. y" L$ A buttonSelImage.pack()
4 a$ r s! \( B; ^0 O q app.mainloop()8 R" @' [1 o V: M: f B7 @
' i# A% W+ T/ b
3.说明0 e$ p* ]8 L1 ~ ]3 g$ h4 j! x
首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。
0 t( p# j1 \7 g/ i' Y. G
5 T; A' F6 R' v% I( a# A; q
( _! t9 C& D! @6 c" E! t3 m. R( @1 Z, V
其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片# [# y5 U0 p" a. g0 l
$ v2 g" q" g( V2 W! A/ g
4 s5 J; q& \& V- D- G @! |
* ^9 y1 b! S: M# T! }: u" U" \
但是效果会存在色彩的失真,效果如下:) w5 x- h+ t& P& m
3 r0 r& x( t/ V7 k2 @. V" Z0 H; k
& [. I" J( ?1 d# p- B也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。
! E" ?0 m! [' d3 E) n- M* F! t! T1 @$ j; F6 C& e
这里简单提下PIL的九种不同图片模式:
' l7 y) H' z% c# J+ Q
1 n1 y5 k1 ?" F/ nmodes 描述 `0 Q! x3 ^0 a7 v8 X. U2 | i" P
1 1位像素,黑和白,存成8位的像素" x" {8 _' ] q: ^* b
L 8位像素,黑白- O0 S6 x" r( Y7 M7 ^! N9 x
P 8位像素,使用调色板映射到任何其他模式6 M/ L) J* N" Z
RGB 3× 8位像素,真彩
- M% |' K4 h; O6 @' { H% eRGBA 4×8位像素,真彩+透明通道: ? {) h- v) b, l$ j9 |5 r6 v3 r
CMYK 4×8位像素,颜色隔离' g0 b; [; i! @- F
YCbCr 3×8位像素,彩色视频格式: _9 E4 E! H, x7 a: ]2 X) u* M
I 32位整型像素8 o$ Y2 z/ U8 W' N- R- N
F 32位浮点型像素. O: {2 \; }; N( S8 P2 U
4.实现效果
0 E( k% U5 _2 _* R( E: l; M: P0 p" F. J
/ x" u. G4 O; W- n+ `. K+ s
# l6 O, c8 ] k ]" h/ j7 l
2 \$ _) n3 A6 J0 |6 _ 可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。0 s. V- W( j7 w9 S) t% J' X: n
————————————————
x) V% I, ]' n; \版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。( I3 Q5 y9 I# l5 u4 E7 D
原文链接:https://blog.csdn.net/qq_17486399/article/details/1266292882 U1 m9 K. s! ]
! Z& a, ]8 L8 U7 t( R& O
, g! n9 I, i3 N
|
zan
|