数学建模社区-数学中国

标题: Python 基于OpenCV+face_recognition实现人脸捕捉与人脸识别(照片对比) [打印本页]

作者: 杨利霞    时间: 2022-9-14 17:07
标题: Python 基于OpenCV+face_recognition实现人脸捕捉与人脸识别(照片对比)
Python 基于OpenCV+face_recognition实现人脸捕捉与人脸识别(照片对比)
& W: n9 E  S' X' F& y
: v; ]+ R) E4 R1.安装包依赖& P  j- {% b! B- J
与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。1 U% Y. ]2 ]0 o6 k: r

6 u. _1 z% p& ~1 Q7 w# I在python 3以上版本tkinter是环境自带的,所以这里不需要安装8 g8 C0 s- d8 e2 A8 u( M; k

& M% l% C9 ]  L: U, [2.代码示例8 C3 @' v$ I) B1 V( s  ?% Z
import os7 |) [  n/ R% o
import cv2
/ `7 Z( o- Y& H& E) k8 Iimport numpy as np, X* k5 x+ ], {  y4 j4 q7 s
import face_recognition+ J8 o: j4 {( a5 e! `* S
import tkinter as tk  2 D6 y* c% h: |; T
import tkinter.filedialog4 M$ _7 G/ }2 u! l$ f8 w+ t% e
from PIL import Image,ImageTk 0 e4 d6 q$ _1 g7 r

8 L# h6 k3 ?6 ]) {4 Y; }' ^* gclassNames=[]
+ I; C1 f2 V6 I( {2 i4 E$ H" c& Qimg_path='Picture'6 L5 E& q5 }: s8 A+ u; }
img_recognition_path='Recognition'/ {, X/ P- ^" P* q; l" ?
existsEncodeingList=[]) K* \' a+ z* B/ t
#对人脸集合进行编码进行处理
4 ~9 z7 x/ O4 ]9 xdef findEncodeings(images):
* c! T/ J8 p8 n! v5 a- g    for img in images:
' O! t% r( Z* T0 M; w: ]        #灰度处理
- Y! B: J, t* P4 f        img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)7 I& a* ~$ A! J/ U6 P* Y
        #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果
: G) n; [, x7 W, V+ l4 q        encode=face_recognition.face_encodings(img)[0]
6 p4 N$ d8 I7 n3 j        existsEncodeingList.append(encode)
" k! ~. }5 z) ^$ `* D# D& j( P* J* ^& h8 {
#获取当前存储的人脸编码集合
8 ^+ [- p2 ]& s/ J) ]4 m; Mdef findExistsEncodeingList(img_path):; k5 @! Y: w8 {4 |  J/ P
    images=[]
3 k8 Z* P0 U: t    #列出已经上传的所有图片% ^9 P8 ]5 H# U4 \* A% v$ U: M
    imgList=os.listdir(img_path)- @5 \; b+ G7 y! E5 W3 |
    #处理存储的图片得到其人脸编码
1 I& [/ }" Z. I3 R    for pic in imgList:2 J) {( C$ r6 M1 U) I! N) w5 K5 y
        img=cv2.imread('{}/{}'.format(img_path,pic))6 A+ w& _& d' j7 E
        images.append(img)3 T# ?5 T( `  }5 h- z. o
        classNames.append(os.path.splitext(pic)[0])& Q- M  @9 b( e9 S% {  N. \' @
    findEncodeings(images)
$ q* ~7 U  _6 G* K6 p. v6 ~' a& T$ z
#选择并对比图片. T2 u- ^9 t- O& N( \6 T0 u
def choosepic():, L' g% U  x, ?* F
    choosepath = tkinter.filedialog.askopenfilename()
( K: m; K9 V- T' [0 Q2 K# L    path.set(choosepath)
/ e/ T. k: @' h3 K+ |5 U2 b' V) ?    img_open = Image.open(entry.get()).resize((530,750)). M( D1 G! _, }8 C
    img = ImageTk.PhotoImage(img_open)! D  z* Q! E3 |+ O+ e' h
    lableShowImage.config(image=img)
$ `$ o" |4 q, c6 ^' k7 i' J    lableShowImage.image = img- d1 n' r9 p8 e
    lableShowImage.place(x=30, y=70, width=530, height=750)( N: p( i% D5 K
    faceRecognition(choosepath)
" g) l1 O3 b+ t  i# O; k) O2 G% q* u& [( z" _
def faceRecognition(choosepath):+ C! C- F' T* A1 j5 w/ v
    frame=cv2.imread(choosepath): g: O( |& p0 {
    frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
: `+ t2 V* g5 B2 _    #对摄像头读取的检测人脸+ z5 x- T% H* n# b9 [* ]
    facesLocate=face_recognition.face_locations(frameRGB)
7 Z& b( K" x" I$ g; j# {, t# G3 p$ D' Y    #进行特征编码6 ]* ^4 }) Z. U( V0 d) }9 l6 r0 E3 m
    faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)& [7 F) N8 B  t/ I: t6 n
        #遍历检测的人脸和库中读取的图片进行对比,计算其相似度  G6 O/ g6 z5 h! z8 X
    name='unknow'2 w. P. Y4 n9 m' f) {- Y8 Z) E6 j
    for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):4 S0 u" h. Y& m# @+ t2 D9 O1 U
        #进行匹配
; q! p5 u+ `. n' `        matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)# X3 m5 p* `& X& T) K. Q& x' u
        #计算相似度5 c$ |. G+ C6 J" g
        distance=face_recognition.face_distance(existsEncodeingList,face_encoding)
# ?0 Y# ?+ R* C2 _/ N  J: @! S        lab='unknow'* [6 J  l, l( v8 q# p
        for index, item in enumerate(distance):0 B! a$ ]% D0 e& y2 B" {8 T
           if item<0.5:# b0 Z/ k" N# h1 P, R* m
                if matchs[index]:8 Q1 L/ G' J) r2 p
                    #得到匹配到的图片名称与相似度值
