QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4170|回复: 0
打印 上一主题 下一主题

[其他资源] Python 基于OpenCV+face_recognition实现人脸捕捉与人脸识别(照片对比)

[复制链接]
字体大小: 正常 放大
杨利霞        

5273

主题

82

听众

17万

积分

  • TA的每日心情
    开心
    2021-8-11 17:59
  • 签到天数: 17 天

    [LV.4]偶尔看看III

    网络挑战赛参赛者

    网络挑战赛参赛者

    自我介绍
    本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。

    群组2018美赛大象算法课程

    群组2018美赛护航培训课程

    群组2019年 数学中国站长建

    群组2019年数据分析师课程

    群组2018年大象老师国赛优

    跳转到指定楼层
    1#
    发表于 2022-9-14 17:07 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta
    Python 基于OpenCV+face_recognition实现人脸捕捉与人脸识别(照片对比)+ C7 _3 m% Z9 k. i$ n* D

    1 a% ^' L/ j- k( k7 p$ ~5 f1.安装包依赖
    ) x# G8 W2 b- @# X& v3 B与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。: y7 W" F! R6 `4 Y2 {8 j4 U3 o  R

    ; C! t6 D8 d0 p* G( s+ F, A在python 3以上版本tkinter是环境自带的,所以这里不需要安装+ s5 p$ A. s" Z" J; R! V

    & r: ^& i  g. i1 d9 p2.代码示例+ o7 R' b$ E6 l3 D1 r
    import os3 y) `& J, _& U2 A
    import cv2
    ' ^1 N8 g! u' v8 i- `% Eimport numpy as np- r" Z6 A; T, K( {- w, ^
    import face_recognition
    5 o: D+ ]( ]) a  Aimport tkinter as tk  
      a; S  J0 C6 I! R! w7 z6 }import tkinter.filedialog! X* H8 z6 }; Q
    from PIL import Image,ImageTk
    $ m( x7 o& |- n3 G6 u. u
    6 k0 f8 {7 d1 H! }classNames=[]/ g- T5 [  f1 x8 I- \% ~; V$ ^
    img_path='Picture'" U7 M! K6 W* n2 L
    img_recognition_path='Recognition'
    8 a3 M; h: W) c* j1 H  GexistsEncodeingList=[]
    # W# G' ~3 m! N) D+ x0 T#对人脸集合进行编码进行处理' J3 O/ h4 h% t/ A7 y5 z
    def findEncodeings(images):
    : O3 u8 Z6 X3 W: ?: g0 P' U  [. E+ l    for img in images:
    # i8 X6 B) q; V$ K; F        #灰度处理- @$ I1 i& r4 l% ~( q0 S
            img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)$ @$ r5 X# [5 v% x+ b
            #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果
    + ]8 ^9 {6 Q/ [9 E( S5 H( B        encode=face_recognition.face_encodings(img)[0]
    ' W+ K  Y$ h( W        existsEncodeingList.append(encode)
    ( A# X5 q8 r! I$ n5 g; C, N0 ]. P3 N! Z, d
    #获取当前存储的人脸编码集合1 [! z8 v  L' a, [
    def findExistsEncodeingList(img_path):
    $ Q$ G9 [) Z. r/ B% P- e    images=[]2 C8 N3 t. ^( r. Y2 p; C3 Y7 x( |
        #列出已经上传的所有图片
    6 \  ~# a4 M4 Y/ e5 ~! ~    imgList=os.listdir(img_path)
    9 O- y5 E8 V/ [  X! c! s# H& x1 G    #处理存储的图片得到其人脸编码  Y% `$ B& j# P: m2 y( O& [+ ]
        for pic in imgList:; Y3 ~* Z, h5 ~; {
            img=cv2.imread('{}/{}'.format(img_path,pic))0 {1 _& W/ p1 ^% C" e8 S
            images.append(img)
    ) t3 D; }) P( S        classNames.append(os.path.splitext(pic)[0])
    5 Z2 z. E6 y# @2 y5 @    findEncodeings(images)
    , j0 K) r$ E% r8 w: X
    5 }+ e7 H- T& R! h6 |7 T" ~#选择并对比图片
    2 X5 [' r4 k: k) ddef choosepic():
    ! y! u& ?" r( a- P  {    choosepath = tkinter.filedialog.askopenfilename()" |' a' v' g* H8 _6 a) e0 W' X
        path.set(choosepath)
    ! R  a/ l, `0 H' N, i# m4 N8 _* w    img_open = Image.open(entry.get()).resize((530,750))
    ; n" [' H' \; {5 _  K& f    img = ImageTk.PhotoImage(img_open)8 ?! `9 x# v( e0 V$ Y) ]8 _  ?
        lableShowImage.config(image=img)
    9 I. {% X1 Y( s. R% s    lableShowImage.image = img
    ( g# n6 V5 [: X) K3 J8 \) U# J    lableShowImage.place(x=30, y=70, width=530, height=750)6 v* ]- K  S1 l$ z9 m5 Y8 d5 k- u
        faceRecognition(choosepath)" x( R: N9 V8 o9 D" ^4 d7 c4 I% I

    - P! c  ^- C9 k) Y8 O) wdef faceRecognition(choosepath):! K. B, h5 K4 u4 X& C3 M( O, X. e/ C
        frame=cv2.imread(choosepath)
    + N# G- E3 ]- P: h! y& j" q$ ]    frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
    - e& W+ E5 |# V& L6 N    #对摄像头读取的检测人脸
    , V: v. E; z0 ]0 d- d' M+ A    facesLocate=face_recognition.face_locations(frameRGB)
    + f4 p2 e$ u. G' P; c    #进行特征编码
    ! K0 P+ E$ o$ W9 ^    faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)5 h$ m. V4 B# G& R
            #遍历检测的人脸和库中读取的图片进行对比,计算其相似度* |! Y% d5 y# Y' n2 h  S3 d
        name='unknow'' i) o/ U- Q- J
        for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):
    1 w: |$ _% c5 {7 H6 o        #进行匹配
    * |+ n. W+ G$ O8 T+ \' ?        matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)
    2 Q* z2 f$ z( G9 }7 u        #计算相似度% f" ^* }4 I- I7 G
            distance=face_recognition.face_distance(existsEncodeingList,face_encoding)
    9 d9 {! I7 h" B. F' e; o" u. B        lab='unknow'3 |6 Y: G( A& i& {  U2 h) o
            for index, item in enumerate(distance):
    + p% h  g+ L" y4 F/ w: Y& `! w$ y           if item<0.5:& e1 E% h, M0 P- |
                    if matchs[index]:
    : ~# K+ j; s2 D3 T                    #得到匹配到的图片名称与相似度值
    2 l; H4 D( {4 e( l+ B                    lab='name:{}; Similarity:{}'.format(classNames[index],item)& e9 q; _5 H. L7 B
                        name=classNames[index]
    : x5 g$ @% W+ ]) f9 b4 i                    break
    9 P- D) T$ N  g6 o8 c9 C) @8 \; b        #初始化面部捕捉框显示绿色
    0 D( S! L) }4 M: n9 C        color1 =(0,255,0)- y# P1 S% U! m4 m6 D* X
            if name =='unknow':
    % j: ?7 M$ o9 {( m4 M            #未能识别的时候显示蓝色
    ) t) W3 A4 n1 y" P            color1 =(255,0,0)2 S7 k7 r$ l3 w2 A* B
            #画面部捕捉框! t  k0 N4 |9 G- Z, K
            cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3): s% L* m9 i, {
            #在捕捉框上添加匹配到的图片信息% B) ]- ]( `. b& b/ N. m
            cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)
    ; M' Z8 S6 a% T' w        cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)
    $ f/ L- k& u9 E% F( F    img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))
    1 Q6 H+ E1 G* t8 k/ K: C    img = ImageTk.PhotoImage(img_Recognition)4 \) w( e( G  }3 {5 J- T
        lableShowImage2.config(image=img)
    & w' j6 k1 k+ a/ ^1 L1 l9 E" y    lableShowImage2.image = img
    ; X, Z8 i5 A6 l$ ~, m    lableShowImage2.place(x=630, y=70, width=530, height=750)$ ]6 H; Y% C* G$ C2 u* q

    , q$ O2 ?' K1 n- X! i  ~- \" ^if __name__ == '__main__':
    ) z, F3 n9 Z* K( n) H, a7 o/ C    findExistsEncodeingList(img_path)
    # @. ]" |. J# a& P0 u* M9 d    #生成tk界面 app即主窗口) ]& L0 O+ ~5 X$ y
        app = tk.Tk()  
    $ U; |: P1 \7 Q% _2 j    #修改窗口titile0 B( [$ L! _* R- U( k9 t2 n
        app.title("show pictue")  
    6 V9 C. {: h  Z2 Y' t, Q. H% v    #设置主窗口的大小和位置
    # ?& h* j8 T6 P    app.geometry("1200x900+200+50")
    ) Q0 B( i$ v3 D. O1 n  L! g8 U+ T    #Entry widget which allows displaying simple text.7 Y, i- u1 w- V5 w
        path = tk.StringVar()
    $ J8 F4 G# q% b. `. o+ h; R    entry = tk.Entry(app, state='readonly', text=path,width = 100)5 ~# S$ q9 N6 G5 I$ R' \/ i/ B
        entry.pack()% g: y; z7 `1 y
        #使用Label显示图片; ~8 u( _$ h/ ~% a- u; v  t
        lableShowImage = tk.Label(app)3 _' {; A$ f( W! f- V; ]* w
        lableShowImage.pack()3 E: I! {* E( o. i- ^
         #使用Label2显示处理后的图片
    : o5 c5 s+ o$ m    lableShowImage2 = tk.Label(app)( D5 i4 z# L6 G9 O
        lableShowImage2.pack()
    % q& M4 O. ^- b9 W% O    #选择图片的按钮! F3 N/ P' x+ g
        buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)& q4 a/ R: {( A4 q1 K
        buttonSelImage.pack()* V1 S* V3 o4 s: M
        app.mainloop()
    " E( {' X: c# ^- E+ b' D  P) d) I; }- d/ u# o
    3.说明) R" D, N9 ]! n0 A2 x7 R2 a4 O
    首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。
    ( [- ]) b6 }/ l. u
    % ~) J: _4 m3 \0 `4 X
    2 k% k5 R; k7 B$ F1 q* Q/ ?1 z6 U9 {# \, M/ l- ~
    其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片
    9 t# U2 C& V/ A& Z$ L( U) W
    ; N" e, ]0 }" I
    & h) v( ~1 |6 @$ t7 t0 K* D8 q) @" a/ Y& t* V" d) C
    但是效果会存在色彩的失真,效果如下:
    $ p8 F$ f8 R, [8 ^* h4 e6 G
    ' `2 x0 ]" |1 k5 z1 k, o( i( k8 c( _% V  @* B: e) e7 u8 J6 c4 w

    $ @# |  {$ Y/ r; \- b8 {9 H) i也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。
    ) f# Y* d& A! g# k5 L7 X
    % I4 @6 C! Y* V5 U这里简单提下PIL的九种不同图片模式:0 S/ x+ l5 r9 U. _+ ?# u" o
    % r# m2 G& T" s. b4 X8 ]
    modes        描述
    . g8 M6 n5 \/ g: ?1        1位像素,黑和白,存成8位的像素
    8 Z2 }2 d. P$ L( UL        8位像素,黑白
    8 ?& E+ _' Q5 r. pP        8位像素,使用调色板映射到任何其他模式9 Q0 Z8 I, p" O9 F, A( S
    RGB        3× 8位像素,真彩
    " g: M0 F1 Z/ I6 VRGBA        4×8位像素,真彩+透明通道
    ( o" X5 G# y- z- o" V4 z+ J) uCMYK        4×8位像素,颜色隔离% ]" m0 B8 o' `  N5 u& q  S8 I* D( c3 J
    YCbCr        3×8位像素,彩色视频格式9 j2 g4 F& @8 H2 D% V& P" Y$ r- j
    I        32位整型像素4 ?2 ]+ i9 m4 c. V
    F        32位浮点型像素
    & Y$ x$ g2 `" [7 J4.实现效果
    ( t) P8 p( h$ M3 n+ O5 V8 H# [$ A8 R0 t: X- [
    $ M  O% d: k: d$ [

    / ^; j- L/ i/ o# i1 y! K- g9 `  R& L/ e  c  i5 F5 d
    可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。
    / R4 t6 o, D8 g- {" ?( t————————————————
    7 ]- }, Z$ V3 B& U$ c版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    ' q0 F, D  G/ H, Z' O, o原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288
    , p7 B) V/ q- K7 G( X5 v0 P' Q/ U! F/ n/ C; A* K7 M

    " e( m4 C& C" F* \- Y# }7 Q
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

    关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

    手机版|Archiver| |繁體中文 手机客户端  

    蒙公网安备 15010502000194号

    Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

    GMT+8, 2026-5-25 08:10 , Processed in 0.351782 second(s), 51 queries .

    回顶部