- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 565208 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 174785
- 相册
- 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实现人脸捕捉与人脸识别(照片对比)
! r( Y2 e3 p; [& u2 y$ D' ?- y, W; r, d! b6 W6 O
1.安装包依赖
9 Q( c, L/ D% E4 F1 G n与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。3 ~8 M7 o% @) A+ |$ v2 e
7 P6 g$ a. k n8 o+ P在python 3以上版本tkinter是环境自带的,所以这里不需要安装
9 _# g8 V* d# D5 ^ Y2 }7 w, V o) ]* C7 b3 D4 V8 l Q% Y5 a% l
2.代码示例" V0 p/ s% v/ X
import os
# i+ l& l+ q& P; ?import cv2
0 S7 B/ ~, R g1 Mimport numpy as np; }5 a- `8 X. m( |
import face_recognition; p2 }6 h) o# I& s
import tkinter as tk
: @" q% L& S$ F; k, W3 ]import tkinter.filedialog; {2 ^$ `) Y8 Q( Q9 h, R
from PIL import Image,ImageTk
& `1 p) `5 @4 L# o- h0 r1 s6 T
* u% n' c2 Z: k4 W$ u' @classNames=[]7 M' P' f- s% I7 H
img_path='Picture'" f5 i' y0 R" Z4 i, Y# N
img_recognition_path='Recognition'
8 R& ^1 K! T8 b4 \* PexistsEncodeingList=[]
2 X# R6 A% m( l7 i9 u3 t+ Q#对人脸集合进行编码进行处理% g8 q; c3 v6 o) \ `/ }" w7 h
def findEncodeings(images):
$ y0 n/ E% K5 e) F! p for img in images:+ k( O& u$ \: l! @* `+ E1 } x: g# s
#灰度处理# e3 T# [- S& |! Y/ x4 D8 G
img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)
: u+ b: S; \2 Z/ _% J6 m! a #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果
" Z/ x3 R" p" O, h `9 {$ H/ F. l encode=face_recognition.face_encodings(img)[0]
0 _8 P, H' a5 f: R existsEncodeingList.append(encode)
6 q6 l5 ~- X7 ~8 u) d. f
- }4 E& r6 O ?, ^; Z#获取当前存储的人脸编码集合9 u' F2 {0 R( e1 ]/ D* v6 J2 y
def findExistsEncodeingList(img_path):
& R* C0 |2 e* } images=[]# a. b" |8 B9 q* ~7 y" r
#列出已经上传的所有图片) _4 Z; c: m' e& C' O Z
imgList=os.listdir(img_path)0 q; d! V. m* q, y8 t% b. ]; u
#处理存储的图片得到其人脸编码4 x2 B5 D. T$ ]. q' c
for pic in imgList:
, E/ X0 W% ]0 m img=cv2.imread('{}/{}'.format(img_path,pic))' j; Z1 C/ m0 M0 T
images.append(img)
) Q- E4 s' d- \( B; r; E classNames.append(os.path.splitext(pic)[0])8 n- X2 ?1 e2 A2 J8 \
findEncodeings(images)6 ?4 v! w4 y3 M1 V+ j e h
( V$ M! `6 ]7 y
#选择并对比图片
$ n" Z: _. Y8 ]; x5 q/ `def choosepic():
( e: A! h: x: g o0 p choosepath = tkinter.filedialog.askopenfilename()
5 y3 a2 a' |. d, p h* d+ g- \ H path.set(choosepath)
* B$ ]) p) D! E& Y' S img_open = Image.open(entry.get()).resize((530,750))( j' _2 r# j/ T Y
img = ImageTk.PhotoImage(img_open)* W) R, S" A' c0 E2 V% O) u$ O
lableShowImage.config(image=img)1 ^ N+ b4 n; l* Y4 w8 l
lableShowImage.image = img. f$ W; n6 x1 Y- E
lableShowImage.place(x=30, y=70, width=530, height=750)
1 @0 x. O( q$ ^7 J( J. ] faceRecognition(choosepath)
0 v1 Y# k+ a& S0 s) K
" M! R, ~8 R( ~( H. M0 xdef faceRecognition(choosepath):- S$ X; X; d" \& u
frame=cv2.imread(choosepath)4 j& U- C5 k3 j5 ?( k
frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
2 u) @- L/ F% _/ @0 g #对摄像头读取的检测人脸: `, E* h3 r' Z$ _/ S/ g
facesLocate=face_recognition.face_locations(frameRGB)5 E4 A5 q, ~' C3 C: k3 B$ M4 w
#进行特征编码
8 R2 d K# u8 L: k7 t( X faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate): h. t! A3 ?$ y3 ^
#遍历检测的人脸和库中读取的图片进行对比,计算其相似度3 _ {; \8 g* K
name='unknow'
- e- p+ Q0 z. n% p/ f! o for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):& T" t( J' V @ H1 T
#进行匹配, [% c' ~ [( Z6 {( |
matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)) i- x; U1 W+ }# p3 q
#计算相似度
' V: D. B6 O6 x3 \5 m9 `9 G- _6 T distance=face_recognition.face_distance(existsEncodeingList,face_encoding)' s8 i. m- @5 d) f6 m- a
lab='unknow'$ o0 Y5 ~9 E4 d% g
for index, item in enumerate(distance):; X t2 V3 ~2 n1 u' @" A
if item<0.5:1 ^, ]+ b; U* l( B1 e0 o& z$ `, z; v
if matchs[index]:+ C& K4 U0 }4 t( _& B1 b& k: `
#得到匹配到的图片名称与相似度值6 W9 ~0 o4 w: A
lab='name:{}; Similarity:{}'.format(classNames[index],item); M8 i w4 b) s
name=classNames[index]
0 Y$ C& L- A3 Q, m break
3 v5 q9 f) I- f1 _$ n) O #初始化面部捕捉框显示绿色; B |" h, f6 o' B, P1 @
color1 =(0,255,0)1 B0 T" F Y$ c9 [7 p9 ]
if name =='unknow':2 i$ H& z- E9 w' d6 B
#未能识别的时候显示蓝色
7 B$ M$ e! w7 n: s4 B7 O color1 =(255,0,0)- W2 O! h& X" ^- C
#画面部捕捉框
% x1 g/ E% ~8 e7 a1 Q3 i cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)
8 F& M' ?/ _$ X! w% t #在捕捉框上添加匹配到的图片信息
& X. L' j3 u2 d; d: e2 | cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)
( V, Q0 n9 Z5 W( d; q% x cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)
* P) P" p$ V" q/ M1 @ ^7 S1 a img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))
) W6 b- b* P% V& D! t6 [* U( b9 |) J img = ImageTk.PhotoImage(img_Recognition)
: R3 {0 A5 F3 |; O0 H/ Z' k2 M' _4 _ lableShowImage2.config(image=img)
2 s$ X( P8 X+ z3 N lableShowImage2.image = img4 v* [$ L( b! ?4 f- O$ O' S
lableShowImage2.place(x=630, y=70, width=530, height=750)
" C8 [! [) z; q. e4 ~6 J6 b. w4 a0 W0 c8 o
if __name__ == '__main__':; \) v' g6 T7 Z! n2 K2 z0 x2 s+ B
findExistsEncodeingList(img_path)- j& v3 N- @% w' _8 ~# f, ]1 a
#生成tk界面 app即主窗口
) Z6 x6 J& ?6 Q; d0 x; p app = tk.Tk() ( l, K/ m, C8 ?6 B, U
#修改窗口titile* m" y' i: P4 ~% w0 V! c4 i
app.title("show pictue") X9 a# D1 o3 L5 _
#设置主窗口的大小和位置
$ R- C& O x% g1 U I" c! v app.geometry("1200x900+200+50")
% r1 |0 v n. q! m #Entry widget which allows displaying simple text.
' x: E1 E4 \9 m% k% v+ | path = tk.StringVar()
! }( i* l# Q a+ E entry = tk.Entry(app, state='readonly', text=path,width = 100)/ }3 I# h9 P+ X+ i4 p
entry.pack()
2 |7 Q: m6 x5 W( @. g3 [; k #使用Label显示图片
% F/ E5 x; p$ x4 | lableShowImage = tk.Label(app)* t# O2 l" `& X( C
lableShowImage.pack()# ?. \: |. |6 G8 V! i2 P1 E7 q
#使用Label2显示处理后的图片
3 ~1 H7 I5 t0 h3 E! c lableShowImage2 = tk.Label(app)2 J9 @0 G, k2 n9 I' l+ ? i
lableShowImage2.pack()
2 H' |4 I+ W& Z) @% O) X7 }/ e. f' ` #选择图片的按钮) n4 {2 Z+ k5 S9 e
buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)" K& u. k6 C( l9 V: s2 i
buttonSelImage.pack()
) q: f9 S' \1 s9 m/ J' ~: \. z app.mainloop()
/ o' T+ s z$ j6 Q3 X& _* ^5 V d* {' ~" T) i" _
3.说明, E- B( @4 D# b% T. h
首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。+ c* f8 V' T' |, U4 a) [( O2 b
4 T: t: c" `8 y% G. O) r5 |$ R. |4 F, p+ M
; D+ t7 E; L/ v3 }, J) v 其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片1 r( o, Z5 m) s
9 U$ r: F7 T U; Y4 g3 `! p
( p( i& W, Z4 E/ E3 _3 C$ X4 W" ~& l# x% G
但是效果会存在色彩的失真,效果如下:
; F8 z }* ~$ E5 y7 W0 n
9 h7 R/ n; x% c: @" |: H$ x8 |7 y
- {& ?$ f6 {/ ]9 Y8 n2 v/ V/ k5 l5 ~- i) K( F A
也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。
2 k. E2 v; F9 ^4 z) K8 r( K5 ?& h! f4 H9 {
这里简单提下PIL的九种不同图片模式:
" X9 k6 H$ a5 l! T r) [+ b5 n4 F( u% w; R/ c E; O
modes 描述
2 p Y$ [, u8 i- Y1 1位像素,黑和白,存成8位的像素4 m- M& V! ?0 p1 P5 V' @
L 8位像素,黑白) q* M' I5 Q% Y1 n9 _% N
P 8位像素,使用调色板映射到任何其他模式; `, I9 `" h* w$ s! v% M
RGB 3× 8位像素,真彩: @2 Y$ V4 v4 y! O
RGBA 4×8位像素,真彩+透明通道
4 \, y! T/ F1 w' |: h3 J% vCMYK 4×8位像素,颜色隔离7 F' A% p- {4 z4 C9 T# p# _
YCbCr 3×8位像素,彩色视频格式, Z3 {" Q3 Z4 X7 \% X. Z* _2 }+ k
I 32位整型像素
! z. x# s5 s2 K! I( r; qF 32位浮点型像素
* F1 s5 s/ y r+ I; m4 L; R- b! N4.实现效果9 A, K" @, Q# e: e8 L) O9 }, t
! Z# M3 |/ A8 e/ r
6 ~' v5 q+ _) m' n) o4 a" t9 j& n- H/ X
3 p) n' a" y* t1 X9 o& c 可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。5 @! ^7 T5 v0 W) w- F/ s' `- }
————————————————' ]% b% E6 K( `( I
版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。9 C+ l9 \) h1 @0 r
原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288- O2 n3 a" D- u$ p+ _8 ~ H
+ r, Y8 @' | z& H
4 R6 E) m" ?% Y$ h, v3 f# H |
zan
|