- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 563412 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 174246
- 相册
- 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实现人脸捕捉与人脸识别(照片对比)
# K7 | n0 a% C+ w
J6 R* f2 m( m5 x4 v! |6 K- g1.安装包依赖
" j" g" ]# p8 F) x2 U: N与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。5 e2 p( ^$ U7 B l" ~
1 d% O' w0 i7 `在python 3以上版本tkinter是环境自带的,所以这里不需要安装
- {# [$ H, Z7 a& \
7 ^' v; E& Q. l( f$ X8 S2.代码示例
% U+ \$ o! G. {import os, d8 |1 D3 {7 ~6 g; u3 e% c* {
import cv2) i6 _: c) D& V! Z" W* P
import numpy as np
% |: E3 Q$ |7 zimport face_recognition+ e% \$ C. q% T8 B# d, P
import tkinter as tk
4 R# D5 a) V5 U! I2 P8 d* y/ Simport tkinter.filedialog
# z8 E9 D0 I0 f/ ?3 o6 G6 xfrom PIL import Image,ImageTk + K! O( q7 u: V1 S6 [
. x! n5 j7 n) F9 v% t! ?
classNames=[] H; _/ A! H6 c0 H! l% R2 k
img_path='Picture'
2 r2 e0 Q! h! X6 Rimg_recognition_path='Recognition'
+ m1 l$ ~# A" R! vexistsEncodeingList=[]
+ d2 D4 s* n: p. U& N* ?$ I#对人脸集合进行编码进行处理" u; X% ^: J" y# m! U5 k
def findEncodeings(images):/ G$ H$ ~' i. H# l
for img in images:" Q" k/ k2 |8 M& O4 u& j
#灰度处理( ?0 |% B( B2 A- G3 O P8 Z
img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)# ]0 m1 R% F5 s
#face_encodings对图片对象a_images进行编码并返回数组0位置编码结果. y% S3 T8 k6 t
encode=face_recognition.face_encodings(img)[0]
. w! \) b$ m' Q X3 l- a2 z# N existsEncodeingList.append(encode)
* j& { C' I; b8 {8 z$ a/ w6 Q: A: F- z4 o
#获取当前存储的人脸编码集合1 v; t: w/ M3 H5 g T
def findExistsEncodeingList(img_path):2 H, D2 k) W4 y3 w( h0 S% D4 W1 e
images=[]- j9 s4 n# `! j: k" e9 S( f
#列出已经上传的所有图片& R: E8 o+ l+ C- s' `
imgList=os.listdir(img_path)
3 x( r- c/ [9 [4 ~. n: B #处理存储的图片得到其人脸编码
' H- ^" l8 Z% d* C! A for pic in imgList:
; i7 u# G) F6 x. f0 Q R0 U" k img=cv2.imread('{}/{}'.format(img_path,pic))1 t4 I9 M$ |$ D) X+ u! h5 A2 t
images.append(img)
) e$ [0 A! |+ B1 W- A0 X& p classNames.append(os.path.splitext(pic)[0])
) f% v2 k* A; Y" P5 g6 a findEncodeings(images)
* O; H3 }% Z2 J( o& d% v. B- E6 P* B: {6 C; U g
#选择并对比图片
: T4 I* F# v/ K1 Idef choosepic():
P" ^- o" l N9 @& u choosepath = tkinter.filedialog.askopenfilename()
+ |# X' y0 R! K+ m% Q path.set(choosepath)
6 ]0 P/ ?0 @+ t: N9 ?+ y img_open = Image.open(entry.get()).resize((530,750))
, b1 M- [+ l" V6 J6 u3 j img = ImageTk.PhotoImage(img_open)
6 ?. T9 b4 n8 K$ @7 |( h! m lableShowImage.config(image=img)) A$ D" w u$ N% _7 o/ j) s- M
lableShowImage.image = img3 [9 y' y2 ?/ M
lableShowImage.place(x=30, y=70, width=530, height=750): Q. y: {+ r: Z$ ^9 x
faceRecognition(choosepath)
3 O, c3 Q3 R! z; H- X3 M
7 H+ v+ w; T0 ]' p/ {1 Edef faceRecognition(choosepath):
% R+ I8 H( `) l6 L$ X; o4 l/ } frame=cv2.imread(choosepath)
, B, Q2 s7 z9 k4 i frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
# C4 K4 W2 C# ~- I- p2 R' R #对摄像头读取的检测人脸& `( M9 X5 n5 A& z+ ?2 u
facesLocate=face_recognition.face_locations(frameRGB)
7 H. S0 z! |6 X; j$ Z6 w( N* |; P #进行特征编码
4 s% D" b" F2 U$ g+ I faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)9 B1 g% W% X- S% m
#遍历检测的人脸和库中读取的图片进行对比,计算其相似度& k# g7 C) V2 k0 w+ T( T
name='unknow'5 C4 T5 A) u, y/ B8 ?6 M3 a
for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):
! H2 q! I) W! x) J2 V #进行匹配2 ]2 I: k8 X( O6 q/ N% b' U. G
matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)
! W9 M, K- V% X( j- N/ E& C8 H, U #计算相似度
* R$ M+ T6 w# \; W5 ^% y distance=face_recognition.face_distance(existsEncodeingList,face_encoding)" _6 ]7 B' z* ]
lab='unknow'; |4 Q; |- N9 p" P
for index, item in enumerate(distance):
4 G) `2 V4 g3 H! L3 ?8 i- s if item<0.5:! l* q* b) v$ I; c. l' {) Z2 V8 a7 o
if matchs[index]:
2 u( a6 L" z+ u% p( p0 o #得到匹配到的图片名称与相似度值5 [+ a9 x5 @) w, u4 n7 E
lab='name:{}; Similarity:{}'.format(classNames[index],item)
2 e* |) |: x0 v. ~% i. D name=classNames[index]/ t& C3 p/ M; }& m1 {$ D
break; e) ^" n) R5 N2 W% {
#初始化面部捕捉框显示绿色' ]) }( L" C4 S
color1 =(0,255,0)
( P" y0 ^9 T5 S" o8 d if name =='unknow':, B l3 n: ^* w( j, Y$ W. ~
#未能识别的时候显示蓝色8 N7 t1 E2 ^2 T, v
color1 =(255,0,0): _2 r, a, X7 l& @
#画面部捕捉框$ _3 K6 ~# w6 [2 i' U6 o! f
cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3) t- K2 d9 _/ b) l* \
#在捕捉框上添加匹配到的图片信息( I) i7 o- w2 T: G
cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)
& ?& ~! V P! U+ d* y# H4 r, x! B: I( H cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame); R' G/ t7 h& `% M4 O @
img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))0 j$ Z5 c2 {7 p+ _" U, k
img = ImageTk.PhotoImage(img_Recognition)
8 l% [' C# z* M/ \* G0 y8 F lableShowImage2.config(image=img)
* d) `; U6 x R1 Z4 {8 o6 j lableShowImage2.image = img
; U% t5 c1 y& P lableShowImage2.place(x=630, y=70, width=530, height=750)- x- l5 Y/ C4 y' n, c- a
' e8 t1 `2 F9 J
if __name__ == '__main__':
6 L* x7 |0 P$ U P) w7 Z; k v findExistsEncodeingList(img_path)
% {4 h, n q' `& S1 @! P! i #生成tk界面 app即主窗口
- m; _) D8 Y- ~. D app = tk.Tk()
1 H ] b! X8 H% Q* A% p( U #修改窗口titile1 H2 ?/ R0 `2 Y1 L# p1 d
app.title("show pictue") " w8 V( `# d& a3 C3 ]; S
#设置主窗口的大小和位置$ X# ~2 f) [. Z- D2 Y
app.geometry("1200x900+200+50")3 ?+ O! h+ R! z. l' ^! M. w, C. _! y
#Entry widget which allows displaying simple text.6 E0 Y% k5 S9 e3 e: }* Q
path = tk.StringVar()9 C( E# S( J9 |
entry = tk.Entry(app, state='readonly', text=path,width = 100)
0 \4 T; B( K. e6 y& t l H( [6 h entry.pack()
/ |- s6 B9 q4 k# C. @ #使用Label显示图片" P8 Q+ w; V4 u1 A* M9 O
lableShowImage = tk.Label(app)9 g+ H& ~% Y( V7 n6 Q# b a
lableShowImage.pack()
+ a/ @, m% O" h9 P b+ K( G+ h #使用Label2显示处理后的图片
: N- ^* D9 k, I lableShowImage2 = tk.Label(app)
6 z7 W) p6 V1 u lableShowImage2.pack()6 X. v. @ ]& U, j v6 s
#选择图片的按钮5 R0 z/ F" R$ O( f5 V/ Y
buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)
3 p( V- c7 t3 T$ X buttonSelImage.pack()) M; f& D- B- K e8 V1 o. d+ {: M5 `* a4 [
app.mainloop()
7 n r4 ^! f6 B' Y0 R) r' q
3 Z; t" H# ]" a: w7 \: T3.说明/ u6 L& Q5 _5 j+ i* e
首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。
# y* m1 P3 e0 t; x/ Z5 H- F$ n7 w$ Q6 S" ]
- Q- {. N+ G& P8 d: s6 n2 i
7 d- k& P4 K$ D) F
其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片
# v! c, |8 C% [! i, a$ }
) n8 t& D) i0 A( ]3 G* u: d7 \2 e
+ D$ Y4 Y* T% h% u7 U; m' P" [6 f6 W% l5 D1 \
但是效果会存在色彩的失真,效果如下:- f) q; L1 r5 K
9 p5 n% N8 B# E4 F( _ E" X/ K
7 w6 E! R: m& }1 l( U
+ y2 n7 S, E& \, l2 q也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。
. `5 L5 z# Y4 S2 Z
! E; ~: y; R1 Z这里简单提下PIL的九种不同图片模式:
3 I0 o) Y8 d3 ]5 m3 Z3 S, Y. M& R" P! D) \: w: |* u) M
modes 描述
6 B- z8 I+ c5 p1 1位像素,黑和白,存成8位的像素# C' ?+ n9 j5 q% d
L 8位像素,黑白" e5 c0 f7 C4 `* o l8 [
P 8位像素,使用调色板映射到任何其他模式
. @9 X4 c+ E; x( o4 sRGB 3× 8位像素,真彩
3 u% b8 m7 ^% k; [& @9 pRGBA 4×8位像素,真彩+透明通道
# ]' o i! s9 {7 U: K0 uCMYK 4×8位像素,颜色隔离( [9 y% O# ]9 d, z7 s
YCbCr 3×8位像素,彩色视频格式
7 Y# q2 E5 G7 R5 l5 nI 32位整型像素
- ^- g* A' M3 ~F 32位浮点型像素8 F# s, v; Y! H1 F
4.实现效果% e# C1 }! P2 U
m, u5 n# A7 I; A( D" d5 D
) N0 V% l; P4 O2 A" U
6 C/ V4 C6 T1 w) {( n
. q. Z* e I( ^& R
可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。$ ^/ d8 [# M: j( v+ Q
————————————————
& B/ v' K1 G0 k5 X }& d- v1 J版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 b( m1 B# c Z& r0 T
原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288) C! Q. q1 E7 t# C5 L8 I- O; F. i
% b1 t' p$ j3 t' T8 S& Z9 o+ G2 ^. I% a* n0 m% [' V" o+ i n0 j9 e
|
zan
|