QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4184|回复: 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实现人脸捕捉与人脸识别(照片对比)
    0 a* p# |3 N5 j( Z! u- M+ z' c& E) r8 _7 G6 V
    1.安装包依赖0 |. ]# K3 h) m, [& L% U+ a( t$ f" \
    与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。2 q% \. Z. \" [. Z- ?8 k

    ! S5 r" _' k7 ?在python 3以上版本tkinter是环境自带的,所以这里不需要安装
    7 O7 O8 B; z% G1 u
    6 |# s! S. L' k2.代码示例4 |  G. Y, {( o+ H1 x' Z
    import os
    / C7 g6 W) R$ o; L, ]import cv2! J5 Q3 w4 m& h$ Q( Z0 L& x
    import numpy as np: r6 G8 P, `/ E  B
    import face_recognition% L3 D6 ^1 Z# E) V2 Y* i
    import tkinter as tk  0 q* w2 N" }' H( [' \1 @
    import tkinter.filedialog
    % c$ z$ [. q2 L6 n! S5 {) Tfrom PIL import Image,ImageTk
    1 r* i8 z4 r1 Z: m8 |! {' b1 D3 T" K, v5 k# ?) C! P
    classNames=[]
    8 K, a5 ~- z$ K2 U, Iimg_path='Picture'
    4 L% J5 }5 q( E. Ximg_recognition_path='Recognition'. Q! I6 `0 h, D; W; c0 `! K2 b6 k
    existsEncodeingList=[]
    ( g& F  v+ H1 i4 n8 n! F#对人脸集合进行编码进行处理
    ' q; V" t" T# x8 adef findEncodeings(images):) J( }  }0 h$ _: y
        for img in images:3 q8 N+ t' c7 y% `3 }( v7 o" e
            #灰度处理; `  @6 R; f& t
            img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)
    * f& L  r1 N( s9 R) X        #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果
    ( ~$ k& ?- F) N. w% `1 y) c        encode=face_recognition.face_encodings(img)[0]
    $ Y0 r4 {/ [4 s) r: N; m        existsEncodeingList.append(encode)
    8 B% e/ A1 w3 K* l
    ! H* n- n9 {0 ?# L/ |#获取当前存储的人脸编码集合
    # D! N# `* U/ i" cdef findExistsEncodeingList(img_path):- ], n  c" s. L; d. G) H, C) _
        images=[]
    % A% k: ^& L7 ~9 b2 Q* ^7 B    #列出已经上传的所有图片$ o" o5 o4 U  ]2 T* t6 X
        imgList=os.listdir(img_path)
    + n" I! c% [3 H; h    #处理存储的图片得到其人脸编码
      e- w$ I6 t* @3 H& I    for pic in imgList:- p& g& s: [6 Y4 B+ X
            img=cv2.imread('{}/{}'.format(img_path,pic))7 ]) T, u4 I: U8 ]# B6 a# \0 |$ B
            images.append(img)
    ; X9 T4 }( h$ `9 P* I  B, U9 Y" g        classNames.append(os.path.splitext(pic)[0])# w+ J' E# r2 K, p) H! v& l
        findEncodeings(images)  u6 w' E( }& n8 d' T

    ( Z" x% l9 U" r* i; l#选择并对比图片
    ( D" g0 @1 O: f3 }% Y* [# zdef choosepic():
    ' A4 }/ U  e9 d; h4 l; |    choosepath = tkinter.filedialog.askopenfilename()
    ; J+ K7 e: h* N/ V% g    path.set(choosepath)$ Z9 T/ X  O- G( g8 G- S
        img_open = Image.open(entry.get()).resize((530,750))
    2 ^. m9 C$ r+ q+ E1 n) }' y    img = ImageTk.PhotoImage(img_open)
    * C, u( G( p" C3 U0 @    lableShowImage.config(image=img)
    , \( S+ O' I! O6 Q    lableShowImage.image = img8 k9 Y: T0 J7 p. n& \' |: F2 d
        lableShowImage.place(x=30, y=70, width=530, height=750)
    5 j, Y, o0 X  o7 t( @6 Q    faceRecognition(choosepath)3 o% Q1 Q) I. i: L# O( O

    9 v! u( \1 b) ]+ d/ z* Cdef faceRecognition(choosepath):
    4 N$ b, f# {2 n    frame=cv2.imread(choosepath)" V, A: R, z# M# w9 j6 z
        frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
    ! }/ e0 o% u. b. Q/ E3 V    #对摄像头读取的检测人脸
    & {) \3 |3 s8 w9 A1 s- T    facesLocate=face_recognition.face_locations(frameRGB)1 s, R7 I9 H  i+ }# c. A' j) s
        #进行特征编码
    , a8 k% c( h7 ^% s& n5 n- m! M    faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)" P! \9 X5 }- `$ H& K9 u; O3 z
            #遍历检测的人脸和库中读取的图片进行对比,计算其相似度- ^7 P" m* `1 ?! H
        name='unknow'
    7 Y6 s" \* x- \! A. Y6 S; o    for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):
      K; C; e' d# p9 q7 G: j        #进行匹配
    6 F" ^6 S  Q2 j: }! {9 Q# c        matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding): s' j( Y. F4 i% L
            #计算相似度& T& H% ^4 h) g" g0 D$ i' M% S8 s
            distance=face_recognition.face_distance(existsEncodeingList,face_encoding)
    5 v! ~) h' F& A2 K$ v! Z        lab='unknow'9 s  C4 T3 @4 S, K2 f
            for index, item in enumerate(distance):
    - p- a- `" w1 L- A9 C           if item<0.5:
    : h- U9 c3 I3 k+ ~                if matchs[index]:" L& M& g( A) j  e7 o
                        #得到匹配到的图片名称与相似度值
    % T+ O+ G" j' e2 Z                    lab='name:{}; Similarity:{}'.format(classNames[index],item)5 H! ]( t& n  n( g; m
                        name=classNames[index]
    ; @; O' u( h' a* {) I7 V4 ^. \                    break
    + }2 f) i6 {9 ]9 q2 \$ {; S& ~* R9 c        #初始化面部捕捉框显示绿色
    9 v$ L- H( H! v0 ~0 }& N/ q        color1 =(0,255,0)3 F# c9 R# x. g/ p( U
            if name =='unknow':
    . X$ |9 R% D# r. y            #未能识别的时候显示蓝色
    : `3 b: J0 R) E, y' e: ^# b            color1 =(255,0,0)
    / q& U/ d) l: U+ H) K' z        #画面部捕捉框
    ; R2 |7 e9 k" L6 C' X        cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)3 a4 j) Z# |) ~2 ^. D* _! h
            #在捕捉框上添加匹配到的图片信息
    9 }$ @! `9 c7 u        cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)
    9 g3 |* Z# E  @4 ^9 e# A        cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)* u% v% f4 ?4 I/ o
        img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))% \0 C0 |" q4 O1 B, v. S
        img = ImageTk.PhotoImage(img_Recognition). a- y( b9 K' n% C6 n3 {, a
        lableShowImage2.config(image=img)
    0 t  ?" _9 L# e/ N* d7 }5 S7 C    lableShowImage2.image = img
    0 f" Z  |; R6 e( \    lableShowImage2.place(x=630, y=70, width=530, height=750)' {7 z3 H, R, {7 b

    , x. c1 q/ p) e& uif __name__ == '__main__':5 |0 H# v8 z5 E' F* Z- x
        findExistsEncodeingList(img_path)& K2 X* T5 j0 L, @  f" Q% o! ]
        #生成tk界面 app即主窗口4 m; V' n5 M& G- |1 F. B
        app = tk.Tk()  1 r: C* g* {' @( F5 L" c
        #修改窗口titile
    # `' k+ b5 q% h7 g: h8 ?* b( M; g    app.title("show pictue")  ' R/ z1 _* x$ Y
        #设置主窗口的大小和位置
    % |$ q- Y: n9 G' c# ]    app.geometry("1200x900+200+50")6 F: f# z) _% o8 P7 r, H( J( P
        #Entry widget which allows displaying simple text.
    2 |1 V2 z7 V: h0 o    path = tk.StringVar()# N3 r3 s9 M$ [) w1 W3 e, }  \1 N
        entry = tk.Entry(app, state='readonly', text=path,width = 100)
    ( G3 t9 P/ W3 ^' f    entry.pack(): P6 Y# ^' p6 p1 L
        #使用Label显示图片
    # t  \7 ?( l0 j    lableShowImage = tk.Label(app)* Z* }' @' D* |1 L, |6 d% M' }% U
        lableShowImage.pack()$ b, }4 F9 B- H# Q, X0 ?/ ~! Y
         #使用Label2显示处理后的图片
    & J6 @8 Y8 {5 W    lableShowImage2 = tk.Label(app)
    . }  {1 l# m9 k3 D. b    lableShowImage2.pack()* H, x) p" U8 w% M
        #选择图片的按钮
      R+ V2 K) u8 T* h1 p  d- G    buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)
    - ^/ D' A  n) f  G, c2 G2 J    buttonSelImage.pack()' F: @. |9 r  U; L, I
        app.mainloop()
    & s" c, O* K. J6 j; @8 r
    - C$ F  G# e- t6 n0 m+ i; i' {3 Q3.说明: Z8 s0 B+ v+ u% q+ T
    首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。( N- D8 L% |4 u5 N4 w" @

    6 d& i- g# Q6 W4 u
    , M% n/ p! Z$ U
    3 D9 D; @/ d$ x4 y$ ^" v; R# S 其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片
    ' f( J# E# q% f1 [; x; s
    + @# Q! N$ l6 @4 B! ?5 L8 C: F
    7 J2 ?9 g) `: A! X  q& ?* `/ H# w& Y9 T
    - g1 ]; K, s) X 但是效果会存在色彩的失真,效果如下:
    ( m, l+ p% D4 M2 m; p
    ; R8 t9 c4 D* u/ P$ ~$ ]& k( x5 n  F) s+ K

    & Q! x+ i. x& k1 ~# Z8 S也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。: T" U/ |" e! {, `; F
    9 T" t" X0 F, p1 v' O
    这里简单提下PIL的九种不同图片模式:$ P( w3 N# ?2 r7 X* k6 c

    - V/ T3 O8 r( f' nmodes        描述
    ' q' ~2 G, V! w7 N" k# ~1        1位像素,黑和白,存成8位的像素
    ; r8 O6 V  n, X0 F: _L        8位像素,黑白
    + Y7 F* B5 G% J4 ]2 g/ {P        8位像素,使用调色板映射到任何其他模式
    : g" W' j! K$ G0 MRGB        3× 8位像素,真彩( G3 c/ ^' c( m; Z( |
    RGBA        4×8位像素,真彩+透明通道; Q% p/ K2 p& M4 [4 G. S
    CMYK        4×8位像素,颜色隔离. A9 y9 f+ [  a0 z) l
    YCbCr        3×8位像素,彩色视频格式) ~5 W; D6 f7 J' L' P# K
    I        32位整型像素
    ( b* k' L8 F+ _) Y9 CF        32位浮点型像素
    $ v0 a2 c/ Z2 q4.实现效果
    + \/ M  U2 T, J3 ~. d; J- k5 K- p: p0 n( R3 h. `6 [9 d
    1 [  {1 R5 L0 f. ]
    $ I1 n$ x' ~5 N; @7 k" a
    / @1 x! v* M: B# s+ ^
    可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。
    2 j4 R4 c$ p9 M( V————————————————5 v8 B1 s: [# u+ t# u
    版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。: u( i) o' Q4 `7 I3 q/ p
    原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288
    1 Q; p& y" v- E+ ^  M* U: C, u/ E; m+ r( V
    1 N# Y. H+ r; _, }1 ~1 ^) h% O' b5 S
    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-9 12:19 , Processed in 0.316441 second(s), 51 queries .

    回顶部