QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3014|回复: 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 T; f, t' ~. d6 ~1 N9 r

    ( E7 o0 V( @+ {' q: m( Y; w* g1.安装包依赖
    6 n+ W: b6 O, h- u. f7 ~' v. v与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。
    / ]. b& k2 g# `# E  E% l2 r! _
    * b% H9 T, n9 _' J在python 3以上版本tkinter是环境自带的,所以这里不需要安装: J0 `1 j- Y# {( a/ y

    % j+ N, l* j! S; @. T/ Q: {2.代码示例9 _5 h- d  @" ~6 N! c! q9 `4 X3 x
    import os) U! K5 E; R* o2 j1 W
    import cv28 _7 h: e8 R  D3 U, m5 t' ^
    import numpy as np& S3 ^$ d) i/ Y
    import face_recognition- H2 z9 v) u' W( U7 b& J2 `
    import tkinter as tk  
    4 @8 t. ~! R* {$ M+ yimport tkinter.filedialog
    9 |- S8 _- b6 l$ Hfrom PIL import Image,ImageTk ) T( s1 O* }. ]; H

    " n2 P6 I/ P! h+ K6 D2 h, A0 L2 vclassNames=[], K' n. Q9 X+ u! b+ U, ?" d
    img_path='Picture'
    ) g! i. D* }% X+ Y' H# ^8 _: @6 |img_recognition_path='Recognition', A" W/ }: r) q$ v! h( o1 g
    existsEncodeingList=[]7 y+ ?2 t! Q0 G* }0 j
    #对人脸集合进行编码进行处理3 }# _2 M  E$ ~% D$ J! \
    def findEncodeings(images):
    , w4 g; j9 x9 Z5 P, I    for img in images:7 X' e* y9 C  L4 d$ l2 H6 R
            #灰度处理
    1 I! Y! x  C: `        img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)$ c) w" @5 K5 A) a: @% y
            #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果: T5 E; b  C0 N
            encode=face_recognition.face_encodings(img)[0]
    ' S0 P2 x8 _! H4 R/ E9 K6 d        existsEncodeingList.append(encode)
      _0 u' l$ J! I" I
    / X/ P* q7 S0 V! D' e6 d. y#获取当前存储的人脸编码集合
    6 X/ w8 E! i: q% [def findExistsEncodeingList(img_path):0 m  j/ l9 H1 X5 h
        images=[]7 o$ T. B4 A6 P+ ^0 j3 h
        #列出已经上传的所有图片  x5 w8 V) `) c+ u4 G
        imgList=os.listdir(img_path)8 X3 I2 c6 k8 _/ T) g4 j" O' s
        #处理存储的图片得到其人脸编码
    " }& V! k0 G+ e, W' l/ E2 k    for pic in imgList:6 D. l0 M- a0 E
            img=cv2.imread('{}/{}'.format(img_path,pic))3 M# H% V& |/ [' _3 d* t* R
            images.append(img)
    8 k! q/ k2 h  a; S) _6 f6 E* o        classNames.append(os.path.splitext(pic)[0])* c$ P/ K9 z2 k2 }/ `1 x
        findEncodeings(images)
      q8 n( K6 W  F9 y, T: z
    6 c9 J' \6 r. v+ b, e5 _#选择并对比图片+ X  C' @& J( C4 ?$ R/ M2 [9 C8 B# V) |
    def choosepic():
    ! L) {) s% N$ ^: k5 v) v: m) K    choosepath = tkinter.filedialog.askopenfilename()
    1 k) ^0 p$ R, _4 s- w1 ?3 h    path.set(choosepath)+ S% c, u2 E  H5 h, Q1 F4 U. [
        img_open = Image.open(entry.get()).resize((530,750))
    1 W1 X/ p$ S7 Y/ r    img = ImageTk.PhotoImage(img_open)- t+ x. J3 c; _* A1 F/ a! F
        lableShowImage.config(image=img)
    ! f0 N7 h6 b! X4 @+ M  S8 s) s    lableShowImage.image = img7 @# M/ G3 e0 x) H( B! @
        lableShowImage.place(x=30, y=70, width=530, height=750)
    ' f( _2 h5 o2 o# e$ o    faceRecognition(choosepath)
      N$ w1 D4 L1 Z, k( a+ @! a) \# ^6 k, [' _2 a( Y1 G
    def faceRecognition(choosepath):7 \8 N$ A' `9 `, u
        frame=cv2.imread(choosepath)
    $ K  Y3 y" x( p* l  r& N! `/ r( g    frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
    5 q. L; |) L* I/ u# ?5 X5 ]0 `" @    #对摄像头读取的检测人脸4 T0 o1 b# M2 a% \  U
        facesLocate=face_recognition.face_locations(frameRGB)0 h. D$ U. p1 D$ i9 I- d4 }
        #进行特征编码
    4 [! Y6 A2 e- [. b, t/ }: S: Z    faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)- y8 _& X7 k, O. Z- c7 C) `0 h
            #遍历检测的人脸和库中读取的图片进行对比,计算其相似度! K: B/ |6 n% Q. g& ?3 D
        name='unknow'
    7 \. z6 t9 P+ ~5 C5 M    for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):
    " r. X5 q/ {, ]5 l. H. ]& ]        #进行匹配2 i: F0 Z- R( E$ N
            matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)/ d/ a) S" ?1 g
            #计算相似度
    0 ]  X) \) J4 `! B        distance=face_recognition.face_distance(existsEncodeingList,face_encoding)
    4 n* Y$ d" F9 J9 R( r* b1 ]        lab='unknow'
    2 m0 G/ D, O+ M* E! Y9 ]' u        for index, item in enumerate(distance):
    . J/ @) _. P5 _+ j8 G# s           if item<0.5:; @9 B( e+ B+ n8 U1 L
                    if matchs[index]:
    : q% Q  w) a$ ]  ?: k) ~                    #得到匹配到的图片名称与相似度值
    1 [7 u) U  X. @* ?' O- ~                    lab='name:{}; Similarity:{}'.format(classNames[index],item)2 d7 T; b+ j0 e. w' N1 K* a
                        name=classNames[index]7 Y! a! q) p, |- x0 a8 K
                        break
    5 S6 j5 |: m) ?+ O# @/ ]: ?, K0 N, ?        #初始化面部捕捉框显示绿色
    - N' i6 f, ^" a" B# i2 y, V        color1 =(0,255,0)
    ' Q' H% v/ u+ o+ p* g0 J3 z/ W7 ?        if name =='unknow':
    ; q$ {- I3 H) r, }; F" M& t0 I1 [            #未能识别的时候显示蓝色
    # _3 ~* X( b% B+ z0 @            color1 =(255,0,0)
    0 @7 _6 u% ]( N5 _2 F/ i2 b6 B        #画面部捕捉框8 I' g! i1 T. W* r: y" N
            cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)
    2 K7 ~# H! g* x3 s: J" N' `3 M$ \        #在捕捉框上添加匹配到的图片信息
    4 S; u8 F; F5 m/ B: q$ h% J* r0 o& x        cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)- L' _7 j4 ^0 `: L2 S8 B& ?
            cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)$ S' z! y/ [1 V7 W: S
        img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))) Z( U1 v8 g0 G3 ?+ ~' m  c
        img = ImageTk.PhotoImage(img_Recognition)7 C0 B; v8 [) {1 t% ?
        lableShowImage2.config(image=img)
    ' G1 j8 z, a# G1 w    lableShowImage2.image = img1 O' Q$ ]( u2 ]) U8 [# Q& U8 X# o
        lableShowImage2.place(x=630, y=70, width=530, height=750)* f  d& ~4 ]( B
    3 u8 Q7 F# z- s4 ?- C/ M" D
    if __name__ == '__main__':' V' z! e2 g, V3 m# c3 h
        findExistsEncodeingList(img_path)
    6 N& J, U! B+ I& c* X$ r% l, x    #生成tk界面 app即主窗口! v, S5 s9 L7 r2 O$ r; Q
        app = tk.Tk()  
    9 |/ A! W6 B9 {+ [5 Q3 X; m    #修改窗口titile
    % \9 {+ R) {3 t0 A; o& Y# P/ V1 j    app.title("show pictue")  
    ' V% z7 w* ~- H/ `# F    #设置主窗口的大小和位置1 b9 B7 J2 {- s( t! U! ~: r  @/ ?: p$ X
        app.geometry("1200x900+200+50")/ ]1 T+ j/ @+ l9 `
        #Entry widget which allows displaying simple text.
    0 p3 r- B/ _8 A- c) K    path = tk.StringVar()9 C- a( ~: D7 B
        entry = tk.Entry(app, state='readonly', text=path,width = 100)
    4 n6 L/ B& p8 L: f% q5 D1 d5 e    entry.pack()
    ' e# n- Q5 f3 U; c' k3 B    #使用Label显示图片3 x! ~# L' V* v7 e- x* w; }3 N# i
        lableShowImage = tk.Label(app)- {3 y' C7 {; p( z3 R
        lableShowImage.pack()
    5 p* W& W# @* M0 T$ B# i$ D     #使用Label2显示处理后的图片
    0 A6 W) |) r4 }! T. _" \7 n6 L    lableShowImage2 = tk.Label(app)
    , H- y9 a- ]- L9 P; b    lableShowImage2.pack()0 y$ l/ U" b4 F, l! U2 m% Q
        #选择图片的按钮/ b, H, ]; w$ I  y9 k
        buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)
    % \/ j. m1 h* J& H+ a  R5 t    buttonSelImage.pack()$ B$ G5 m! J- {: I
        app.mainloop()
      R2 f; h; d6 Y. f; i9 |
    7 n1 t  a: a" r3 M3 O; r) [3.说明
    ( i  N. G% ^) E. N3 t8 V) l首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。8 @# D& `4 s/ j2 @

    2 t! I9 L( j* n* ]+ q9 r9 K; T; Z  W9 l* x$ r* u9 F' h6 R3 Z

    8 F* ?5 s# S, J) f0 R% ] 其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片6 v, `/ m  c$ {. H9 v5 x* Y: J
    7 y5 ^8 N: S/ z3 c# y7 I8 ?/ e8 R

    7 @" h  x' G/ @' q' S( C  e+ Y4 z4 m" c3 ?4 O
    但是效果会存在色彩的失真,效果如下:; P) r$ z3 l% N
    6 R+ h% V* S4 n6 @6 I

    . i: `, ~6 W0 d+ W! X+ z
    + y9 \1 U: W1 U, t5 S8 Q' R% S也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。
    2 X5 U4 G1 N" Y+ m
    5 g. T/ z" S5 B4 {1 _. V& a这里简单提下PIL的九种不同图片模式:
    ; ?; H" y$ Y# x: Y1 U9 ~
    4 M; \9 A2 i& v. a1 p5 Smodes        描述
    ) L7 F! S5 l& K+ f( @1        1位像素,黑和白,存成8位的像素! m! l# {! g) h5 p9 @+ W
    L        8位像素,黑白
    / C, P" i  e3 l: PP        8位像素,使用调色板映射到任何其他模式8 O7 a+ E, S, |7 @8 b& w! i
    RGB        3× 8位像素,真彩
    : S- O  I5 m, H, xRGBA        4×8位像素,真彩+透明通道, H8 U. l2 r* y, O
    CMYK        4×8位像素,颜色隔离, y; W  x2 X5 \$ P( k& t. r* W
    YCbCr        3×8位像素,彩色视频格式& n9 d1 F* f7 \" w4 F9 g9 e- t5 v
    I        32位整型像素# h7 D) n1 k0 }; ^  ^/ R7 j
    F        32位浮点型像素
    6 H0 I# a3 ?8 P4.实现效果# D8 h/ W$ q' q) k5 w4 G" D. }
    - \. f; W- d" B% x
    ' h' Z; ]+ J" x5 C  i) P0 Y
      ~0 d) Y2 ], W# z3 v5 j; ~
    & [, H9 A: z5 f/ o; Z- ]. |
    可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。
    : d2 l4 E9 W% l0 _6 z————————————————
    4 g3 y9 U$ A4 {2 J4 K版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。! b5 q" d, c9 g
    原文链接:https://blog.csdn.net/qq_17486399/article/details/1266292882 B- Z9 K# q$ K) r+ U* D

    - l. U  g0 O2 N/ [
    8 b: f! p0 N& U0 a1 g  Y# y( K2 y
    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-6-2 22:06 , Processed in 0.439135 second(s), 50 queries .

    回顶部