数学建模社区-数学中国

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

作者: 杨利霞    时间: 2022-9-14 17:07
标题: Python 基于OpenCV+face_recognition实现人脸捕捉与人脸识别(照片对比)
Python 基于OpenCV+face_recognition实现人脸捕捉与人脸识别(照片对比)5 p# t* A- y, v! ]/ z

- t1 Q9 D. N5 ]- D; j; U0 U1.安装包依赖/ D9 d2 G0 E, b- i0 C
与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。
* m4 a; S0 R. m+ W! [( z) O% S- t" @5 K
在python 3以上版本tkinter是环境自带的,所以这里不需要安装% H) {+ h1 E& I1 c

8 w5 w3 a+ x0 a2.代码示例3 v6 ~( z3 s$ h. C/ R5 B
import os
( |  T8 n. m* w$ n; W5 @/ c0 Nimport cv2
: g6 _# w" K+ P9 u) D/ u- himport numpy as np) g, I9 r( S2 J7 f! y% m( z
import face_recognition
  h. ~& R" V. _3 T& H+ |import tkinter as tk  
$ Z( Q) Y" t2 O& q$ Cimport tkinter.filedialog( \7 S% \8 I; l/ W' N. X
from PIL import Image,ImageTk ! ]$ @6 a: o0 H7 |2 O4 d

- h& e& s  e" Q# JclassNames=[]2 f/ `% \. X* R! c/ E
img_path='Picture'
: G: a  _9 y8 n3 U/ H! pimg_recognition_path='Recognition'$ n. t5 D" y* _* ~1 ?, @
existsEncodeingList=[]/ D& x# _- @2 q4 T. R
#对人脸集合进行编码进行处理8 U; l% {: D. Q+ f3 C5 E) e4 n* a( Q
def findEncodeings(images):% ]9 Z+ a" ^% u
    for img in images:
* ]* R6 u- x9 Y& T# [% P2 I+ _        #灰度处理
1 H  Y' C- d( g8 ]" A" D- ?. P        img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)6 Q# |: N- R5 t$ M: T. v
        #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果
( P2 u" _) ^) q* _: l# R9 F( s        encode=face_recognition.face_encodings(img)[0]
3 P$ Z/ t8 ^; N* i+ o, m. V        existsEncodeingList.append(encode)
; l( F+ Z5 Q) v  j" G& \
) d9 }2 ^1 j) m* f) D#获取当前存储的人脸编码集合
# G2 |; i3 \5 w2 F. H' v; @def findExistsEncodeingList(img_path):
* n. l/ l: Z" ^: Y6 p    images=[]7 D2 N7 [3 R+ l5 i! W+ x7 m% P
    #列出已经上传的所有图片
# d$ t* f- t% @. V5 |$ u    imgList=os.listdir(img_path)4 p6 V/ m! k7 Z4 t5 s
    #处理存储的图片得到其人脸编码
, ~! r5 I' c) O    for pic in imgList:
0 q5 o" h/ I7 v: r; C" d        img=cv2.imread('{}/{}'.format(img_path,pic))- E( G+ i6 r  l8 Q( ?5 g9 T# t
        images.append(img)2 p- C* K" B! ~. g$ n! D9 W
        classNames.append(os.path.splitext(pic)[0])
: _7 y  Y; c, x. @1 G9 x  C9 \    findEncodeings(images)- v9 o; C# n, }" ^
" N8 X" X& D2 }) }4 j8 M4 P# j
#选择并对比图片
# m  A4 L1 K6 v9 Y2 vdef choosepic():
3 d" N- Z! g9 C    choosepath = tkinter.filedialog.askopenfilename()* b) W4 N1 w' \& }* U; ~
    path.set(choosepath)
6 A, i' ^2 i) S    img_open = Image.open(entry.get()).resize((530,750))$ Q% X& {1 x- \9 ^" G
    img = ImageTk.PhotoImage(img_open)' y9 r2 M3 k% `% p* m) x* U9 V
    lableShowImage.config(image=img)