' w6 k, F6 n. c2 j# m( M% U0 z9 d                    lab='name:{}; Similarity:{}'.format(classNames[index],item)2 u' C  V7 l2 ]# E
                    name=classNames[index]
5 Y  a0 G( e  h+ J                    break4 K( \4 @, a+ w
        #初始化面部捕捉框显示绿色1 x/ Q1 E# C- T/ ~, k" {, [
        color1 =(0,255,0)1 l3 T! v7 \( C% p, G
        if name =='unknow':
6 H2 g7 U; m- s# g" c4 g! i, w5 M/ w) L  H            #未能识别的时候显示蓝色+ R- B. J# }. N7 A% l
            color1 =(255,0,0)
, E( ?, [8 q0 E5 ]        #画面部捕捉框
- \4 @, z* m/ e9 A. G! l! {. g        cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)
& s1 Z, ?0 X$ C+ H" E( S0 e4 k        #在捕捉框上添加匹配到的图片信息) {. V8 D* p" m- S0 f9 x; e- g$ ^& A+ u
        cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2), W3 l. p: ~  x* _3 u
        cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)8 {: _; W% x0 B9 p" j% \( M$ j
    img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))6 ~3 \4 q! V, L7 i
    img = ImageTk.PhotoImage(img_Recognition)
2 K6 M- d% @; C  c- ?$ O5 i    lableShowImage2.config(image=img)7 V, i& ~9 n5 n+ V1 r- Q2 c8 \$ s
    lableShowImage2.image = img
8 H1 d3 f4 H$ ]4 I6 q- ^    lableShowImage2.place(x=630, y=70, width=530, height=750)
" P8 U" s# ~$ x& i; ?$ |" f* [" S2 w9 p
if __name__ == '__main__':* K4 t* J! w8 ~, @' c3 W  a
    findExistsEncodeingList(img_path)  v7 k+ Y2 {) ]6 `7 D; J' F/ X0 E
    #生成tk界面 app即主窗口
2 K5 F0 P5 D. s. M  Q) h    app = tk.Tk()  
3 @! ~9 U1 I" G& r% R% x$ s( ~    #修改窗口titile- t6 N5 v2 }6 H
    app.title("show pictue")  * _* t* ?, X1 P6 g
    #设置主窗口的大小和位置
7 x& d1 ~# `, h2 |    app.geometry("1200x900+200+50")
. D) F7 ]/ [" i. w, ~9 K3 b    #Entry widget which allows displaying simple text.) `& j3 ~, `. u  B6 s
    path = tk.StringVar(), B8 `( V  B% \- k
    entry = tk.Entry(app, state='readonly', text=path,width = 100): |' o. g, t1 k0 V& Q+ ^" r0 r
    entry.pack()
6 G  ]& U7 z8 u0 d    #使用Label显示图片
7 H# f& R$ C$ A3 ?    lableShowImage = tk.Label(app)# O. c6 F9 k9 h* S
    lableShowImage.pack()
3 |5 X5 ^& {6 f+ }% ^; A$ h     #使用Label2显示处理后的图片
6 C6 D$ ]5 G; F  W, M    lableShowImage2 = tk.Label(app)
' U! D" d3 T. K7 z; i# x    lableShowImage2.pack()
8 r: y/ p1 A" m8 e    #选择图片的按钮# G  ?" E# g$ q7 W7 Y! K( l& m
    buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)4 `% ]& M& w( t
    buttonSelImage.pack()3 N+ y6 Y) f9 j; ~1 f
    app.mainloop()
