QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4205|回复: 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实现人脸捕捉与人脸识别(照片对比)5 h7 ?6 j& @4 w9 E) e
    " e2 t. M9 Y" V( ~3 B/ V
    1.安装包依赖
    4 O  D' A* n; _. g# O  }. {" b与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。. m+ m" @0 k- l, g
    , v0 Y3 n7 ^# w% k% y' [( b
    在python 3以上版本tkinter是环境自带的,所以这里不需要安装! Y# H3 n0 T9 \8 I  I

    : F9 z% y8 S- m9 |+ L2.代码示例- C2 ]) i, i# |( F/ ]5 P5 L
    import os
    4 y5 c% ?- G9 rimport cv2
    . f' m+ c- J. eimport numpy as np) o" q4 Z/ b, y  S; k7 |, D
    import face_recognition% M; U4 S5 P2 i2 z% L# S1 p; q
    import tkinter as tk    k0 O1 k# k; F+ T
    import tkinter.filedialog
    # W/ b  ^: U8 \8 V$ Q8 Jfrom PIL import Image,ImageTk 6 C: T% c$ H$ `/ d5 l. e2 t" ]
    & f/ F  p1 J7 v9 z# C; r0 W
    classNames=[]
    . W% R! }: M$ v1 J1 |4 `1 U" zimg_path='Picture'
    - ]6 q/ @0 U* U) y$ _img_recognition_path='Recognition'
    0 P- ^% X8 _7 w+ |4 D- SexistsEncodeingList=[]  f% |6 v. {: V2 f
    #对人脸集合进行编码进行处理' u4 c* Z0 L' L# g% z9 W6 W, y
    def findEncodeings(images):
    - L/ T3 @* L/ k: ^    for img in images:- X% Z8 u& w: ]8 e  {
            #灰度处理! |/ h2 I0 _, S$ N+ r
            img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)+ G! l5 d$ v' x- e* ?' k; k, A
            #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果
    6 w, u; r+ R, N8 T# m& P0 t        encode=face_recognition.face_encodings(img)[0]% _" ^, ]! M% \8 q/ O! u2 J
            existsEncodeingList.append(encode)3 ~3 {4 b" \# j4 {1 R; s

    $ u% F# N+ [# `: c#获取当前存储的人脸编码集合, Y2 ^8 }9 T0 ]! k, i, B
    def findExistsEncodeingList(img_path):3 D6 f: l8 e; u8 ^
        images=[]
    2 o9 N) g' @0 R$ s# H5 n% F6 ~( P    #列出已经上传的所有图片% D1 m, [4 c1 ?: V2 d' R
        imgList=os.listdir(img_path)2 R) z2 g6 J6 O& [( r* ^/ |
        #处理存储的图片得到其人脸编码% o, g5 }& _' _4 }( O
        for pic in imgList:" Q5 Q* G7 q5 h7 c8 h* s
            img=cv2.imread('{}/{}'.format(img_path,pic))* F* b# O7 Q% X2 G
            images.append(img)7 P# h6 d+ G0 u( J
            classNames.append(os.path.splitext(pic)[0])4 e4 y3 |/ {: r# T/ o7 R
        findEncodeings(images)$ h5 ~1 ~* e& W: G( X& B8 }3 a

      w) G0 q1 @$ b, G+ o9 O5 ~# Q+ n$ J#选择并对比图片
    + x* l0 _5 ?2 P; j( ^def choosepic():
    # s. n" h$ b  F7 [- \    choosepath = tkinter.filedialog.askopenfilename()) F. p; t: g, w6 A
        path.set(choosepath)# r- v8 U. O7 f! m
        img_open = Image.open(entry.get()).resize((530,750))! G7 D) ]" v' Y, m* m
        img = ImageTk.PhotoImage(img_open)
    : c) m, `' h1 n" |    lableShowImage.config(image=img)3 S2 N6 U; Y$ C/ y; `6 \
        lableShowImage.image = img
    ' z6 b# L7 u- S3 [    lableShowImage.place(x=30, y=70, width=530, height=750)# S# [- S2 i. `
        faceRecognition(choosepath)
    " \, @5 \1 H- I& E# p7 L- j/ x( A
    % X" C" q6 j. r  Z- E9 ~- Wdef faceRecognition(choosepath):2 G! [) I6 V; F
        frame=cv2.imread(choosepath)% t5 Q: i. c" b: V5 ?; T3 B
        frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)% h! o& ]: N, r4 C; A5 z5 d
        #对摄像头读取的检测人脸
    3 M8 e2 T  g; Y- f% j2 i    facesLocate=face_recognition.face_locations(frameRGB)0 A8 M% s& j! R! J6 d. y6 W
        #进行特征编码/ J* z& B& f* ]
        faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)
    2 Y; s1 H  b! u) e# {, u( y        #遍历检测的人脸和库中读取的图片进行对比,计算其相似度5 U% Z( o0 ~1 ]; e( q" h9 I3 @! ?2 u# E
        name='unknow'
    2 ~6 {. m9 Q" Q    for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):  B- m5 U) `' E% w
            #进行匹配
    . R- h( H7 `3 s$ |- T# C        matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)
    . I+ u9 p. E7 y% H# `+ }" Q        #计算相似度
    1 O, ~4 L" p4 @/ w        distance=face_recognition.face_distance(existsEncodeingList,face_encoding)
    7 }' p/ [1 l0 `) Y% {5 \4 d        lab='unknow'- q- R% _: v- x2 x6 g, U$ a1 X
            for index, item in enumerate(distance):) T$ ]5 F' |/ ?$ h" [3 W! [2 k2 }
               if item<0.5:2 g) d$ K# j5 A& c
                    if matchs[index]:
    0 z* E- R0 k! }" V. z                    #得到匹配到的图片名称与相似度值1 D/ u4 N7 N$ |$ O
                        lab='name:{}; Similarity:{}'.format(classNames[index],item)
    / s3 h$ j' Y' n$ ^" d+ f                    name=classNames[index]- K, c2 D0 I  I" i$ F
                        break
    ; c" W, |, K+ G3 @- A        #初始化面部捕捉框显示绿色7 X$ ]% E$ ~9 l5 J' `  ~! y
            color1 =(0,255,0)
    1 b, Y% _# j( p5 ^, H5 {* ]        if name =='unknow':! R; _2 e2 @% z( P' c
                #未能识别的时候显示蓝色
    2 D2 m0 @2 w3 [, {4 n            color1 =(255,0,0)3 p4 e6 x# h" }4 J+ N) W
            #画面部捕捉框
    ; G6 z5 a! M% ?* b        cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3). G8 C& g7 x0 u6 C; o/ @0 Y5 J8 z
            #在捕捉框上添加匹配到的图片信息
    % ?8 x- Y; T2 b/ r: w! e& \        cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)2 x$ m) b. b: `3 D3 \9 C9 y
            cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)
    " j6 ]+ X. U( e% b    img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))
    4 d. k0 B0 {# k/ `1 |; C9 {. {    img = ImageTk.PhotoImage(img_Recognition)' {' V* v6 `; r% T6 d8 F7 n
        lableShowImage2.config(image=img)1 r* ?* T+ }! d  ]  K9 j5 e  E
        lableShowImage2.image = img
    ! z, |7 S# L- ?5 {/ e    lableShowImage2.place(x=630, y=70, width=530, height=750)# k. y7 M5 }& x, }* }
    / Y* d" P2 j. ~! ?* c
    if __name__ == '__main__':1 |4 A' x3 |7 S5 B8 x: s
        findExistsEncodeingList(img_path)8 c7 R: H  M% D8 R- f$ ^
        #生成tk界面 app即主窗口/ I6 A6 D4 ~! }* |
        app = tk.Tk()  : H+ g! K5 M1 a: E2 J( s
        #修改窗口titile
    ; ^) n9 `2 m; G9 F) t    app.title("show pictue")  - g+ `: B5 [5 f. `
        #设置主窗口的大小和位置0 B+ M& Y* k* ~2 q; c1 h$ r
        app.geometry("1200x900+200+50")
    ) g6 m: z7 o$ n* x0 {& U    #Entry widget which allows displaying simple text.
    + [! c( z( ^) Q    path = tk.StringVar()9 F: P1 b% F3 G" ^9 N8 h
        entry = tk.Entry(app, state='readonly', text=path,width = 100)
    ; K4 l4 K! X  B% l8 I& k    entry.pack()
    : B$ I* {1 @, z& Y  z. O2 C2 @    #使用Label显示图片
    + _& d& Q( j  v" _( K    lableShowImage = tk.Label(app)
    2 U& G5 Q( E) C    lableShowImage.pack()4 m  ?+ r$ w; k  K. q; k
         #使用Label2显示处理后的图片& ~) C' I! d; o
        lableShowImage2 = tk.Label(app)" x9 a5 ~9 L- i+ F
        lableShowImage2.pack()7 q- V, `0 c- V( x( R4 M: g, ~
        #选择图片的按钮1 r) E! _. }% Z' h& R
        buttonSelImage = tk.Button(app, text='choose picture', command=choosepic), K/ |/ `! Z1 n
        buttonSelImage.pack()  p5 g1 y$ r7 j- b
        app.mainloop()
    2 m1 n2 J* w5 Z) \- s; E  v: T" |* Y; s) _6 `
    3.说明  Y" q7 A& l0 S2 M3 c
    首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。
      A" D( I& d& t! h' R2 O4 c! w& h3 j  b$ N$ T) A& m% ~
    ' @- |5 u* v8 {- _$ x& S; E$ c

    % T' h8 ~& G, S4 R" G  S& ~ 其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片$ g" }3 l( B. s+ G  v" ?  @+ \% A: Y

    $ n* A% M* w# h  ^+ }7 p1 z- s9 p1 Y& p& v  O+ y4 I# b

    ' v( E- `1 S: v+ D9 n% X 但是效果会存在色彩的失真,效果如下:2 j5 b5 ?% U% `
    # g) j3 q' S$ B) |

    & u! o- }/ E1 O2 ~0 ^( B5 Q4 O
    # C2 \2 O! v  [: z也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。
    & b) w/ _" E( p, m3 i5 q. t' p2 @$ c$ u# ?) n1 {$ T
    这里简单提下PIL的九种不同图片模式:
    / O) N9 |# }1 j% c) \9 I* [" {4 m1 `. J# }# d
    modes        描述/ J5 D3 v9 Z7 ]; G* z* {/ M
    1        1位像素,黑和白,存成8位的像素
    6 ]. h0 R, Y/ h) wL        8位像素,黑白
    0 @# {' J0 y- u- e- `$ l( ^7 BP        8位像素,使用调色板映射到任何其他模式
    + O/ n" K" R  _: |RGB        3× 8位像素,真彩
    ' J* }' b& l) J4 v. z5 }RGBA        4×8位像素,真彩+透明通道% T$ t# I7 ?$ B! {# H$ X
    CMYK        4×8位像素,颜色隔离+ _+ }' h7 v) Q3 U
    YCbCr        3×8位像素,彩色视频格式7 O/ m( \5 h2 h- f
    I        32位整型像素
    / z& S# o0 _+ T9 e, v# f/ f% X: A) A9 fF        32位浮点型像素4 I7 m4 M) N$ U
    4.实现效果1 Q& N- h: W" C. A. [- \% X

    - l* b3 \) O+ U7 M5 \4 w5 k; h. z& ?

    3 J  v! d; g) ^4 N! W2 S* ~: I* y& S) V) _: R9 K4 m
    可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。. p3 Q- N8 n" a( H
    ————————————————
    6 a% o* ?. X& G: d  |" a  Q& Y版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。6 X, {3 V4 A/ V
    原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288( E+ v, S. {4 Y0 P$ [) e0 e

    3 f% I* h( ^' @) f
    $ W* U3 i$ O  C1 ^' |
    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-8-24 03:40 , Processed in 0.455951 second(s), 51 queries .

    回顶部