3 Y1 j* D! r: W) Q4 G    lableShowImage.image = img6 H: Z& q" S' C) z5 T
    lableShowImage.place(x=30, y=70, width=530, height=750)
4 x+ ^/ ~" e4 K) Z/ D# n    faceRecognition(choosepath)
! N& m% X% T8 M6 q1 ?5 D0 N- M! U5 ]9 Z- c! b4 F# N# T
def faceRecognition(choosepath):
8 W# y, W0 `( N    frame=cv2.imread(choosepath)6 j, `; M3 r) ?. Y: b0 p& m
    frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)  X! G* _! d& Z, X
    #对摄像头读取的检测人脸
3 S1 P5 W7 E: @5 E, k7 U2 H% X    facesLocate=face_recognition.face_locations(frameRGB)
  o+ E2 y" i0 {$ r5 a# Q. Y7 Q    #进行特征编码
4 ]: c( Z" L8 l( ]4 I6 C    faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)3 a: m8 y6 n9 h" n# w' p
        #遍历检测的人脸和库中读取的图片进行对比,计算其相似度  P7 ?' f8 U4 |6 o0 q  c4 R
    name='unknow'# t) E: h4 z/ W2 M3 |9 z
    for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):3 I9 m. P3 e9 L# f
        #进行匹配
+ l$ A. ?* S" c! z9 c        matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)
7 l, g+ G" e2 H4 a, ~/ ^+ z        #计算相似度
+ S) Z8 D/ F5 ~& Q- e; @        distance=face_recognition.face_distance(existsEncodeingList,face_encoding)9 u1 s$ J( H2 X* w" b
        lab='unknow'# C% G! w8 S6 C9 ~3 y
        for index, item in enumerate(distance):
) V8 r* H2 D1 \# T) w4 N8 a           if item<0.5:4 j# f. o* q+ w; A# @6 \7 s
                if matchs[index]:5 i  k7 f3 k  X/ C# h% ^6 H
                    #得到匹配到的图片名称与相似度值
