QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4282|回复: 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实现人脸捕捉与人脸识别(照片对比)
    ' V+ L& y- ~9 o5 j1 B
    " D1 O" r' y: q1.安装包依赖1 Z( O  w6 `# Z9 [/ c2 [# d
    与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。
    8 t1 S6 h5 O; U- k5 v: t3 Y+ u/ E3 f( ^3 F
    在python 3以上版本tkinter是环境自带的,所以这里不需要安装
    " Z# d4 I/ P4 j0 Y) F2 l( J- D4 y  X$ ?. S" b3 k8 E6 @5 W
    2.代码示例9 R# c( e2 C9 w9 x  f5 R) H
    import os
    - E7 S. P- O. V) bimport cv2
    4 P2 O: Y0 N. |+ X6 bimport numpy as np- T7 Q# g! e9 [! K2 g
    import face_recognition4 q" M8 W8 C; e& Y+ ^* a* g, x1 V
    import tkinter as tk  
    - f8 K: L2 {7 ?. N8 [import tkinter.filedialog
    % F( v: F0 Q# U) t5 q. Kfrom PIL import Image,ImageTk
    ! r0 p& E' h# @, x( O& S# U6 t5 n" n6 C- M& J2 b9 C' s: r
    classNames=[]
    " _/ k7 F* |7 p2 @; Z9 w0 k1 t# kimg_path='Picture'1 t5 L; P6 g" b5 U
    img_recognition_path='Recognition'+ L& w! T# K- Z: A) f. }; a9 R
    existsEncodeingList=[]$ Y9 G! ^# S3 K0 R1 \: b3 [4 A
    #对人脸集合进行编码进行处理( }9 x2 W! Z/ }& ?
    def findEncodeings(images):
    ' m3 y1 K- {, c/ l; p# \/ M    for img in images:' V; a! D* p) U
            #灰度处理0 ^( i$ f  @" W0 r, K
            img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)
    " d2 ]( P: K* G# Z5 u8 D+ s8 U        #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果
    ( u/ ]& t) [) K% I        encode=face_recognition.face_encodings(img)[0]: d6 _' M* n6 ?, R  g" D
            existsEncodeingList.append(encode)
    , k" v: w6 A- O7 q( n; d. M# [
    + o! \3 z$ t+ q- P# k#获取当前存储的人脸编码集合
    8 V6 V; R: W2 w: cdef findExistsEncodeingList(img_path):+ O6 s" L" M8 n6 J2 j6 g
        images=[]
    5 {: [) N2 ^  Q1 V1 ^, C* a9 K    #列出已经上传的所有图片) t: T7 e- H( I$ E/ s
        imgList=os.listdir(img_path)- ^4 a' P  @- Y5 `5 n* ^* _+ f% B% d
        #处理存储的图片得到其人脸编码6 w- t. K( P( t, C1 ?% u- i. l0 J
        for pic in imgList:
    3 e; e& _4 B3 [, o* I  t5 @        img=cv2.imread('{}/{}'.format(img_path,pic))
    3 \6 `3 v/ @  t        images.append(img)
    * J$ I3 Z2 I- r6 W( Y4 A        classNames.append(os.path.splitext(pic)[0]): _' Y6 H' O$ }! G  ~' @
        findEncodeings(images)9 ], v' Q2 b( }9 I! \; D
    * n4 n  `/ w! }  C' t* u4 e
    #选择并对比图片/ @( h. @- B0 T3 Z# p9 S" [
    def choosepic():
    + A8 V$ O  V2 E! B    choosepath = tkinter.filedialog.askopenfilename()# u9 F& G3 ?) D+ X+ L
        path.set(choosepath)
    5 F% U& e8 M+ d: C$ W' \: W    img_open = Image.open(entry.get()).resize((530,750))
    : |1 q3 V- C/ X' {% W    img = ImageTk.PhotoImage(img_open)' w5 v5 L3 z; Q3 a1 e
        lableShowImage.config(image=img)
    # f4 @/ T8 p: B) Y/ Y' x    lableShowImage.image = img
    $ w1 ^4 h3 Q# [    lableShowImage.place(x=30, y=70, width=530, height=750)/ @5 w& r, R+ I. @5 b: ]
        faceRecognition(choosepath)
    1 E  H7 Q+ D# i+ Z  e
    , h- X2 D, l/ x3 c( h% gdef faceRecognition(choosepath):. p; K5 T+ w' ?5 x
        frame=cv2.imread(choosepath)
      K+ \6 d% C- U# j& _6 k. [( U2 [    frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
    $ m$ S( Y( N7 d/ v5 t    #对摄像头读取的检测人脸
    4 Z3 s+ ?& q$ b3 ^  \: \* f: S    facesLocate=face_recognition.face_locations(frameRGB)% }1 F  s% V  g- b, o3 r
        #进行特征编码5 ^# ^- m- _  w& ]
        faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)( Q5 v2 C) a8 z, a! l+ J) k
            #遍历检测的人脸和库中读取的图片进行对比,计算其相似度
    9 O- f/ f1 K9 l, x" m' s" \, @    name='unknow'
    , ]& X  B; K  q* x  q    for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):
    : _4 V3 E9 `& d1 k  X$ \3 p" l        #进行匹配; c7 [3 s6 B- v: l; d6 G5 e6 ~
            matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding): b9 Z" P) j: w5 h5 P/ n& ?2 ?6 ~
            #计算相似度4 v/ `' T: M9 Y8 }7 A
            distance=face_recognition.face_distance(existsEncodeingList,face_encoding)
    ' t0 y# g. L. L  C. q4 T9 s        lab='unknow'0 n- ?; G8 \; @
            for index, item in enumerate(distance):
    4 \/ F( k9 N3 M8 `2 I! Y           if item<0.5:8 w3 _) u0 K% v  s7 y! V) t8 c2 i
                    if matchs[index]:
    . ~9 `8 S% Y9 K                    #得到匹配到的图片名称与相似度值
    : w9 N/ S9 o4 q5 ^$ R% `                    lab='name:{}; Similarity:{}'.format(classNames[index],item)
    0 i4 y' v* W# @' h* y6 F                    name=classNames[index]. R+ j3 D+ X- [; x6 P
                        break
    . v* i' T. }. F, V2 U  V+ Y" W7 H* [- w# v        #初始化面部捕捉框显示绿色
    ) Z1 P; }0 D! x; H        color1 =(0,255,0)
    : n  Z1 P; L/ M/ _8 I* D" b3 J        if name =='unknow':7 T7 ]* M$ B: m7 ~2 j" y! t/ ]0 K4 P
                #未能识别的时候显示蓝色
    , x2 G9 Y2 W" l! Y            color1 =(255,0,0)
    7 j( Z) B: P, R/ j. k        #画面部捕捉框( `' {! u( E6 |; b7 \" i
            cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)  g/ u9 S; A- z# O. K
            #在捕捉框上添加匹配到的图片信息- i# n2 I  d( K# o. X3 e7 k! g
            cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)
    4 H9 i' d+ R# T' u% x# x) Z1 t# X        cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)
    4 _0 ^$ g* w8 z1 |5 S! S    img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))' I+ ]! O2 x  a0 X
        img = ImageTk.PhotoImage(img_Recognition)1 T3 \( W4 Q  b$ o. t
        lableShowImage2.config(image=img)
    & g" U; H+ N1 W9 _% D    lableShowImage2.image = img; Q& k" v, f+ W8 m
        lableShowImage2.place(x=630, y=70, width=530, height=750)8 c: W: \& U  U7 v! _0 Y- e( L' @

    7 g+ t6 V; b3 l" m5 b% bif __name__ == '__main__':
    1 d& r3 P) ^1 R( ~0 K' b( p    findExistsEncodeingList(img_path)
    8 F; C+ S- q, |    #生成tk界面 app即主窗口
    ; ?( u" a) P5 ]4 X! x% n    app = tk.Tk()  
    ! P$ D4 c4 F; x; B" [    #修改窗口titile; I1 i) |9 Y9 J8 g! t
        app.title("show pictue")  
    7 A. y( z: @# {! W' Y& s! o- Z    #设置主窗口的大小和位置
    & e: b- {: D  L- Q  W* r    app.geometry("1200x900+200+50")
    7 c0 W# m  h3 u1 y( M    #Entry widget which allows displaying simple text.' k, N, G$ ^% s6 E- `8 \9 [4 q
        path = tk.StringVar()
    9 C4 z& e5 @, K6 l! a    entry = tk.Entry(app, state='readonly', text=path,width = 100)
    $ X- I! G3 u$ N2 B5 H' `    entry.pack()
    ; e9 ^& s' Z' Q    #使用Label显示图片
    / ~5 o( l/ A% j1 m% z. p$ A" m    lableShowImage = tk.Label(app)
    5 ^/ D+ _, b6 [    lableShowImage.pack()
    ' O- g# |* e6 @     #使用Label2显示处理后的图片" `# y0 l; c- f8 P
        lableShowImage2 = tk.Label(app)
    4 y# G- H2 n2 N4 Y4 b4 U6 H  L& M' n    lableShowImage2.pack()
    0 L) y$ {9 m$ ]  C    #选择图片的按钮' C( ~% b- p5 v& f. M4 }4 e
        buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)  {5 }1 v: E' ?) _# b+ U0 w
        buttonSelImage.pack()
    3 I/ G* V* u# w8 E    app.mainloop()
    . Z6 j8 i/ e# ]3 P( `; i
    7 V5 U. X' B4 H3.说明
    : p3 i- }) _$ M. h7 k; O首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。
    / K" u1 V: A; N
    $ X% G( _) E) S1 x4 {! _/ H7 t" [% q% w0 {) r8 O6 a$ j% |
    2 I- a5 l; }1 H+ y. v5 w; E8 @
    其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片
    / V* q$ e- J6 N) [1 u! T4 s; X/ S4 Z+ `- t$ B5 c/ F

    ! Q  q! a: G/ \
    0 u0 D) c. T8 y0 C4 s3 X 但是效果会存在色彩的失真,效果如下:
    ! S7 _" D6 U0 W
    . P% W, t2 P7 r3 |  J0 ]+ J2 |) u2 w3 _$ D. B0 V* m( j6 b3 L& O( f( U
    : x# ?( f( J4 |% M
    也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。( j; H. f0 r4 ~
    ' P' v- k- P1 n. ~
    这里简单提下PIL的九种不同图片模式:  i( \' ?0 J7 o+ g( O

    2 J# z# F6 X% |  Ymodes        描述  U4 K  x3 k. m" x4 x
    1        1位像素,黑和白,存成8位的像素
    : t- W( w* R9 H- O2 gL        8位像素,黑白
    # f9 f$ @" @* y; A* uP        8位像素,使用调色板映射到任何其他模式+ O4 y2 h& ^$ |( X; P% b2 m4 l
    RGB        3× 8位像素,真彩
    - i6 p) W) I% W; O* G0 [RGBA        4×8位像素,真彩+透明通道5 p9 @3 S! f7 j, }) J
    CMYK        4×8位像素,颜色隔离8 X$ Y: K+ {3 }9 {% ]3 z" @
    YCbCr        3×8位像素,彩色视频格式
    1 d+ Z2 d: p2 t; O0 c- f) eI        32位整型像素! N. p' H* r+ i+ d! X: C4 B
    F        32位浮点型像素
    ( l$ S$ v" E" z7 ?7 M! ?4.实现效果" j; w, U* D( t
    ( n9 k6 i* p) P# Z# @' w9 t' ~8 Y

    3 R2 ?' s$ c3 R) O" x
    9 g/ C/ X$ x1 i/ ]% y/ f( _. w( @7 F" `! A5 n
    可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。/ E; t8 S4 X5 [, Z! C% d! {
    ————————————————  _0 {/ W" H! N4 v' z) y7 T+ k
    版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    ! U% j$ C3 x0 h: a: o$ f+ N1 W原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288
    + D" H8 v; Y+ }# C9 `  j) W
    ' k/ b/ v: u+ M
    ) Y; N# J# _' w, 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, 2026-10-10 07:18 , Processed in 2.391934 second(s), 50 queries .

    回顶部