QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4280|回复: 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实现人脸捕捉与人脸识别(照片对比)
    8 K# y5 e/ n$ v! P+ [0 Y- X; e5 R0 q5 P  a! W9 ^( V, k1 }
    1.安装包依赖
    3 }4 ~$ @+ `5 g. p& b与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。' q5 [) I7 V) v
    1 w& t9 ?$ H- v  A$ N8 o0 u* k+ z
    在python 3以上版本tkinter是环境自带的,所以这里不需要安装
    * Q& F; y: n1 n) i: _% Y6 l7 |
    ! }$ k7 ~4 v3 G# D. ]0 \  v2.代码示例
    : b, c$ ^" M+ I2 y8 k; A- q) |import os1 n8 \# y- j4 N3 }
    import cv2; Z* ?0 k0 `. h6 s% i! `# u- Y
    import numpy as np8 M2 I' k! V) K3 @/ r
    import face_recognition
    : f: e( T3 P( z  l3 Q$ wimport tkinter as tk  3 T" c2 w! Z" p! }& x$ E
    import tkinter.filedialog' U7 M; \: r7 q' @$ p# ^
    from PIL import Image,ImageTk ! g' F- ?. f' \0 D- M: _% K
    + U% B  a3 |! [0 |3 e
    classNames=[], c8 X$ O: T9 e- a* T. p# Y+ X
    img_path='Picture'/ P) Y8 t! n! y. n5 D5 @
    img_recognition_path='Recognition'
    $ N- @" ^$ t0 c' ^: {existsEncodeingList=[]
    ) C, v' O0 M) ~+ h9 n#对人脸集合进行编码进行处理
    8 z9 W3 `% q, Q8 a( F4 xdef findEncodeings(images):
    ; P$ O( o4 m4 c5 h9 w    for img in images:
    % @5 K6 J6 j& w        #灰度处理
    2 h6 o4 O' b' m; S* E        img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)
    , t+ J" w' z; I" N& o, O  `; q        #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果
    ) f8 e4 t& g2 G# W. H1 {        encode=face_recognition.face_encodings(img)[0]
    ' |9 p: o3 j+ v& V, X        existsEncodeingList.append(encode)7 ?' t' ^7 ?8 V! Q3 G3 l. r

    ! w  {+ L1 V4 ^& C7 }/ N#获取当前存储的人脸编码集合
    + _! ]! u' Z! W: h1 |$ v" Fdef findExistsEncodeingList(img_path):4 @- U; g! y- y8 V
        images=[]- D8 C0 e7 b5 ]" d' f; Z% s
        #列出已经上传的所有图片
    3 A  ?  W0 c5 ?/ Q! M    imgList=os.listdir(img_path)
    / z3 D  F+ E- I/ r& O+ s6 h    #处理存储的图片得到其人脸编码
    + ~/ h3 Z5 C: c8 i    for pic in imgList:
    ; O( B5 _) h! P  X" E6 a: Q        img=cv2.imread('{}/{}'.format(img_path,pic))
    / I% C6 R8 `4 |: v1 j        images.append(img)7 ^& t- F* F2 b  Z) j5 p
            classNames.append(os.path.splitext(pic)[0])" `' P" E9 M. @/ K3 s
        findEncodeings(images)
      m0 S8 H, W9 t/ y& k/ I, \* {$ ~. I% U" w
    #选择并对比图片
    ; l) l" E% V8 E( M( B" ndef choosepic():
    & E) u6 j2 s+ N3 [$ E6 K: _    choosepath = tkinter.filedialog.askopenfilename(); t7 ?; {6 ~8 ^2 P
        path.set(choosepath): Z. P0 y8 b8 l& a- v' r) {
        img_open = Image.open(entry.get()).resize((530,750))
    " J/ S" Y8 H- ^) ?2 f/ C% e$ X    img = ImageTk.PhotoImage(img_open)$ z! @( ^* L9 P7 G4 {% @
        lableShowImage.config(image=img)# _! O# z; A- N9 Q: F/ K
        lableShowImage.image = img
    / [. ?% @9 u) `% N    lableShowImage.place(x=30, y=70, width=530, height=750)
    " D! S# F( _5 r# _  ~+ M* s9 F0 k$ ^    faceRecognition(choosepath)
    3 i& L; ^+ X* @+ M7 T
    8 [0 O: f' r4 L! Y  H) x+ Idef faceRecognition(choosepath):
    ! ^7 `, H; v! q# _4 y/ N    frame=cv2.imread(choosepath)  U! O/ q5 _$ Q6 b+ g- E
        frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)* g8 h' p( Q) R% r7 Q1 h
        #对摄像头读取的检测人脸" X  @( W' R4 V$ ?
        facesLocate=face_recognition.face_locations(frameRGB)$ Q( t' b- ?& N* M3 _
        #进行特征编码( G) f4 e2 j# r) u$ G
        faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)4 q- a6 {/ K( \( ]9 C# o9 f/ `: Q
            #遍历检测的人脸和库中读取的图片进行对比,计算其相似度
    / ?! v& w! a& d    name='unknow'
      s$ d- q  {2 M    for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):
    ( q( k- l9 ]) T6 c        #进行匹配  ?4 n7 u% \3 B* `, d; M# t
            matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)
    ; E9 l( ~, h' L        #计算相似度" c5 F6 c7 n! j8 ~0 L
            distance=face_recognition.face_distance(existsEncodeingList,face_encoding)# t( [0 H7 J. V. ^, S
            lab='unknow'
    / m7 L" r" ^! S        for index, item in enumerate(distance):
    6 I5 g8 _& [0 ^9 R( b: A# Y           if item<0.5:( H& N1 ?& ]. T/ p0 O7 D
                    if matchs[index]:  n- m- y) T& O9 v. A
                        #得到匹配到的图片名称与相似度值5 R/ C/ g$ Y* O. ~/ I! Z& r
                        lab='name:{}; Similarity:{}'.format(classNames[index],item)
    : [. w7 C8 }2 k' g, ?" D$ c                    name=classNames[index]
    0 w4 M$ u' @) ]- q- G( Z                    break
    6 O0 K3 Q& Q8 t( Z$ N5 B1 N" Y9 Z        #初始化面部捕捉框显示绿色& k% B4 g9 i9 Y
            color1 =(0,255,0)4 Z0 X9 l1 F/ R; i6 H
            if name =='unknow':# |4 ^( I) q, Y2 y0 b
                #未能识别的时候显示蓝色3 q, @" A5 \$ K
                color1 =(255,0,0)3 v% Q7 L/ K# ^# n9 i# s0 S
            #画面部捕捉框# n7 v' L/ A2 a
            cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)
    / A2 z2 q  T! T+ P        #在捕捉框上添加匹配到的图片信息
      m' [& \& L  Z' x! Z        cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)
    4 F% |$ A" W- m6 H0 d. V        cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame); ~+ X: T  V* S/ h
        img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))
    9 T7 j" K$ [# L1 B3 b3 A    img = ImageTk.PhotoImage(img_Recognition); J4 M) [. a+ u* Y
        lableShowImage2.config(image=img)
    " U; C# K3 F# K' l    lableShowImage2.image = img
    $ d4 ^/ }4 ]* P) ?+ H    lableShowImage2.place(x=630, y=70, width=530, height=750)
    : K3 a# C! f" E5 b& M! {$ ~) G  B2 J# q6 @, d4 w
    if __name__ == '__main__':
    4 r9 L. Z  x' F+ ~    findExistsEncodeingList(img_path)
    4 e) p. \) A& ~+ A$ O# `+ K' D7 C    #生成tk界面 app即主窗口% u& y  B3 ?5 x8 q5 Q- z# ~9 O# ^
        app = tk.Tk()  
    ; Q6 N) D# Z+ e" {! |    #修改窗口titile
    / w4 Y, z4 N2 X8 N$ K, o2 J    app.title("show pictue")  6 W( D  E* ?' Z, J0 Z
        #设置主窗口的大小和位置) H& Z+ [. ~) @7 l5 j' y
        app.geometry("1200x900+200+50")
    ( Y) U3 T" r# m    #Entry widget which allows displaying simple text.
    & b. W3 B! c2 C. u7 o1 q    path = tk.StringVar()! ?) c3 n  _  E4 [4 |5 ?
        entry = tk.Entry(app, state='readonly', text=path,width = 100)
    0 k+ o+ c: U( x+ ~    entry.pack()
    % g& T0 o2 y, R7 w1 N8 x$ O    #使用Label显示图片7 u$ J+ s% Z8 h
        lableShowImage = tk.Label(app)! C* ]4 ?  W8 X5 C. G8 v# Z9 Q
        lableShowImage.pack()0 k# e) |' Y& n  Y1 o
         #使用Label2显示处理后的图片' ]4 g8 F3 D) W7 L1 w' q) {
        lableShowImage2 = tk.Label(app)
    9 X5 F  u$ T* T7 L: w1 o4 P0 N    lableShowImage2.pack()
    " J0 G( C) }$ u% n9 C    #选择图片的按钮  l) ]' H4 j* \+ D' K: R
        buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)3 Y1 e, k& t% x2 H
        buttonSelImage.pack(), @% L* v5 V0 w* t7 ~! t) w
        app.mainloop()
    * G7 f7 Q: Y9 l# b. e- u! T, O) w  a, \' F6 G: J: ~! U
    3.说明# R; |$ X$ S: }: S% z& A% L
    首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。! E( x$ h9 e+ y- }& P5 a, S

    7 ~: r3 d. L+ g1 u( |- K3 [7 H. ?$ d" G6 ?# J

    2 u, i3 G% W3 k4 j- }0 I4 w# | 其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片3 f& K- p) D' y" g. F( }
    # {6 E+ b. v" m- h0 U# I$ ]

    3 _6 f, h4 V8 Z! b( _+ A' I. `' W. y
    但是效果会存在色彩的失真,效果如下:1 W  r" f  C5 l; w
    7 U2 i0 R  Z7 C0 S$ y5 m

    ( z3 X9 w" J) \! I
    - r4 @; m5 e) M8 r% E也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。  F! u1 J' [/ {3 V) @6 J- d) y0 R
    - l8 B" [' _+ N. a
    这里简单提下PIL的九种不同图片模式:  W8 f: q' S  L9 t% p7 {& q$ d

    4 p6 D! k7 E# f1 U) Dmodes        描述" `; x/ G' I: h4 B- A( g, _
    1        1位像素,黑和白,存成8位的像素
    % a4 C; V0 t8 {5 H9 oL        8位像素,黑白
    8 l0 A2 C4 v! b, u. MP        8位像素,使用调色板映射到任何其他模式
    : b# B) O! _' `1 `* D5 z( PRGB        3× 8位像素,真彩
    * O  A, K4 P3 ^" ARGBA        4×8位像素,真彩+透明通道* \. `- |$ C. q5 }0 J: ^  L8 O
    CMYK        4×8位像素,颜色隔离/ a- m& X2 E+ g  X& ^) h7 `
    YCbCr        3×8位像素,彩色视频格式
    7 k) I+ E  K& b9 q8 O# kI        32位整型像素
    ; a7 O7 D( r5 I# QF        32位浮点型像素6 G) C- O: Q- g/ C
    4.实现效果  B* d+ q9 x" z# f1 l. t( j
    1 d* x9 c/ T8 U$ |: s
    . M0 d& p4 H4 @6 W9 x

    & i# O8 k$ g' J( X. C) A) J; j" u0 M2 O# B6 {" y" @
    可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。
      |" o. J" Q: x  U$ a. i. U————————————————
    # h; b9 {5 |% Y9 b' R版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    4 I( s- @1 ]- i& q. U$ D" w原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288
    ; x/ [0 \2 l/ P/ @" s" ]
    6 a2 q: E0 c+ K$ J) V9 p: G9 P* T* i& D1 q/ z
    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-9 19:56 , Processed in 0.581782 second(s), 51 queries .

    回顶部