QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3335|回复: 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实现人脸捕捉与人脸识别(照片对比)
    3 G! S. L7 U$ U- q* V! ^6 H
    0 v5 T% Y6 y. ]# @6 J1.安装包依赖
    $ o; }; A1 T; }% j与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。' }- m# a# C7 N0 s4 O# W. b! y8 {# w

    9 u8 m0 K2 A5 k# z, J5 f6 [2 {在python 3以上版本tkinter是环境自带的,所以这里不需要安装4 ?% \$ C) N# W2 ^0 w5 e' [  U
    ' U3 D( i& e* D0 I5 s
    2.代码示例2 h9 i( \& v3 S4 W  L' g) X5 y3 e: Z! ~
    import os
    ' V, R7 Q3 B% ~* K3 Mimport cv2
    1 V0 w. I1 c5 A9 Q7 g) F6 pimport numpy as np! U- N* f: L( g1 Y5 i" G0 t
    import face_recognition% @+ M% ]$ j4 [4 W. U! n* l
    import tkinter as tk  . w' K+ b4 q+ }! N% _
    import tkinter.filedialog* e, X  }( p2 m: H
    from PIL import Image,ImageTk
    - K" w5 z1 p& b! ~+ w$ ^/ X9 ~4 P- ^' k
    classNames=[]3 s6 E( O: Z  |
    img_path='Picture'9 H1 Z9 G- u! m  }/ w
    img_recognition_path='Recognition'
    ! S1 |  R$ j# v/ KexistsEncodeingList=[]
    " }0 ~( O+ R% S9 p#对人脸集合进行编码进行处理
    ' C/ u/ m# N# A- p7 xdef findEncodeings(images):
    ' ~4 {% j2 e! V( D+ s+ a    for img in images:
    * {% {7 R( o* l* @) c- R/ V$ B* [        #灰度处理
    & v2 I/ Q8 T) C# }" b6 v& w* o" z        img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)
    + h. u$ d/ X7 b" R3 A        #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果
    4 m+ t" l% p9 g! U        encode=face_recognition.face_encodings(img)[0]6 x# O/ \4 @; ^" p/ D3 X
            existsEncodeingList.append(encode)
    + M. L0 f+ Z9 I4 I5 Z/ e. x; w% E
    / D3 E4 @0 P6 D#获取当前存储的人脸编码集合
    9 Z4 J& @! n. S9 |8 F' j$ `def findExistsEncodeingList(img_path):) W6 c2 `: y7 o- p0 T' B
        images=[]0 w, ]* l! M+ I; d
        #列出已经上传的所有图片3 H6 k7 R& q" g' B1 }* ?3 h. x7 D/ v
        imgList=os.listdir(img_path)
    1 }- \) _1 Z& _& S/ f- S, W: L    #处理存储的图片得到其人脸编码4 i2 W9 _* Q  v8 l& |/ l% v. K6 Y
        for pic in imgList:& O; n0 a- h$ f, J  P/ M( J, X
            img=cv2.imread('{}/{}'.format(img_path,pic))4 c! e- D! j! F* r6 m; B7 }
            images.append(img)
    ! u3 |, M" Q9 s& y( j0 K        classNames.append(os.path.splitext(pic)[0])* B/ U# o9 N  C% |6 [
        findEncodeings(images)/ M# M+ {" L4 }+ y2 g/ N. z5 |0 h

    + A, f, V0 b. @; V# p4 l& K6 w#选择并对比图片
    # e2 j4 L- r5 ~6 jdef choosepic():; G' w& v/ ], Y
        choosepath = tkinter.filedialog.askopenfilename()9 ?- L6 P  J. Y  f: C) d- z
        path.set(choosepath)8 d) s! {- e- S* d" H) _+ l! }
        img_open = Image.open(entry.get()).resize((530,750))1 T6 Y* q1 j  B2 [5 `# [6 g
        img = ImageTk.PhotoImage(img_open)
    : o5 U5 Y" B) B. l    lableShowImage.config(image=img)) {/ A, d- E2 M& w% }' g
        lableShowImage.image = img) o- _# j( l% L* h
        lableShowImage.place(x=30, y=70, width=530, height=750)0 H9 k( F) D0 O' J: q. J
        faceRecognition(choosepath)% ^) U+ q$ i5 H- ^; _

    + Y3 g& Z: V- b: N9 gdef faceRecognition(choosepath):
    9 e. @* m7 g' U9 O$ k2 B4 O    frame=cv2.imread(choosepath); _( Q6 ?6 O  f: n2 f* G
        frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
    8 ]& `( N. ~/ f  ]4 j- o" N2 Y    #对摄像头读取的检测人脸
    - v4 h  j9 j) c5 p" A$ b    facesLocate=face_recognition.face_locations(frameRGB). t/ h" I, [* v; }8 _& ]. c
        #进行特征编码
    ( F* m/ d# E! l, X. _6 |8 ~    faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)
    . ]( e' a  V4 A0 W' {        #遍历检测的人脸和库中读取的图片进行对比,计算其相似度! x3 L3 ~- j- `. X
        name='unknow'
    # b- X2 x4 h3 W    for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):; S& P, [: Z! u8 w
            #进行匹配/ q& q2 X4 j* K* ?
            matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding): u7 f4 Z( }2 y& P2 f: _3 V
            #计算相似度9 p; S7 j% ]+ e% m
            distance=face_recognition.face_distance(existsEncodeingList,face_encoding)0 C+ Y  B- Z$ O. t
            lab='unknow'# A. V! _; D$ U6 Y3 Q3 J, i
            for index, item in enumerate(distance):( ^( ^  [9 y: K5 l, L6 p
               if item<0.5:0 {, n) b4 y6 f5 F0 o
                    if matchs[index]:
    % l1 a4 [' F) U* Z7 E$ D' h, ~                    #得到匹配到的图片名称与相似度值+ [( k& n, _8 A, T$ o. N  |1 Y7 _& N
                        lab='name:{}; Similarity:{}'.format(classNames[index],item)
    , {* x8 m" V  w2 w                    name=classNames[index]
    3 A# t0 C! g4 ?% r% G3 b- W                    break) J: s. e$ E/ Q4 n  |6 ]7 w! `1 u
            #初始化面部捕捉框显示绿色
    " t2 a) W6 B0 w! B- s9 Y4 b+ B/ N( H        color1 =(0,255,0): c$ h# a" I8 T. Y7 m
            if name =='unknow':
    - S9 g3 C8 T* m6 {) r            #未能识别的时候显示蓝色
    6 `# v/ n- Y9 e  |- E& T( r  _            color1 =(255,0,0)
    " k7 Q; \+ e- B. ?1 q        #画面部捕捉框$ d- W% P8 k) m4 v7 N, |# R4 ?
            cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3), ~9 q. X; s/ [# G& j
            #在捕捉框上添加匹配到的图片信息! @6 \) }* b' G  z& y: K
            cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)
    . q# o. e0 v. G. f8 z. @        cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)" ^/ B) [7 N" f( Q0 S& J2 r
        img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))0 {3 s9 Q# A1 [$ Q" n
        img = ImageTk.PhotoImage(img_Recognition)" c0 J1 q$ `# P
        lableShowImage2.config(image=img)6 N- ~2 [' f  X! ]) T' F
        lableShowImage2.image = img0 G. F! C/ B2 W# z
        lableShowImage2.place(x=630, y=70, width=530, height=750)
    6 a  k7 ]( U) a6 v$ `& F, Z6 m5 P* B% k" n/ t; x% q! [
    if __name__ == '__main__':. \0 v" j/ ?) Q3 U6 w
        findExistsEncodeingList(img_path)
    9 f* x$ z; R' z9 |    #生成tk界面 app即主窗口
    % r! Y8 D( J$ u' X4 |" |5 l    app = tk.Tk()  
    9 \; c( K9 z) N    #修改窗口titile
    6 A3 A# m: b# F+ l. ~2 t    app.title("show pictue")  . ]6 K$ Y8 Y. y* A) a
        #设置主窗口的大小和位置
    & }3 k3 G/ b' K, U' l; p7 R) ]: N: K5 r    app.geometry("1200x900+200+50")
    # j: M2 s. h* t( X    #Entry widget which allows displaying simple text., W( |/ I5 U" b$ ^/ c$ M  c! H0 l1 M6 q
        path = tk.StringVar()2 ?; N1 @4 w, k  A& I+ `+ b
        entry = tk.Entry(app, state='readonly', text=path,width = 100)
    4 D$ D  g# k, f. w( u    entry.pack()
    8 b/ ^% l* _3 Z( P6 m7 V. y+ `    #使用Label显示图片
    1 ^# W2 r. z4 x' t4 Z    lableShowImage = tk.Label(app)
    / b( @# g$ |8 a    lableShowImage.pack()" _& {3 e" }5 t( A$ W
         #使用Label2显示处理后的图片
    & C3 L% `) X8 w) H7 K    lableShowImage2 = tk.Label(app)
    / \/ Q2 n0 _, y+ u* u; m' Q$ r9 B6 w& ~    lableShowImage2.pack()
    : |! x8 J  C5 l3 N    #选择图片的按钮
    7 W% p3 N# m: M5 |! T; M4 w/ x    buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)! t& n7 v+ n0 y) c
        buttonSelImage.pack()
    " A# j( f% K8 H# X8 q    app.mainloop()
    + i! L3 S& G& `2 `" G' x* @
    1 o% W- b& n9 \+ G$ j( Y3 B3.说明! Q9 E2 P$ p- K0 [. {/ B! n
    首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。& I0 s3 q2 ^- L
    & X2 N' b9 P% z0 r6 S/ X8 M

    : ?0 t+ F( ?; R: s9 `: E
    , I) Z! t2 \# `4 P& ?& } 其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片
    7 u- _1 k+ [( K. |3 H
    0 _, O- F* @. j1 N; Z0 p" g' m. K" N' n, m7 S

    " B5 B8 H9 U- N% j$ L$ ? 但是效果会存在色彩的失真,效果如下:, T' {" N) |* F
    , k8 S4 ]; [2 @5 k2 X( Y
    , w$ \/ r1 y9 r4 u- z
    5 |3 Q$ g8 U& m' Z( `
    也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。  r) @5 n1 M1 q0 q

    + p4 h, m1 o7 [) `, @* V这里简单提下PIL的九种不同图片模式:
    $ }# A. m5 {$ W+ D4 Y' z! Y5 O. T! D) F( r) _3 i
    modes        描述
    2 ]4 p: H7 m/ E/ F! d, O1        1位像素,黑和白,存成8位的像素4 {3 _9 A, S1 n( b9 p
    L        8位像素,黑白% L8 O$ U: D9 \: `4 d( b
    P        8位像素,使用调色板映射到任何其他模式9 k$ `" `: C/ Y9 @- @
    RGB        3× 8位像素,真彩
    0 t2 U% V. B$ P  C# F# |RGBA        4×8位像素,真彩+透明通道
    $ }: N/ a- C& g: S- t* b4 H5 Y' dCMYK        4×8位像素,颜色隔离
    ' V2 K9 [7 Q( y' P8 v2 l; d* FYCbCr        3×8位像素,彩色视频格式7 V. A! l6 A4 a; h4 ]
    I        32位整型像素
      l0 q# a3 j/ i4 j" T$ X1 GF        32位浮点型像素
    % i' `: y( B0 E, T' ]5 {0 q4.实现效果4 X- z' X) \  O) ]6 a7 M

    $ |) y4 l8 z4 i/ S2 A* D
    1 b' }0 M$ ~" d( V$ R% X( Z* b, Y" Q' d" x/ @" m2 {2 n
    ; h, L0 X# o) _
    可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。
    0 s  [- k2 Z; ?" V" {. `+ F————————————————
    ' f5 T6 u" U5 P9 s8 I版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。6 a& x  `) V) ~: N2 L
    原文链接:https://blog.csdn.net/qq_17486399/article/details/1266292880 N! M/ f3 j( C# Q7 Z2 x# s

    ! }2 ?, \6 f2 S" ^0 n3 x
    / j7 M. Q4 W' k' c% j
    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, 2025-7-16 19:07 , Processed in 0.359645 second(s), 50 queries .

    回顶部