QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3892|回复: 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实现人脸捕捉与人脸识别(照片对比)& v7 F3 n' M. L5 U  c3 b8 _

    " V/ ?, q' l! C- r9 F1.安装包依赖
    - |! M) ^) N8 q% _6 y5 P与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。6 o4 T, G4 _5 A" D0 }9 t% @3 l9 E
    4 m. V- D& `5 W7 Z" `' E
    在python 3以上版本tkinter是环境自带的,所以这里不需要安装% h. D. r* B; G" b7 i/ l

      o( [8 i. i8 a2.代码示例
    ) z/ N, ^1 b. W# uimport os
    ! F4 y) X1 K6 {import cv2
    # Z) M# D3 b/ Mimport numpy as np
    " ?, C1 ~  K% g: g2 nimport face_recognition
    ' {1 G' y4 N! Himport tkinter as tk  
      p/ d% }2 t, s: s' vimport tkinter.filedialog! N8 f6 w" q( C7 S, D
    from PIL import Image,ImageTk 7 j7 ^: Y+ i1 j/ m5 ~: t  G& A( e+ P
    7 f' f3 M7 g$ Y$ j- x& j
    classNames=[]$ f% x+ Q2 W9 ]! G" V0 n0 o; g* }2 R
    img_path='Picture'
    ; m4 m+ a& ^' m+ ~! h2 D! S+ kimg_recognition_path='Recognition'
      b& g' ~; q6 h4 EexistsEncodeingList=[]
    & D% {9 Y+ z" D" |. b5 K8 s2 u#对人脸集合进行编码进行处理
    ) n9 @% @( x6 k8 \: Rdef findEncodeings(images):
    - p, z1 R2 k5 O  \    for img in images:9 G0 q6 K, a# f; [- @1 O
            #灰度处理$ f- q3 y; O3 ]* s* f
            img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)
    5 Q: @% w, @/ H: ^, G. {        #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果
    1 q' a/ B7 L& o0 V( e) \2 _        encode=face_recognition.face_encodings(img)[0]
    ) P  [9 L  _/ s0 X- \8 ?        existsEncodeingList.append(encode)
    $ Q$ v" _3 ^- b4 r: S) d1 U  \3 K/ F2 W5 f8 x  \/ r
    #获取当前存储的人脸编码集合
    7 m- A- e) ?/ ~  X& G3 ldef findExistsEncodeingList(img_path):# z- z7 D* H( H8 ^/ k4 y" M9 e+ R
        images=[]
    5 }& A  ~% N  q( y+ j    #列出已经上传的所有图片$ c' y/ l+ \" V/ o
        imgList=os.listdir(img_path)
    ; d, d" M2 o7 U/ w1 X' z9 s    #处理存储的图片得到其人脸编码) a, K& Z! \( P: y* ]" _) A+ J
        for pic in imgList:5 M* c8 q4 I& t; v- z) K
            img=cv2.imread('{}/{}'.format(img_path,pic))
    2 m9 P$ a: k" I. H        images.append(img)
    5 T6 U9 {6 |& J9 S        classNames.append(os.path.splitext(pic)[0])
    - {# B4 t$ U6 W7 ^9 z. X  f    findEncodeings(images)0 l+ S* ^. z3 W0 T2 [- j

    2 c* q+ q& l8 ~' q" U7 f6 }#选择并对比图片9 [+ O5 n' }$ y3 M4 w; @0 Y
    def choosepic():% ]6 X; [# u% o. ?$ A; `
        choosepath = tkinter.filedialog.askopenfilename()
    ' R$ Z# b  r1 F2 l$ ^; F    path.set(choosepath)
    0 v) Y/ Y# y$ p' j' I    img_open = Image.open(entry.get()).resize((530,750))6 j' {/ y' A- m
        img = ImageTk.PhotoImage(img_open)
    - O0 p* S& J% H( f: `3 i3 `    lableShowImage.config(image=img)3 b8 k- D1 E( f4 B7 I
        lableShowImage.image = img) k& _. T, s/ S# l
        lableShowImage.place(x=30, y=70, width=530, height=750)
    & `  j0 W* S6 U( n* {4 u/ F    faceRecognition(choosepath)
    0 o" Z( ~6 v/ r- i  i5 i& I* g8 l. \. t1 ~! d
    def faceRecognition(choosepath):
    ; @" s( }9 e: d4 E7 g' i    frame=cv2.imread(choosepath)3 E+ ]: n! H, H8 C- [/ e+ k
        frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)1 r" [, k- j; _# {  ?
        #对摄像头读取的检测人脸
    9 G$ i. v0 P; }" p    facesLocate=face_recognition.face_locations(frameRGB)" a& U( x: {, N4 T. N4 y
        #进行特征编码+ H/ G3 o+ \5 V8 x" M9 B
        faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)
    5 [4 W4 o0 Z$ Q2 y- w        #遍历检测的人脸和库中读取的图片进行对比,计算其相似度
    . ?# [& ]) c! ^/ K; L) z; j1 A. o# b    name='unknow', l# ?# k' A8 M# g
        for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):" [4 }) W0 c% X0 d6 O* i7 P: j7 z
            #进行匹配/ x! B& Z) D( R
            matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)7 i* U+ ~  ^; N: f* E' c# c) R$ f
            #计算相似度) S5 k. k3 n0 c  z# e* S: |
            distance=face_recognition.face_distance(existsEncodeingList,face_encoding)( o7 t' z. _) |: c9 B3 q" [$ R9 M  S9 N
            lab='unknow'9 r& Q4 ~+ N8 p  r2 P2 _
            for index, item in enumerate(distance):
    ' p0 M, l  S+ }           if item<0.5:
    9 E; F4 t5 d9 m+ Y" v5 ]4 l                if matchs[index]:
    ; c# F: d( }5 u: P& h7 m                    #得到匹配到的图片名称与相似度值- J1 B5 h& [5 K% W# U) {  S
                        lab='name:{}; Similarity:{}'.format(classNames[index],item)3 e7 n" O3 Q+ N* q. g+ S  ]
                        name=classNames[index]
    $ y$ X9 d2 e; r                    break
    $ w; E; s3 ]4 J) c9 m. D, ?        #初始化面部捕捉框显示绿色
    * f5 D7 u- e+ @) \2 D  A        color1 =(0,255,0)8 Q# Q1 o. O- o' s6 }4 d
            if name =='unknow':$ J7 T& ~/ c2 K, l; r$ m" C5 r! L" K
                #未能识别的时候显示蓝色1 S. i+ V* K4 M0 w( t8 w2 G& \
                color1 =(255,0,0)5 M5 B' d# i9 V/ `* }9 \
            #画面部捕捉框
    ( d" B" H- P+ {; A: t: B        cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)
    ! W. a) n7 ?0 E        #在捕捉框上添加匹配到的图片信息6 ~/ V, s, z" |' x2 d1 ^5 |, r1 m/ U
            cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2). F2 x5 f" e! \' P
            cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)( K$ p% y6 [4 X; a
        img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))9 R; L" i- v' [3 z2 g2 ~4 q
        img = ImageTk.PhotoImage(img_Recognition)
    ' y0 o/ P; o8 M8 q    lableShowImage2.config(image=img)" G' G6 d$ `+ j# I: K5 G
        lableShowImage2.image = img! L% c( G/ a: ^) n+ @* U, L
        lableShowImage2.place(x=630, y=70, width=530, height=750)2 i+ ~: x7 X. t5 h/ i& l2 W
    # N  m) Q  o0 G+ \- B8 y2 A
    if __name__ == '__main__':
    # Z0 c( E& d) A/ R# w$ y    findExistsEncodeingList(img_path)3 S1 J! x. V9 Y& K/ r
        #生成tk界面 app即主窗口
    * j6 _1 }# R8 f. A3 k! B    app = tk.Tk()  
    2 j+ l% ~  V5 G0 Q$ S    #修改窗口titile2 [: x( q/ X# j# p
        app.title("show pictue")  : M% |  D+ Z3 B
        #设置主窗口的大小和位置
    ' ?1 a7 D8 V0 B! u+ _/ U5 R4 M    app.geometry("1200x900+200+50")/ t% Z0 K, O( R% K6 W
        #Entry widget which allows displaying simple text.
    & |, E2 B, H7 z! x    path = tk.StringVar()$ t4 A$ t" U4 f0 L4 x$ E% B
        entry = tk.Entry(app, state='readonly', text=path,width = 100)# U+ {4 N4 L# p
        entry.pack()
    2 n) U1 ?+ i2 v; P. ?5 d    #使用Label显示图片
    1 m0 w+ W  `& p( b    lableShowImage = tk.Label(app)
    " n, N: U% @- n- @2 J. y5 {5 D    lableShowImage.pack()
    ! E8 Q7 q; O- Y$ L     #使用Label2显示处理后的图片( S: ~/ P' a0 V4 n& S1 V9 a
        lableShowImage2 = tk.Label(app)- X; N  W8 _  K2 F/ W' w) t
        lableShowImage2.pack()
    ( D- Q3 Z7 B+ W    #选择图片的按钮) c8 p! b0 z* w" k" O1 l2 d
        buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)
    ) d: D/ x& M: d/ |) Z* U    buttonSelImage.pack()' N+ M6 S) J' ~0 t. n
        app.mainloop()
    / i) {0 f  K1 b. B* k& R
    + J6 m8 K  V( }9 B3.说明4 ^; F; t$ V0 c# m+ t! n; M6 i
    首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。
    & b) z) I# }% r( S
    ) z. ~: ~/ ]% {2 K6 `' G4 `* ~- j! e2 T9 N& I

      y; m8 d5 s. S5 [" c) ]7 R/ k; L7 X& o4 s 其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片
    9 X- _+ u  c/ [2 T( G* [2 @# k: t* x4 v. }% }/ D7 J
      w0 b/ J: e2 C& X3 e1 z
    : Y$ X, {% S1 ~, s2 D4 u
    但是效果会存在色彩的失真,效果如下:0 T% c% x  A& z( o  b

    7 t3 M) K6 k; \9 U
    ; b# \# P0 }& c' {
    , i/ u7 {/ w9 d* [7 O6 f也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。. b* |0 A8 m8 b+ x- o( ]

    ; @3 m4 j% X! ], k这里简单提下PIL的九种不同图片模式:: ~1 A  ~, r2 y6 X- m- }
    $ N) M+ U: _9 m; c
    modes        描述1 e2 `8 ~+ x$ G0 X
    1        1位像素,黑和白,存成8位的像素
    ; f2 E3 f+ w7 nL        8位像素,黑白
    2 _. C( G+ E2 r3 F1 h( p, OP        8位像素,使用调色板映射到任何其他模式$ f' l9 m( t6 c, W% }
    RGB        3× 8位像素,真彩
    0 E9 j/ O7 [3 A8 XRGBA        4×8位像素,真彩+透明通道- x9 i8 g+ p$ N, ]0 |+ T
    CMYK        4×8位像素,颜色隔离$ R' R: m' w* W$ D7 v  N+ X* k! l
    YCbCr        3×8位像素,彩色视频格式2 T+ K+ ?! U1 g( k8 e# q8 d
    I        32位整型像素
    # |1 f; k' X+ A1 W/ `/ U% \F        32位浮点型像素4 Z5 X3 A- W- b% @. R/ z
    4.实现效果% K$ E5 J" `! o: |% @, r
    ) F+ N6 K# I3 K+ ^6 ^4 K0 ^( A& Q9 B

    : Q# O+ K7 e4 ^  D4 L4 ~& a+ f
    0 g0 i9 Z$ q- |! u8 C6 f( B# t* W
    7 w9 m" |0 X; L: \& w 可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。( t% W) y4 X; S% M2 v
    ————————————————
    6 P& o. S" g& v( _: I" ]) L$ l版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    $ {3 x2 c: M- V3 r原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288
    " M9 ?4 ?" o) }- Y- ]# @& R7 M0 i( [

    $ X7 I+ v, O# \# N7 x& `
    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-12-5 16:23 , Processed in 2.695530 second(s), 50 queries .

    回顶部