QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4141|回复: 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实现人脸捕捉与人脸识别(照片对比)
    1 Z& R& t2 O8 p3 p% T$ }& u4 y/ |0 {" M, t* v# C0 [! X+ }5 W4 s
    1.安装包依赖
    2 e  u( R8 l% c- M4 g. w% e与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。& g" |; I  }( P; x
    , H$ u; f; A! Z0 B
    在python 3以上版本tkinter是环境自带的,所以这里不需要安装
    ' b8 K, z, [) x/ Q( Y! ~: ?6 ]9 n3 t3 x! L# Z
    2.代码示例
    0 l- [. x* m7 y- G% b% h. Z. t6 jimport os
    3 L: g( s5 Q& T2 n1 z2 U/ u; Pimport cv2
    ! ?# U2 |, `  o8 R, n6 qimport numpy as np
    : K7 p8 l- ]/ f3 T" fimport face_recognition. m% `" w) U5 ~, B6 X$ G
    import tkinter as tk  
    " e0 s' `3 t) d* l% S& @7 aimport tkinter.filedialog2 `8 q" ~! m5 N! t& V' Q, D
    from PIL import Image,ImageTk ! K: Y/ m) ^0 Y$ N+ z1 S/ R1 g
    0 ~4 {: u. m5 L" W* t4 t2 ]
    classNames=[]
    , K' O1 Z% J$ q9 Y" ~, ^. R- nimg_path='Picture'" b- \6 ^  t) R5 a4 Q
    img_recognition_path='Recognition'. n* W! M5 C. H" d1 o
    existsEncodeingList=[]
    6 h  l) J5 c( A) C#对人脸集合进行编码进行处理4 P* l. N' @2 Y; [
    def findEncodeings(images):
    " D# x4 ~' b) g  N0 z4 z) ^! h) }    for img in images:
    : @. j( L  e' f: R3 u2 f        #灰度处理
    * t7 P9 t  z" v2 \* E0 z        img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)5 T1 y2 ~4 _- h+ c. e; K
            #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果% d6 g: ]) z# }( O$ I# ?& k
            encode=face_recognition.face_encodings(img)[0]% ?' s$ L4 _! ?/ v2 O5 j  l
            existsEncodeingList.append(encode)- ~% l7 `+ c  W

      S1 {9 C% R: E4 _7 J' j#获取当前存储的人脸编码集合1 N+ t/ _1 N+ j, U9 w7 l$ w
    def findExistsEncodeingList(img_path):
    ' T& s7 H4 |, m1 D1 |& \& b9 v    images=[]( [8 y. |- F- n# N5 E1 b/ S
        #列出已经上传的所有图片/ j4 v5 o" E" T- C2 @
        imgList=os.listdir(img_path); B" U7 c" B2 `: k, h9 M
        #处理存储的图片得到其人脸编码
    8 W% j# t+ l. q! w  \* k    for pic in imgList:+ X5 a; A# }& A/ m) B* m
            img=cv2.imread('{}/{}'.format(img_path,pic))
    0 x: k2 J5 S) A" X* R, s! o        images.append(img)/ I, t' x7 l& |) z9 B
            classNames.append(os.path.splitext(pic)[0])# Y( T) w5 W& c" X2 W* N: r8 G
        findEncodeings(images)
    2 {8 q- E' j2 ^1 u7 F. l' j6 L% o' l8 [9 s" A
    #选择并对比图片( D9 k4 F- W! C+ N+ J
    def choosepic():
    / ^4 v) o$ i  L* f, O& Y" o' _6 ~. y    choosepath = tkinter.filedialog.askopenfilename()
    1 E7 j+ P& c- ~    path.set(choosepath)
    / y) D( h. N/ c    img_open = Image.open(entry.get()).resize((530,750))% U( t! B4 {; N) w) Z* H* b
        img = ImageTk.PhotoImage(img_open)
      O. W, Z; {  C2 f/ ?- _+ ^    lableShowImage.config(image=img)3 J' p9 {6 N& l
        lableShowImage.image = img
    5 H! q3 `( L3 |3 D# P5 R3 z    lableShowImage.place(x=30, y=70, width=530, height=750)
    2 h5 `1 I& k: n4 R    faceRecognition(choosepath)& U  n4 R* _0 t

    ( w/ _( _: K2 Q$ m% W. W. adef faceRecognition(choosepath):
    ' O9 h" r) a. d. n- Q' [    frame=cv2.imread(choosepath)$ l; R( z( _3 C' {) [: t
        frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
    8 P' D7 E+ i0 n! Z9 ^, i; {2 x% c    #对摄像头读取的检测人脸
    2 w4 H2 b( q. e: w  _, y3 @    facesLocate=face_recognition.face_locations(frameRGB)
      U0 W) {$ R+ a( U! j& r# p    #进行特征编码. ]9 g. {2 ?8 ~6 x$ e% W
        faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)
    ( @+ O# t$ @' v  c/ h& `        #遍历检测的人脸和库中读取的图片进行对比,计算其相似度9 w! S% |( |1 p( }# h0 w. N
        name='unknow'
    ! b1 ~' S4 _# k1 z    for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):; ^) a# H$ c: i: d7 N8 S0 P
            #进行匹配  y$ ~8 V$ G0 ^3 W4 l9 b
            matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)5 L% r- b- B: O9 N
            #计算相似度6 y0 N7 M3 v7 o) F
            distance=face_recognition.face_distance(existsEncodeingList,face_encoding)
    # q! i- _0 m& O# h0 J        lab='unknow'
    ) j+ G- J- [; a, r: C+ C1 R$ l* w        for index, item in enumerate(distance):4 M4 K) v( I8 v/ Y; N
               if item<0.5:$ c: D' T' B& z' y8 G
                    if matchs[index]:
    " t4 c+ t% ?* w# B                    #得到匹配到的图片名称与相似度值6 \* l% a' q6 n: j0 i+ ^
                        lab='name:{}; Similarity:{}'.format(classNames[index],item)7 ~7 ~* k) x" [" N+ I) N6 I9 W7 t
                        name=classNames[index]& b1 |9 p+ }6 f# s  P
                        break5 W7 [( X; t2 G5 c- t/ @( O
            #初始化面部捕捉框显示绿色5 J1 Z6 O0 h0 o2 ^
            color1 =(0,255,0)
    : Y8 d5 x4 ?" H7 ^3 ^+ k/ \  ]        if name =='unknow':1 g7 D/ x$ n, E1 c/ T# A, u
                #未能识别的时候显示蓝色
    . r) |, u5 E+ h" h            color1 =(255,0,0)
    0 k# H5 ?5 r  L, F! \) k        #画面部捕捉框1 w+ q  K9 B, p3 }1 B9 ?( E
            cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3): ]2 b9 x0 P5 ~! N8 F0 y3 w3 H
            #在捕捉框上添加匹配到的图片信息. R! F# g# M! N! i2 n
            cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)% d! b: x: v$ B
            cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)6 f' Q9 |; P2 ^8 d/ C( C
        img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))+ y% {7 q  M, i. A* ^
        img = ImageTk.PhotoImage(img_Recognition)1 L8 j- R8 s& B6 F
        lableShowImage2.config(image=img)
    8 C3 X, f$ Q  V' r( U$ ~    lableShowImage2.image = img2 I. p7 Z7 \* h. R
        lableShowImage2.place(x=630, y=70, width=530, height=750)8 i7 [6 a2 @% L4 V2 S' f; @) A

    " d' A& h7 U5 ~" Q* Rif __name__ == '__main__':+ L- x- A- }+ V  A; ^
        findExistsEncodeingList(img_path)/ H) H0 C9 ~6 e4 r
        #生成tk界面 app即主窗口
    , M% D- e/ N+ p/ X( ]    app = tk.Tk()  , [3 |2 A9 G( P  t
        #修改窗口titile* O3 S6 a9 m6 `+ L" b/ H0 L7 _
        app.title("show pictue")  
    " v/ p. G) P& }    #设置主窗口的大小和位置
    # q* n' P) _1 x! O7 W1 ~% t    app.geometry("1200x900+200+50")2 E. R* I8 U) H2 q! u$ C/ j  v; Y2 R
        #Entry widget which allows displaying simple text.
    7 d% ]7 q0 ?4 }    path = tk.StringVar(), `. S$ T' p7 @, D% M" _
        entry = tk.Entry(app, state='readonly', text=path,width = 100); N/ |/ O2 e* m8 ^7 v6 b+ ]
        entry.pack()  H1 j) e! h! z9 Q) a. |
        #使用Label显示图片
    6 A/ T3 T; s- X    lableShowImage = tk.Label(app)) y) o" A' p6 |+ l) I& n  u/ M
        lableShowImage.pack()
    4 T! x; `1 D. r, X- q1 @0 `     #使用Label2显示处理后的图片
    . k  z' R+ N1 k. K    lableShowImage2 = tk.Label(app)% X7 G: }4 K' z$ ~4 B" Y
        lableShowImage2.pack()
    0 G  a% X. U5 b) Q# `2 K    #选择图片的按钮. X( g8 K4 s0 H8 x2 c! {. E
        buttonSelImage = tk.Button(app, text='choose picture', command=choosepic), v1 l( L9 \0 C; O, Q  k* R+ F
        buttonSelImage.pack()! ~- r* n3 l# M0 p$ @" d+ @1 z
        app.mainloop(), ~0 R" h1 P( Y- [- l% x

    9 b" H- y2 H2 v2 z- g, j3.说明
    ; F& L" ?0 H0 E' U# N# f首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。
    ' R/ A2 V/ x1 Q- i  R* p7 B7 E" M& j; m- L3 \* t
    " L1 w. s- `% L/ e

    . Y6 m) n( A: K* r- j 其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片
    * R. W; s2 r1 l! `7 E5 f
    . |7 j: C4 I2 D! d' D: l/ B( _# e( T8 u4 p- K+ D

    8 z3 T: V; l! e, Y" | 但是效果会存在色彩的失真,效果如下:% B, Z/ N  c9 S1 S) `7 R
    8 b  @9 E6 D  Z; X" X
    ) h+ x+ D' ^' E" B1 N& f% t. W

    3 m( ~4 D6 N8 j1 Y! p6 T也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。
    6 H1 R4 @7 p+ I  [" x
    2 p1 w8 B! n1 ~3 w% l) t5 q3 ?1 q/ @这里简单提下PIL的九种不同图片模式:
    * O* m; u8 ~9 ?, w; C* z" `8 c
    * P+ C; I& x. t+ F3 N. [, Hmodes        描述: I. c1 T* ?: q7 z& J( a. C# _
    1        1位像素,黑和白,存成8位的像素2 G. b8 r2 X' S0 z  r; k
    L        8位像素,黑白; e" E% \+ C- o% w9 n: z
    P        8位像素,使用调色板映射到任何其他模式4 \0 y2 Y2 f& @8 O1 O; w
    RGB        3× 8位像素,真彩
    2 }: _' y5 M+ g" j& NRGBA        4×8位像素,真彩+透明通道
    / E7 `" X5 A9 fCMYK        4×8位像素,颜色隔离/ P4 u5 |/ N5 k2 I# Y! B" M  r+ n
    YCbCr        3×8位像素,彩色视频格式
    ' [# ^8 ]' E& A) t/ c. jI        32位整型像素3 Z2 q0 f2 k% |5 D- L
    F        32位浮点型像素& A5 h! R  P9 S0 z5 p, |' P4 O
    4.实现效果
    7 O4 x; c9 y; G# n7 c
    ' Y3 r- O/ n6 N6 Z9 W, O4 X% f; n. B5 x' U
    - F' p9 `! l1 O. B: M# w$ L
    % p$ ?6 U4 j+ X+ [
    可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。. a# g. N. T5 V& ^, H$ B  B8 m
    ————————————————
    % ]9 e$ W3 X3 @9 a3 j9 O版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。8 p5 I* L6 v' y# W) ~5 j& w
    原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288
    0 S( r: B9 s$ c! T+ q3 ?9 E% {0 p8 G$ f( [+ E0 x( g

    - t- H% R. i! e- T5 U/ T, {  _
    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-4-9 20:32 , Processed in 0.613790 second(s), 51 queries .

    回顶部