QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4190|回复: 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实现人脸捕捉与人脸识别(照片对比): y0 L/ l; R4 R2 |" q9 t' m
    1 C* ~5 \' ]& b4 M0 o& m+ m4 l% B& [* n7 h
    1.安装包依赖
    1 q' K$ I2 z( R2 @( r4 x; U, l与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。. {9 E( ~" G6 q. d, x8 M3 c% v
    6 A! Y8 y& v3 R/ O7 N. X/ G0 S6 T& z
    在python 3以上版本tkinter是环境自带的,所以这里不需要安装
    5 P( {0 F) V/ R- ^* X( t
    , Z) x, G' y% B  ~) _2.代码示例
    3 L+ M7 N- h9 K( Z% T3 b) Gimport os
    : g2 a  B* t. w# Aimport cv2
    3 X1 }' ~) G3 q, fimport numpy as np9 z) f( J/ b' I. `6 b5 [! c4 ~
    import face_recognition
    ( U' W' L( ^" W# x; \' pimport tkinter as tk  , K& q3 k! ^( `' d8 T
    import tkinter.filedialog6 Z2 L0 v$ n# D; b
    from PIL import Image,ImageTk / j, s* X- Q& A& Z9 a8 F
    1 U4 q3 p. B9 Z: h' X, L0 G
    classNames=[]0 T( l0 \+ i, S1 Y
    img_path='Picture'
    ! F( `8 z: ?. l+ ~7 n: \- ~img_recognition_path='Recognition'
    " J* D5 w& H6 ^4 k1 yexistsEncodeingList=[]! `4 g& B; p$ ?6 l; r
    #对人脸集合进行编码进行处理2 _* j, k! m6 c% A
    def findEncodeings(images):
    4 S- {% {9 n$ h" O    for img in images:6 J: `2 e& z& w5 [5 p6 [# U0 w" H
            #灰度处理
    7 b5 |' n9 }3 g5 F        img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)% I- }2 h+ A. R/ R. d4 Z" X
            #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果# e3 W% V; [) D8 `
            encode=face_recognition.face_encodings(img)[0]
    ; S0 t0 S4 Z6 T7 z1 k, c        existsEncodeingList.append(encode)
    : \2 d. y0 {/ A+ A# }. r& k! w0 R- Y
    #获取当前存储的人脸编码集合% ?; {7 _" T- w0 B
    def findExistsEncodeingList(img_path):
    0 h" b5 U( l' ?    images=[]
    ; N9 h. H% a, y0 t    #列出已经上传的所有图片1 a; K, z8 B1 l; b4 u
        imgList=os.listdir(img_path): i: ~: Z) _6 L/ e$ {
        #处理存储的图片得到其人脸编码! q$ Q! P5 N. w: n! Y4 P1 Q
        for pic in imgList:$ e9 g- }+ {( A
            img=cv2.imread('{}/{}'.format(img_path,pic))
    3 j5 Q* m+ G) G. {) ?3 }        images.append(img)
    ' t( v/ y: I8 b' e$ l        classNames.append(os.path.splitext(pic)[0])6 G2 j8 M' ?) i
        findEncodeings(images)! F; G/ w- N2 }: H: S
    % k) {* n, X0 w1 p
    #选择并对比图片" M6 w% v' R7 l/ {
    def choosepic():
    5 p- J, c) S" T+ k* W8 z- b) N2 O4 D    choosepath = tkinter.filedialog.askopenfilename()
    2 B5 p& `( N, S3 E* J6 J# a% t( X    path.set(choosepath)
      h5 s$ H- k5 c. K: |5 C    img_open = Image.open(entry.get()).resize((530,750))
    : e  U2 T0 x7 z# ?9 n/ L& w8 U    img = ImageTk.PhotoImage(img_open)4 ^% ^) r7 o6 y8 Y# e3 w: f6 s* e4 W1 Y
        lableShowImage.config(image=img)
    2 [- ~1 A/ h/ q4 Z' ~    lableShowImage.image = img, h( m: P0 \9 r# o
        lableShowImage.place(x=30, y=70, width=530, height=750)
    * H. U9 s# }+ M1 g9 V8 Q& l    faceRecognition(choosepath)
    5 X/ F7 W! [! h& f
    * {( n, u- w1 I/ l# ^def faceRecognition(choosepath):
    * F$ ~7 m3 h2 ]& L9 x    frame=cv2.imread(choosepath)
    4 L, X1 s. B+ P. V1 h    frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
    ! h& o+ S  O1 \    #对摄像头读取的检测人脸
    1 k# H" Z9 N' U# ~: L3 T$ e    facesLocate=face_recognition.face_locations(frameRGB)
    " W5 Q6 |3 m: i& F; E9 P4 E    #进行特征编码& }: G6 J& X: Z. v" ?5 E$ P
        faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate), ^$ ?4 d- X9 ^
            #遍历检测的人脸和库中读取的图片进行对比,计算其相似度
    ) ^: ~4 b2 d! \6 C5 M+ V    name='unknow'
    - ]5 K5 T5 B* H7 l8 u+ S    for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):4 T$ o+ T- t% S
            #进行匹配0 k9 r, s: ^, O4 q9 p
            matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)
    $ r, _- K7 J' C* p0 B        #计算相似度
    ; w; y) t8 a' H% r! m8 Z& M1 W        distance=face_recognition.face_distance(existsEncodeingList,face_encoding)
    : D" J* y% e; }  l7 f. c/ e' M        lab='unknow') G/ [2 m! i9 b. M
            for index, item in enumerate(distance):' J: D5 Z8 _+ v* T0 T% @
               if item<0.5:
    . v3 h3 p' o# a2 i6 B: @' J                if matchs[index]:
    / a7 Y$ m! k: d) e                    #得到匹配到的图片名称与相似度值4 ^, S" I) G' w8 `3 {
                        lab='name:{}; Similarity:{}'.format(classNames[index],item)1 x& \# X5 A% a' V1 U7 \
                        name=classNames[index]
    : }5 `6 s2 u) G" L                    break
    0 |7 {# O" h, O  @        #初始化面部捕捉框显示绿色
    5 w3 G3 `5 }3 o. p        color1 =(0,255,0); d+ B# h2 u! T- H: e' i7 Q& n
            if name =='unknow':* d. _9 Y- X: k) s( R
                #未能识别的时候显示蓝色9 n; i5 [1 N5 S
                color1 =(255,0,0): W# h6 ?. g( Y' ?1 X
            #画面部捕捉框
    1 R6 B3 j- P. \: Q& r+ |. S        cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)& J6 Z1 `) I9 k) g, \: t* ?
            #在捕捉框上添加匹配到的图片信息# q! g' u4 [3 v$ C
            cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2); W# P( b# z- }9 C$ v, Y6 G/ I
            cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)6 S6 L/ P. S1 [7 y* f& i
        img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))
    6 r* f: _  ~" c, Y  z7 c* Q* {    img = ImageTk.PhotoImage(img_Recognition)
    * M* ?$ L& U* `6 T* |    lableShowImage2.config(image=img)
    / X) }6 T; [! `    lableShowImage2.image = img; H. j3 ?2 w* L: V" v: o- J  Q
        lableShowImage2.place(x=630, y=70, width=530, height=750)2 r+ ~8 ?. G3 z; Q# M& y+ D2 ~5 d
    , m6 k# X. O& D0 v7 |* [
    if __name__ == '__main__':
    * t! }. h3 \7 m" E    findExistsEncodeingList(img_path)
    5 R" o# K0 g- M& }5 j) {    #生成tk界面 app即主窗口
    ; }2 P; G1 r8 `. ?2 b% [, T    app = tk.Tk()  7 h2 a# {) m6 E2 i4 R  t- Y
        #修改窗口titile3 k8 S. I4 W; X* l- U
        app.title("show pictue")  3 I6 B4 D0 Y3 L. I  O! Y7 `% j
        #设置主窗口的大小和位置
    7 W/ W7 ?9 b% Y' ~0 J    app.geometry("1200x900+200+50")) f" x# X: k3 G. y2 n
        #Entry widget which allows displaying simple text.
    0 C7 h- W* C* N( R$ P    path = tk.StringVar()* \! P7 x7 b$ h) l3 }$ M' e  p
        entry = tk.Entry(app, state='readonly', text=path,width = 100)
    : C; p+ S8 M- K$ O5 x+ T    entry.pack(): g4 d$ P) L) ?* L# q
        #使用Label显示图片
    / W) l; M( @* }    lableShowImage = tk.Label(app)' `5 o4 O8 r" {9 [) x
        lableShowImage.pack()1 E9 t& f: E5 s: N  i
         #使用Label2显示处理后的图片6 u: z7 j3 @- L; W
        lableShowImage2 = tk.Label(app)) H: T+ b  E, u; @% }
        lableShowImage2.pack()" b8 O) q. P) t8 |( y9 s0 U0 a9 a
        #选择图片的按钮
    6 Z4 c, i0 B& M5 G7 l) n    buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)3 q4 x$ Y, o. y: d0 [
        buttonSelImage.pack()
    ! K3 k$ J4 J, g# i6 g$ I/ T    app.mainloop()
    5 c$ F5 w1 ^5 @8 _2 @
    3 I5 M* ~2 ?9 x+ v! ]# v3.说明
    . J( V, k, S! i首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。
    ' G3 k2 G: Z; L; Q8 `4 t( T- h; m, P* D9 {* ]( h
    + Z- @1 r) C) i7 a  `
    ( x6 k5 I- b2 Q; @5 |% m  ?0 E: a
    其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片" [3 W, U+ f8 v2 e: b$ `$ K) O1 U% h
    , x6 }' v7 c- }. K7 ?* W

    ! d- w( s0 _* o4 {2 }- W
    6 B* n/ n* [4 t1 A; } 但是效果会存在色彩的失真,效果如下:$ Q/ t2 |" X7 d4 f! a( c

    ) V" O& r, g) g1 N, Y3 \) R9 j! S& q  C8 H
    . P; R' i2 N# S) q1 ~
    也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。5 ], ?" k1 v" k+ K5 k+ u

    ) O7 Q# k) K& O- x& V这里简单提下PIL的九种不同图片模式:5 e% v# j  W9 C! B' t
    ' m, {1 u' X2 }9 O5 v. A
    modes        描述
    ) ]2 |& w' C5 }4 X+ b1        1位像素,黑和白,存成8位的像素6 `9 E) Y7 z6 c( h. b8 y! F% b& \
    L        8位像素,黑白2 _# M2 d4 d5 B" X' a4 }
    P        8位像素,使用调色板映射到任何其他模式
    ; b) o" s2 j- ~& Q+ V0 Y# LRGB        3× 8位像素,真彩7 j& E+ u- u1 |# F% T4 g1 T% g3 R' [! N
    RGBA        4×8位像素,真彩+透明通道& K/ A$ \  o. y( d% L& s
    CMYK        4×8位像素,颜色隔离% k8 v/ s+ p- m( m- _+ }: x
    YCbCr        3×8位像素,彩色视频格式
    # V# x: o0 n/ w4 ?7 Z$ yI        32位整型像素+ @. W$ q+ V- d- A* N  s5 n. ]
    F        32位浮点型像素
    1 L) E7 H: a* \- w4.实现效果
    ( h: f, z  }/ Q8 b
    . ]7 B, s* ~7 }! \0 l6 J& c
    : y$ Q! V! t9 k+ l
    , G/ M0 E7 T+ {9 j( k+ M9 }
      E1 Y. E& T" J' |4 g7 \" D. i 可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。
    1 l+ X- @+ e. d% a————————————————- ~. X( p) m9 o& a5 q0 _
    版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    6 M! O" G* a* i  O- t8 @原文链接:https://blog.csdn.net/qq_17486399/article/details/1266292881 i7 j+ [7 L& W- J1 t0 t" q+ c. u
    & l- y) G' Y  [* Q

    1 `  x2 K: l3 |8 z8 S/ 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-7-10 04:38 , Processed in 0.652864 second(s), 51 queries .

    回顶部