请选择 进入手机版 | 继续访问电脑版

QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 84|回复: 0

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

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

4879

主题

75

听众

15万

积分

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

    [LV.4]偶尔看看III

    网络挑战赛参赛者

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

    群组2018美赛大象算法课程

    群组2018美赛护航培训课程

    群组2019年 数学中国站长建

    群组2019年数据分析师课程

    群组2018年大象老师国赛优

    发表于 2022-9-14 17:07 |显示全部楼层
    |招呼Ta 关注Ta
    Python 基于OpenCV+face_recognition实现人脸捕捉与人脸识别(照片对比)
    7 e5 i' n3 {% D! }8 Z; c! |! ]6 z- x6 R: o0 @
    1.安装包依赖" C8 k7 ]5 N. x1 t1 q
    与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。( y8 t1 q5 Z0 t* T8 p. a) _
    3 Q: E7 r. L/ r
    在python 3以上版本tkinter是环境自带的,所以这里不需要安装4 }. P2 E3 S) ?
    ! U# h1 G; b6 l7 Z; S, @- R$ y5 @# W
    2.代码示例
    0 F# O  D) T; a2 Limport os) \# L1 |* u: M/ n
    import cv2
    9 Y8 m. e5 }$ L% J5 R) e: _9 uimport numpy as np
    8 D+ k9 e9 w  w, p5 l( kimport face_recognition
    " q* l- Y4 G  z/ B. zimport tkinter as tk  
    1 G2 c: J( @7 ^" Y3 zimport tkinter.filedialog
    5 i3 x* _# ^$ K: |/ vfrom PIL import Image,ImageTk   Y5 w8 I  h, j
    : W/ s4 x& M* S. h) l( A& R- t  i4 m+ w
    classNames=[]/ G6 p# y, N/ X/ T/ g
    img_path='Picture'
    6 ~: \2 p# a% Z! D+ cimg_recognition_path='Recognition'
    ' m6 R/ `) j' f4 i! u* B, jexistsEncodeingList=[]
    * g* A5 e1 D' U0 N+ E7 r. S- R#对人脸集合进行编码进行处理- Q; K* k" v' ^7 [' Y3 {4 C
    def findEncodeings(images):
    9 |; \! y% H6 R4 Z* F! J( g8 E9 g    for img in images:* M* f) k; l' S4 y! R9 q
            #灰度处理
    + x' ~$ J- u+ U& p6 Q* c: P2 B        img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)# q% q+ C5 F7 L( c2 V
            #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果+ X# N6 L' [7 @0 s
            encode=face_recognition.face_encodings(img)[0]
    : V' c/ p* O* O9 A        existsEncodeingList.append(encode)
    " R- B, j% P- l# J8 L# P( u7 z4 |  T( Q+ }
    #获取当前存储的人脸编码集合
    ; q  y" ^. {- W. Rdef findExistsEncodeingList(img_path):
    7 W$ _7 o* y: I; @8 @    images=[]4 }" M  N7 H7 K2 x, ?8 |4 W6 Z# a
        #列出已经上传的所有图片5 n& k: |2 P. w8 s. ^6 P* _
        imgList=os.listdir(img_path)! G" c& R. |4 k& B- Y" e
        #处理存储的图片得到其人脸编码$ c" X5 @2 g! b+ G5 p# E
        for pic in imgList:
    ) H9 }  h7 p, ?        img=cv2.imread('{}/{}'.format(img_path,pic))
    - K3 Z) Z/ q+ D+ S2 f( b        images.append(img)
    % x4 i  i9 o3 Y        classNames.append(os.path.splitext(pic)[0])
    ! `0 y, `1 C' P- m, j! a    findEncodeings(images), R6 n( w8 ?# Y% d( K
    # ]# Y2 j* b& V9 U* i
    #选择并对比图片
    $ ]$ _) U8 c# Mdef choosepic():
    $ F) M: z; I. Q    choosepath = tkinter.filedialog.askopenfilename()& P0 k- {5 [5 Z
        path.set(choosepath)' e, I" y. n( t5 U' T5 x) i. D& R3 z
        img_open = Image.open(entry.get()).resize((530,750))
    : B  ]) m$ |8 B& k5 ~    img = ImageTk.PhotoImage(img_open)1 E2 {- F+ e* ~3 j
        lableShowImage.config(image=img)$ o) K) f& S: K1 y: [% z9 L
        lableShowImage.image = img
    * Z9 z9 n- n. C" y' K6 Y    lableShowImage.place(x=30, y=70, width=530, height=750)0 O# l: ^* q+ ~* X! g: u6 s+ Q6 t
        faceRecognition(choosepath)
    . T* ^- t" z& G8 U
    % I, t8 H. E3 b% L8 }6 e, _def faceRecognition(choosepath):
    , F. u' U/ c- I  p# u7 D    frame=cv2.imread(choosepath)
    - m# b* V# u* h- ?    frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
    / ?5 X. S9 ?3 D2 H    #对摄像头读取的检测人脸* n2 z6 p; I; {5 m
        facesLocate=face_recognition.face_locations(frameRGB)
    8 S5 i1 a2 S2 P6 P! x  F1 O" S    #进行特征编码
    2 f1 b5 L! L/ d9 u9 p/ R+ b    faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)9 ^2 d& ~) w( R
            #遍历检测的人脸和库中读取的图片进行对比,计算其相似度/ L/ ?% g3 p: _4 L0 l
        name='unknow'3 h7 s" h% @$ _$ p9 V( y
        for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):9 ~" K8 P$ u% N, d
            #进行匹配
    " T1 p$ _6 Y$ w" Y/ x1 e        matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)
    4 }1 S+ c8 E6 r0 {/ O        #计算相似度6 Q: U2 M' }/ e6 D
            distance=face_recognition.face_distance(existsEncodeingList,face_encoding)
    5 z; w. a5 l, k0 P8 w5 o4 y        lab='unknow'
    . U$ @+ L# D9 h3 T8 O% ^        for index, item in enumerate(distance):3 N7 L0 G2 F% A! e3 ?! A5 H
               if item<0.5:
    6 z) ~8 X3 X! K# W& c% G                if matchs[index]:
    , ~; f  z' G: I0 E* _& j2 k                    #得到匹配到的图片名称与相似度值
    , ~8 j! g8 a( z! \0 O  L' ^/ [- n                    lab='name:{}; Similarity:{}'.format(classNames[index],item)
    ; n. p7 h' _& e) T$ n1 m                    name=classNames[index]
    7 `1 w4 }1 q* M4 l$ }/ ?                    break
    1 Y4 J8 y- z7 A0 q! j        #初始化面部捕捉框显示绿色
    * @! [* g" D1 Q+ L2 ]        color1 =(0,255,0)# ~' V& H9 o! Q& ~4 O3 s; t& s
            if name =='unknow':1 ]3 P8 A& \) J) @! Y$ Z
                #未能识别的时候显示蓝色( x+ Q7 k! o/ x3 W" u+ E
                color1 =(255,0,0)1 v4 c( J/ v( T8 e: G3 h
            #画面部捕捉框; S4 R- i. W4 e( p& E" I
            cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)  S; }$ J0 F. c) G2 C0 N1 h# v
            #在捕捉框上添加匹配到的图片信息
    2 U. x2 E2 E7 S6 e$ Z        cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)
    0 v# p9 x/ c. y4 s        cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)
    9 b( ^' _! {. y( I4 M    img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))
    5 F. ^; C) u4 {    img = ImageTk.PhotoImage(img_Recognition)% E) I2 Y3 N! c/ k$ y& x
        lableShowImage2.config(image=img)
    * ?# K3 h9 L) R; a1 i    lableShowImage2.image = img
    ! E7 [6 G- E# I" U% G! ^9 k    lableShowImage2.place(x=630, y=70, width=530, height=750)
      c% i; z! m( x" j& ~
    $ b' h/ S- e* |if __name__ == '__main__':  H8 K- F/ Z: n6 q* |
        findExistsEncodeingList(img_path), i/ w9 L5 [2 S1 I- t9 M9 Y
        #生成tk界面 app即主窗口5 G$ q+ Z; g  K  w0 Z; p6 F1 f  ]
        app = tk.Tk()  " b- u; T0 e! \8 }# B: `3 @5 _
        #修改窗口titile
    % v. t$ c( T! M    app.title("show pictue")  
    2 R$ t' x) c: O' O    #设置主窗口的大小和位置# u' y! o* f$ q; b
        app.geometry("1200x900+200+50")* e* x8 M. W- ~* R: x1 V6 v' @
        #Entry widget which allows displaying simple text.
    * |! D; q5 L2 X    path = tk.StringVar()
    4 i8 t% a- Z" Q3 P* T; f' X  `    entry = tk.Entry(app, state='readonly', text=path,width = 100)# X6 y* c5 Y# b& ?: [
        entry.pack()
    ; _5 f/ d" y3 L; h  H8 Q    #使用Label显示图片
      b% A: ?: |5 I0 p    lableShowImage = tk.Label(app)
    ; @2 k6 O( f0 a% [) A% ~    lableShowImage.pack()
      G3 f+ O8 @* l! F1 U9 E& o     #使用Label2显示处理后的图片
    . _2 @. A( x: g' K7 |    lableShowImage2 = tk.Label(app)
    1 B$ Y7 [3 T7 J( `1 L, [" k( p/ A    lableShowImage2.pack(): k4 W3 L* Z! F, `5 B
        #选择图片的按钮
    # M6 J) f+ N) O7 B/ L; c    buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)
    2 N! c& }& Y% }: N, k5 i# e" H    buttonSelImage.pack()
    ( ~# M; D1 `; ~2 D+ d& C6 u; H    app.mainloop()
    , A  x1 p4 y" s, y9 M; C3 g5 l1 `% U+ p
    3.说明
    0 x* L, n: b! a$ g' O首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。
      d8 ]3 R! p% ~4 B; t+ q3 {0 H
      O- K+ e- m9 e5 y7 b/ {  ^" o& `: @1 }2 z4 Q3 U, E
    & K( w& e$ r( g; I4 F% u
    其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片
      U+ ?% q) [) D- j3 ]: H  p$ z: [  t# Y

    : n3 E! f& [3 t2 t* g: k# j: ^( F1 _2 F4 I" {# R" b0 v
    但是效果会存在色彩的失真,效果如下:
    $ K: _+ n- g" O% T6 j
    8 m" s% b7 `! K% D! k  k+ e
    6 X: U: C$ |. |$ V
    $ H( s9 _: X% n0 }& U' B" \也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。# W  R- h1 E! k) ]/ j6 ?$ l

    7 ?+ g) m# I* a/ G这里简单提下PIL的九种不同图片模式:
    - }* g" P, f9 d
    1 V9 D( H. `0 w' L1 v2 A% e  Emodes        描述
    4 ~  B3 A4 A% a& I+ I8 {1        1位像素,黑和白,存成8位的像素9 u' k; n+ j7 ~( k
    L        8位像素,黑白) O4 s' \) }- Y. I9 T
    P        8位像素,使用调色板映射到任何其他模式) A" A7 G: m0 A
    RGB        3× 8位像素,真彩' |; V- n, D/ ^6 V
    RGBA        4×8位像素,真彩+透明通道
    - N/ H9 Y" W2 z" O+ M  U  xCMYK        4×8位像素,颜色隔离5 s; d% [0 f6 p, a+ Y; x9 g+ m3 @
    YCbCr        3×8位像素,彩色视频格式
    5 G% a" r' B( H* V. W. v. A' tI        32位整型像素1 v/ x1 l6 V: o' q+ q4 I" [+ X
    F        32位浮点型像素
    8 g6 d; T- |* ?" K! K4.实现效果
    8 @7 q3 r* j0 w1 U$ j! m  q, X) w/ A# ]; o8 y) D$ t6 Q

    ! Q* Y) w; [; `! D! G% ]
    7 Y% }/ B( Y; ~
      V, I7 l# I) U( y 可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。" i9 {  L9 l( k8 X3 C8 H
    ————————————————' [# l$ j( ^( G& z& A" `
    版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。- v" M# q' r# [6 k
    原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288! z1 g* V, Y. i( s
    / F7 C8 [, z" }" R: W& n9 r
    ) ~; W1 z) Y/ Y2 M
    zan
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

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

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

    蒙公网安备 15010502000194号

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

    GMT+8, 2022-9-29 22:13 , Processed in 0.652493 second(s), 52 queries .

    回顶部