! X: e* X( A! w( ^3 [' `                    lab='name:{}; Similarity:{}'.format(classNames[index],item)2 X3 V. A! D/ u  l' ~$ q: C8 {+ g
                    name=classNames[index]
/ ?2 x+ Z- V8 a- g# v                    break/ [! x: j2 ?+ s  P  @5 f3 j
        #初始化面部捕捉框显示绿色
; I  ^0 K, h4 z" [; z: X1 G# C# [        color1 =(0,255,0)
" H9 L& X4 o; W0 V2 `8 g5 F8 A; c! O        if name =='unknow':7 C: f! F4 g( g' K  D3 ^
            #未能识别的时候显示蓝色6 c, t0 {# z  Q6 f# a6 a+ [
            color1 =(255,0,0)
! I6 K: {4 J1 `9 o        #画面部捕捉框
- D$ P5 H% a% T4 L) Y/ d0 b        cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)
8 ]/ s9 t. @; W9 @        #在捕捉框上添加匹配到的图片信息# r) o: ?) y: N" J/ J
        cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)
4 |2 e5 I8 Z) h0 s4 g        cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)
3 c( t  ]1 g( c    img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))& z( \; s0 J9 s& i" H
    img = ImageTk.PhotoImage(img_Recognition)
. x0 ?7 [' ?9 v* V    lableShowImage2.config(image=img)6 {% h" E5 |& T/ C  Y
    lableShowImage2.image = img- S! H. n4 z# D$ r- z1 @6 P% L& d
    lableShowImage2.place(x=630, y=70, width=530, height=750)
* f9 R' u* ~# B7 Q0 q* t2 T% J; c6 Z8 O
if __name__ == '__main__':4 W: p$ o9 o: |
    findExistsEncodeingList(img_path)0 a* V' h) L) ~8 j6 J% N( b
    #生成tk界面 app即主窗口
) a- [) e9 F0 O5 Z8 M: H. _: q    app = tk.Tk()  
. _6 ^0 O8 g. M3 d- ?. b4 h* J& N6 b    #修改窗口titile0 ^3 l( v- n  l; R* N6 |
    app.title("show pictue")  
7 Y! U( S  T3 S    #设置主窗口的大小和位置
4 G# [4 \) w8 l    app.geometry("1200x900+200+50")( h3 J2 c- F" e% W% k) Z1 @
    #Entry widget which allows displaying simple text.% J1 h  [1 P- [- ?6 o0 t
    path = tk.StringVar(): S  v) C6 S/ |; M3 ~. @4 _
    entry = tk.Entry(app, state='readonly', text=path,width = 100)
& V9 U1 V' Q' O# K" U- u) D2 q    entry.pack(); ^7 g4 {% A0 \% d/ D  L7 t
    #使用Label显示图片# f3 b, V& K' x, k
    lableShowImage = tk.Label(app)5 m4 W$ b% W  _1 x, @& @) H- Q
    lableShowImage.pack()
4 p  x5 L$ q5 @5 V     #使用Label2显示处理后的图片* B$ ?' c) _5 W! N( R
    lableShowImage2 = tk.Label(app)% ?) Z8 U& Y# G2 g" y
    lableShowImage2.pack()
4 ]) I0 X. Q9 p; [) Q* s+ U. S. i* H    #选择图片的按钮/ k% C( q7 ?! j0 n: r( v+ i  h, q
    buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)5 t- \& R. |$ E' l: L+ }# P  K
    buttonSelImage.pack()
5 O0 _9 L2 ]- I- q6 W7 E5 U    app.mainloop()8 s8 C$ l4 C4 R- ?; [) A5 j
- t3 M- r5 X1 f+ d8 ]2 ]2 N
3.说明8 r/ N9 F$ c5 M6 |
首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。
! P& g. D+ z, l8 J. N& Y, B/ j' o/ C$ h! m8 Z: _4 w) {

3 B3 d/ j. Z, f* `+ H2 S
. i7 S1 Y' o% j3 |4 a 其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片
; j3 s- l8 h5 b8 H3 H% q  a( S6 ]$ O1 a; s  \

2 }0 ~+ X  @5 J+ Q$ F! O( y; N
  [6 L( M4 g$ h* t% {( L 但是效果会存在色彩的失真,效果如下:5 E9 J0 o( e4 l" m- n. J

& V$ [1 A% d+ D* K
' x2 r% A+ Y9 {7 {8 @" e. e# Q3 K2 M' U9 S! E
也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。
% \9 `, ?" e/ {3 z4 n4 O
& U! X1 m1 W$ S# W7 Y! A这里简单提下PIL的九种不同图片模式:8 `7 H; H$ i3 L1 k0 n3 |) y* u
+ X" k. I! J$ T) P  |
modes        描述
4 U$ G; p+ m# I$ V1        1位像素,黑和白,存成8位的像素
$ A* k5 R  ^7 G6 ^( s( EL        8位像素,黑白) p3 h+ ~$ G  B+ b8 v6 v
P        8位像素,使用调色板映射到任何其他模式
$ N* ], B% }9 Z; k& K1 \# PRGB        3× 8位像素,真彩
  V3 _+ F; _  O  \- dRGBA        4×8位像素,真彩+透明通道
! p7 V- F8 G  D% U, V7 jCMYK        4×8位像素,颜色隔离
6 G5 g6 C6 s4 {1 g/ x6 ^4 wYCbCr        3×8位像素,彩色视频格式
9 R# }8 A- G8 nI        32位整型像素* b8 T0 {, I; }& q0 {& ]2 h
F        32位浮点型像素! n. p' u( x$ e* v3 B3 x
4.实现效果' k# k" _% l: q% x) q7 q$ c, ~
( j5 ^. H0 W' p% |: b
9 H7 b- |1 F) o' n

" o# f4 c( t7 L* j7 s% W) j* o% ?' [
可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。
$ G8 K$ _. N- X* B( W1 p' o" Z————————————————/ A9 f2 X1 w, V- }0 P+ r- E- g+ e
版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
4 i; D6 Z+ J4 i1 N原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288
( E* f. `  f) V* t2 G: V' R! O! A9 U

) x3 s. l) U- ]/ L2 {  U2 M




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