QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4278|回复: 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实现人脸捕捉与人脸识别(照片对比)
    . K1 E. n/ m( {; h  D/ P# q7 C5 G5 C; @
    1.安装包依赖
      V- i, C) G, z3 S与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。! {4 u5 _$ |: \# \2 h# G6 C
    - H1 \) v  K) x, D6 k5 X) Y$ ]
    在python 3以上版本tkinter是环境自带的,所以这里不需要安装; }* g3 k& ^0 J/ C9 t
    2 K% V' r" C: u' e4 N+ D
    2.代码示例) |# t2 j8 J5 s7 c% E6 N: G; z! K6 o. p
    import os
    . d& i8 J& C& M  {3 o# M$ Nimport cv2
    2 F5 t5 i/ p# s' a0 b2 ?8 Zimport numpy as np9 P# y  w& x8 T# S& A
    import face_recognition
    - D1 H: g3 V$ ~1 |8 H& ]+ i5 ]import tkinter as tk  
    7 M" u4 R3 Z& j# o# T1 yimport tkinter.filedialog; U$ o, t; m4 z$ W  r7 o- I
    from PIL import Image,ImageTk ) o7 |+ i! W/ H. P% c8 v

    $ U. C" ?9 L/ k1 G, ~classNames=[]
    1 m' R0 t* `& q1 l) f$ V, cimg_path='Picture'
    # G4 K3 L" H1 w8 E8 J% cimg_recognition_path='Recognition'# k1 a. J' s) E" |( J* I3 T- H
    existsEncodeingList=[]
    % E6 Q! h  P" x! ]9 A$ q, Q- h' l#对人脸集合进行编码进行处理
      ]3 J7 Q/ k$ x# n8 Z6 ]% s% I  gdef findEncodeings(images):
    9 D9 h4 x/ R, U    for img in images:6 m! S& V" s1 i* t. i
            #灰度处理4 R5 l& R, b0 p
            img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)
    8 |4 P3 L/ P) g* d        #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果
    8 r  Y( T) H. R$ R5 t        encode=face_recognition.face_encodings(img)[0]
    ) c# A  f7 {9 a3 y        existsEncodeingList.append(encode)3 q3 e- W8 ?1 N  B# b" }

    * e; H) _3 l: ]#获取当前存储的人脸编码集合" M3 ]5 t* z" m" c0 W3 W0 l! K
    def findExistsEncodeingList(img_path):
    % k! f2 q1 x0 O6 s% O+ K8 a    images=[]
    & W) r: V8 x+ e" G. m0 e    #列出已经上传的所有图片4 E/ G& a; ~) @% f4 {3 I. l- ^; I
        imgList=os.listdir(img_path)
    " q. j7 w$ U4 N1 `* I7 O- {/ A1 F    #处理存储的图片得到其人脸编码
    % g6 ]+ U' Z1 q  L6 Q9 T    for pic in imgList:
    ( T, V5 M, a9 b1 I/ Z6 g4 }- J9 g        img=cv2.imread('{}/{}'.format(img_path,pic))  U1 i% E$ p" l" U5 D0 G( ~
            images.append(img)& l% u- [/ i& ~  A3 ^/ x
            classNames.append(os.path.splitext(pic)[0])
    3 k6 [% H( O3 J: U6 D( N% d    findEncodeings(images)4 s2 |- [6 H* Y5 \$ N; N& u' }

    5 D, Y' o; k2 m/ H' y! S! {#选择并对比图片. n& S/ y5 R5 S8 w5 j" L
    def choosepic():
    2 Y1 m5 u' T4 C4 B  O, U    choosepath = tkinter.filedialog.askopenfilename()
    9 x- n8 B4 l, l% V% U8 \8 J- ^+ q    path.set(choosepath)9 W3 H" B1 p! D: q% y
        img_open = Image.open(entry.get()).resize((530,750)). m2 ?& e/ r9 L, A2 @
        img = ImageTk.PhotoImage(img_open)/ a; U2 e/ p% T, U9 X4 I
        lableShowImage.config(image=img)
    1 Z. B) ], L8 y    lableShowImage.image = img
    ) N9 a% _( m1 s0 ?5 n! E    lableShowImage.place(x=30, y=70, width=530, height=750)5 _/ ^! c1 o. q! I0 w' V( e
        faceRecognition(choosepath)
    & ~$ b+ u" }" L3 ], c% ?
    $ K( ?: J( c2 q+ H( ^def faceRecognition(choosepath):
    ! |$ W/ T6 y! L5 g    frame=cv2.imread(choosepath)
    1 Y3 @6 Y$ K2 b( c$ A5 }: f3 a( D    frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
    - l9 O5 _. Z4 Z/ q    #对摄像头读取的检测人脸9 S5 j# K, _- m! T4 }% q9 n
        facesLocate=face_recognition.face_locations(frameRGB)
    ) A: \1 U6 a. _+ @$ ~. a    #进行特征编码
    8 R$ e3 e$ n+ K# Q2 ^    faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)2 X1 h7 m$ ~' o* d
            #遍历检测的人脸和库中读取的图片进行对比,计算其相似度: x# ^1 F; ]1 O+ t- q" a
        name='unknow'
    : v! R- A4 t- L7 Y% x    for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):
    6 a, O+ k  N/ l7 c+ y" ]" N        #进行匹配- u: {8 J( o7 o" a( x) g
            matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)2 Z( Q+ B& G5 R! E' {' f
            #计算相似度
    ( D# g- U* k5 g6 B: x7 W) _        distance=face_recognition.face_distance(existsEncodeingList,face_encoding)# _; \; s) H% m3 }
            lab='unknow'
    7 ]1 L1 w! }7 K% A        for index, item in enumerate(distance):3 x4 o9 ]# g" [+ t& p
               if item<0.5:
    6 i" y2 {. l- ~( \, @                if matchs[index]:
    * U& T" ^/ u; A$ d# Q- T! K2 C! T                    #得到匹配到的图片名称与相似度值8 f7 G- q+ p: U0 f! r( k
                        lab='name:{}; Similarity:{}'.format(classNames[index],item)
    3 v4 T& ~3 b+ ?' ?( s: H0 |                    name=classNames[index]
    7 i9 D. E7 r- f+ J) C7 Z# x                    break# z9 O+ W1 s9 j" o: ~0 }
            #初始化面部捕捉框显示绿色
    % t  T9 a7 a$ U% S# I0 i6 k        color1 =(0,255,0)
    0 Y  s! {& h+ ~; {& i# [7 N        if name =='unknow':/ F$ u( J% I- L) }3 c0 H* W
                #未能识别的时候显示蓝色
    . K% B+ r/ G8 l6 C: u  K/ D+ G: M            color1 =(255,0,0)
    ) W7 z% y2 q' f2 j6 B$ V  x        #画面部捕捉框
    + G/ N7 Z6 J+ u% R" ~$ p' ^        cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)
    % \  T5 L7 ^7 S        #在捕捉框上添加匹配到的图片信息
    $ }+ s5 I2 b  ?9 ~        cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)
    . R5 v5 M- [+ e8 h# r4 u        cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)" j! d4 L; i; n/ y' l
        img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750)); W( O. w  [3 r: d: T  E# J% d& t
        img = ImageTk.PhotoImage(img_Recognition)
    9 B, Y" f3 F4 |' m( W% [    lableShowImage2.config(image=img)
    ( ?: \+ p' P" e( p3 y. h9 U    lableShowImage2.image = img
    6 u( m/ `$ V& d    lableShowImage2.place(x=630, y=70, width=530, height=750)
    1 t, ^- ?! a6 B- l2 q4 m
    4 j( U3 d1 \$ x/ o7 Mif __name__ == '__main__':0 E7 ?# a  b& ^% b/ X$ w' G9 D* Y
        findExistsEncodeingList(img_path)
    $ @& e" Z, L; i, G. f4 a3 {    #生成tk界面 app即主窗口
    % x9 x% s4 V7 P- J, U    app = tk.Tk()  ' G' V, ]7 R" a) v
        #修改窗口titile: b. O6 V; g3 r
        app.title("show pictue")  5 u/ T+ v5 Y. Y( D
        #设置主窗口的大小和位置7 t6 G. H8 P7 B, _6 P6 E
        app.geometry("1200x900+200+50")
    , h6 T$ k+ r8 U: S  O    #Entry widget which allows displaying simple text.0 l& U1 `- j9 v+ M8 v. R
        path = tk.StringVar()
    ! e* @# ~! U7 G3 R: t2 W0 s( R    entry = tk.Entry(app, state='readonly', text=path,width = 100)3 L% ]& l* f/ O2 ~  e
        entry.pack()* ^5 \+ C0 P3 G  t$ X1 k1 Y( A
        #使用Label显示图片
    . B& P# U4 \6 q! S    lableShowImage = tk.Label(app)# `+ q9 v" ^4 r, L, g* `- S
        lableShowImage.pack()  [" z- J$ Z. B; L! @  t
         #使用Label2显示处理后的图片
    , w9 _5 N6 \& m/ U' N* B/ f  H" s    lableShowImage2 = tk.Label(app)
    : W+ D6 i  U" E. g    lableShowImage2.pack()
    1 a- r6 s2 V5 J7 k/ g    #选择图片的按钮' O; E  }' V- x: _
        buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)- X# F1 e/ x( I9 S0 g# K) P/ y
        buttonSelImage.pack(). d$ V% Q" @1 w/ n; Y/ K
        app.mainloop()" |8 L/ r; Q5 |" Q" @! ^& H4 X, _
    6 G7 W! c: e) }% o+ A/ m
    3.说明/ i5 o. L- t5 G9 _$ D
    首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。; N- d% T/ r: y) x: c$ @
    / I% _9 X' e4 ?) h/ q5 L+ z  |

    # l% S- r( K! U* w, E8 P: z) @. ]( T4 `/ L; D
    其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片
    7 Y3 Q8 Q* r$ z: {: {7 D) X1 i$ O* q; @. u
    % ~1 [% T9 E" c5 {! c$ J  f) `. o' A. G
    ) r' H. {; }+ D7 F2 O
    但是效果会存在色彩的失真,效果如下:1 h$ q. |6 J/ a2 L. q* B8 D6 p
    ' Z9 r$ F! a) |9 e9 i8 l+ W0 b5 h
    1 _7 \  L; M' s/ \
    / @7 O8 R8 c% h, [5 R- c
    也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。
      P9 C+ C1 S2 t/ i* I0 ?$ p( F. A  \  s3 ?% r
    这里简单提下PIL的九种不同图片模式:
    0 g! [9 \. S' J3 e! W7 p1 T7 d
    - _( v4 P6 j: ^- E2 [modes        描述
    / @- U( {+ q7 z; I1        1位像素,黑和白,存成8位的像素
    ( i; @: b& N5 Y3 t! sL        8位像素,黑白# p4 e* k0 M8 q7 s% M
    P        8位像素,使用调色板映射到任何其他模式
    0 R( ~4 R+ U. [7 zRGB        3× 8位像素,真彩
    6 t- v+ ?, h2 ~7 |$ cRGBA        4×8位像素,真彩+透明通道
    / q8 x; `+ f$ J6 }CMYK        4×8位像素,颜色隔离& J. d  ?4 h" I. R( g0 e# ~) p# \: }4 y
    YCbCr        3×8位像素,彩色视频格式
    ) I  ^3 C0 N8 ^5 m1 w9 S) Z. eI        32位整型像素  h1 M( t- R- h7 h& D' w
    F        32位浮点型像素
    # w! h+ ~" Z( v4.实现效果
    ' S5 h. s. c! n! U! o( R5 A6 M; O/ y% ^  ~

    + U4 u  f5 l8 ]  F9 p
    ' E- E- X% |. S+ Y7 [  o7 O
    / t3 C; |/ g0 V! c) J) J/ p) G 可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。
    6 |  Z! m5 N; r# u————————————————
    : B. J5 u% Y, L7 I: J+ k' @+ c版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    3 V) n9 G- _5 Y* b8 B) N/ i原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288+ c( C. [3 |* ]1 H
    ( r" f/ `8 S+ n5 t: q' F* U

    & {/ a/ O, W8 u$ d  b
    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 07:08 , Processed in 0.658361 second(s), 51 queries .

    回顶部