, ~1 a0 q% J4 L2 p+ C4 c$ H; V& O1 a& w
3.说明9 Y. e8 j/ _3 @# {- x
首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。/ {- F7 @9 E5 h' }' b  K/ l
0 z9 \4 ?" U2 M/ b) |2 S/ R

0 I8 S5 v  E+ J* X( f) M
- E- n8 o4 Y9 g. Z 其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片
3 _% }+ ?; k* M( e2 B( A" h% `, k
( a6 l, g) p/ J- t2 q
% ~+ F, ?) h( J$ @, E6 D( S% h* f. F4 s( ]
但是效果会存在色彩的失真,效果如下:3 Q' |9 z8 w: @- c. l- y

! E+ Z# G3 x, A6 }' S1 ~
, s8 A/ k# V0 {+ Y0 J$ V4 a1 t
6 d( w4 E" K8 b2 Y也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。9 N- O- J: I. B2 t+ X

) c7 i6 y  ~3 V; Q/ n( u这里简单提下PIL的九种不同图片模式:; v5 R; n, Y( _4 _7 a4 D# P

" Y# C2 k  S- c% A- c5 u, gmodes        描述% W" a8 Z7 F# \" }" T
1        1位像素,黑和白,存成8位的像素# [. l8 }- [6 a+ |7 V5 z' n
L        8位像素,黑白
" E0 m0 p: ]/ M  RP        8位像素,使用调色板映射到任何其他模式
* Y- b' f4 b0 [3 h" ^$ l4 N" R2 ^  U$ DRGB        3× 8位像素,真彩7 f: U) X2 e. q! b4 N
RGBA        4×8位像素,真彩+透明通道
) ~, C) I, c7 }- p  B" ^9 dCMYK        4×8位像素,颜色隔离/ J5 u" A- A- p4 I0 _
YCbCr        3×8位像素,彩色视频格式/ y& c' H: `* X  y8 O8 A
I        32位整型像素; |! Y8 e& c$ k
F        32位浮点型像素
8 T. M% A+ A4 }. }8 I4.实现效果: e, [9 _& Q  ]% [3 L: W' `6 l& q
# H, z# }: z. U# }6 h1 s) \0 {

0 S: o: j  l% c5 j0 \0 p# H- b9 z0 E# b$ @1 Z7 H
% f; C& J+ U2 e# N
可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。
! l) w- u2 I7 l4 \% l  Y* e# z5 \4 z————————————————
, R' w: x) |$ s1 Q% w9 j! ?版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
/ _/ ?; ]1 B4 i& E# m+ B原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288* I) {) |; G, i' g/ T& n/ M5 T5 w7 H

5 g+ C3 W! O. O' }: e2 L2 y3 s
0 M$ Y( B' P5 H" H) W




欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5