QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4193|回复: 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实现人脸捕捉与人脸识别(照片对比)
    ! r( Y2 e3 p; [& u2 y$ D' ?- y, W; r, d! b6 W6 O
    1.安装包依赖
    9 Q( c, L/ D% E4 F1 G  n与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。3 ~8 M7 o% @) A+ |$ v2 e

    7 P6 g$ a. k  n8 o+ P在python 3以上版本tkinter是环境自带的,所以这里不需要安装
    9 _# g8 V* d# D5 ^  Y2 }7 w, V  o) ]* C7 b3 D4 V8 l  Q% Y5 a% l
    2.代码示例" V0 p/ s% v/ X
    import os
    # i+ l& l+ q& P; ?import cv2
    0 S7 B/ ~, R  g1 Mimport numpy as np; }5 a- `8 X. m( |
    import face_recognition; p2 }6 h) o# I& s
    import tkinter as tk  
    : @" q% L& S$ F; k, W3 ]import tkinter.filedialog; {2 ^$ `) Y8 Q( Q9 h, R
    from PIL import Image,ImageTk
    & `1 p) `5 @4 L# o- h0 r1 s6 T
    * u% n' c2 Z: k4 W$ u' @classNames=[]7 M' P' f- s% I7 H
    img_path='Picture'" f5 i' y0 R" Z4 i, Y# N
    img_recognition_path='Recognition'
    8 R& ^1 K! T8 b4 \* PexistsEncodeingList=[]
    2 X# R6 A% m( l7 i9 u3 t+ Q#对人脸集合进行编码进行处理% g8 q; c3 v6 o) \  `/ }" w7 h
    def findEncodeings(images):
    $ y0 n/ E% K5 e) F! p    for img in images:+ k( O& u$ \: l! @* `+ E1 }  x: g# s
            #灰度处理# e3 T# [- S& |! Y/ x4 D8 G
            img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)
    : u+ b: S; \2 Z/ _% J6 m! a        #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果
    " Z/ x3 R" p" O, h  `9 {$ H/ F. l        encode=face_recognition.face_encodings(img)[0]
    0 _8 P, H' a5 f: R        existsEncodeingList.append(encode)
    6 q6 l5 ~- X7 ~8 u) d. f
    - }4 E& r6 O  ?, ^; Z#获取当前存储的人脸编码集合9 u' F2 {0 R( e1 ]/ D* v6 J2 y
    def findExistsEncodeingList(img_path):
    & R* C0 |2 e* }    images=[]# a. b" |8 B9 q* ~7 y" r
        #列出已经上传的所有图片) _4 Z; c: m' e& C' O  Z
        imgList=os.listdir(img_path)0 q; d! V. m* q, y8 t% b. ]; u
        #处理存储的图片得到其人脸编码4 x2 B5 D. T$ ]. q' c
        for pic in imgList:
    , E/ X0 W% ]0 m        img=cv2.imread('{}/{}'.format(img_path,pic))' j; Z1 C/ m0 M0 T
            images.append(img)
    ) Q- E4 s' d- \( B; r; E        classNames.append(os.path.splitext(pic)[0])8 n- X2 ?1 e2 A2 J8 \
        findEncodeings(images)6 ?4 v! w4 y3 M1 V+ j  e  h
    ( V$ M! `6 ]7 y
    #选择并对比图片
    $ n" Z: _. Y8 ]; x5 q/ `def choosepic():
    ( e: A! h: x: g  o0 p    choosepath = tkinter.filedialog.askopenfilename()
    5 y3 a2 a' |. d, p  h* d+ g- \  H    path.set(choosepath)
    * B$ ]) p) D! E& Y' S    img_open = Image.open(entry.get()).resize((530,750))( j' _2 r# j/ T  Y
        img = ImageTk.PhotoImage(img_open)* W) R, S" A' c0 E2 V% O) u$ O
        lableShowImage.config(image=img)1 ^  N+ b4 n; l* Y4 w8 l
        lableShowImage.image = img. f$ W; n6 x1 Y- E
        lableShowImage.place(x=30, y=70, width=530, height=750)
    1 @0 x. O( q$ ^7 J( J. ]    faceRecognition(choosepath)
    0 v1 Y# k+ a& S0 s) K
    " M! R, ~8 R( ~( H. M0 xdef faceRecognition(choosepath):- S$ X; X; d" \& u
        frame=cv2.imread(choosepath)4 j& U- C5 k3 j5 ?( k
        frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
    2 u) @- L/ F% _/ @0 g    #对摄像头读取的检测人脸: `, E* h3 r' Z$ _/ S/ g
        facesLocate=face_recognition.face_locations(frameRGB)5 E4 A5 q, ~' C3 C: k3 B$ M4 w
        #进行特征编码
    8 R2 d  K# u8 L: k7 t( X    faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate): h. t! A3 ?$ y3 ^
            #遍历检测的人脸和库中读取的图片进行对比,计算其相似度3 _  {; \8 g* K
        name='unknow'
    - e- p+ Q0 z. n% p/ f! o    for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):& T" t( J' V  @  H1 T
            #进行匹配, [% c' ~  [( Z6 {( |
            matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)) i- x; U1 W+ }# p3 q
            #计算相似度
    ' V: D. B6 O6 x3 \5 m9 `9 G- _6 T        distance=face_recognition.face_distance(existsEncodeingList,face_encoding)' s8 i. m- @5 d) f6 m- a
            lab='unknow'$ o0 Y5 ~9 E4 d% g
            for index, item in enumerate(distance):; X  t2 V3 ~2 n1 u' @" A
               if item<0.5:1 ^, ]+ b; U* l( B1 e0 o& z$ `, z; v
                    if matchs[index]:+ C& K4 U0 }4 t( _& B1 b& k: `
                        #得到匹配到的图片名称与相似度值6 W9 ~0 o4 w: A
                        lab='name:{}; Similarity:{}'.format(classNames[index],item); M8 i  w4 b) s
                        name=classNames[index]
    0 Y$ C& L- A3 Q, m                    break
    3 v5 q9 f) I- f1 _$ n) O        #初始化面部捕捉框显示绿色; B  |" h, f6 o' B, P1 @
            color1 =(0,255,0)1 B0 T" F  Y$ c9 [7 p9 ]
            if name =='unknow':2 i$ H& z- E9 w' d6 B
                #未能识别的时候显示蓝色
    7 B$ M$ e! w7 n: s4 B7 O            color1 =(255,0,0)- W2 O! h& X" ^- C
            #画面部捕捉框
    % x1 g/ E% ~8 e7 a1 Q3 i        cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)
    8 F& M' ?/ _$ X! w% t        #在捕捉框上添加匹配到的图片信息
    & X. L' j3 u2 d; d: e2 |        cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)
    ( V, Q0 n9 Z5 W( d; q% x        cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)
    * P) P" p$ V" q/ M1 @  ^7 S1 a    img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))
    ) W6 b- b* P% V& D! t6 [* U( b9 |) J    img = ImageTk.PhotoImage(img_Recognition)
    : R3 {0 A5 F3 |; O0 H/ Z' k2 M' _4 _    lableShowImage2.config(image=img)
    2 s$ X( P8 X+ z3 N    lableShowImage2.image = img4 v* [$ L( b! ?4 f- O$ O' S
        lableShowImage2.place(x=630, y=70, width=530, height=750)
    " C8 [! [) z; q. e4 ~6 J6 b. w4 a0 W0 c8 o
    if __name__ == '__main__':; \) v' g6 T7 Z! n2 K2 z0 x2 s+ B
        findExistsEncodeingList(img_path)- j& v3 N- @% w' _8 ~# f, ]1 a
        #生成tk界面 app即主窗口
    ) Z6 x6 J& ?6 Q; d0 x; p    app = tk.Tk()  ( l, K/ m, C8 ?6 B, U
        #修改窗口titile* m" y' i: P4 ~% w0 V! c4 i
        app.title("show pictue")    X9 a# D1 o3 L5 _
        #设置主窗口的大小和位置
    $ R- C& O  x% g1 U  I" c! v    app.geometry("1200x900+200+50")
    % r1 |0 v  n. q! m    #Entry widget which allows displaying simple text.
    ' x: E1 E4 \9 m% k% v+ |    path = tk.StringVar()
    ! }( i* l# Q  a+ E    entry = tk.Entry(app, state='readonly', text=path,width = 100)/ }3 I# h9 P+ X+ i4 p
        entry.pack()
    2 |7 Q: m6 x5 W( @. g3 [; k    #使用Label显示图片
    % F/ E5 x; p$ x4 |    lableShowImage = tk.Label(app)* t# O2 l" `& X( C
        lableShowImage.pack()# ?. \: |. |6 G8 V! i2 P1 E7 q
         #使用Label2显示处理后的图片
    3 ~1 H7 I5 t0 h3 E! c    lableShowImage2 = tk.Label(app)2 J9 @0 G, k2 n9 I' l+ ?  i
        lableShowImage2.pack()
    2 H' |4 I+ W& Z) @% O) X7 }/ e. f' `    #选择图片的按钮) n4 {2 Z+ k5 S9 e
        buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)" K& u. k6 C( l9 V: s2 i
        buttonSelImage.pack()
    ) q: f9 S' \1 s9 m/ J' ~: \. z    app.mainloop()
    / o' T+ s  z$ j6 Q3 X& _* ^5 V  d* {' ~" T) i" _
    3.说明, E- B( @4 D# b% T. h
    首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。+ c* f8 V' T' |, U4 a) [( O2 b

    4 T: t: c" `8 y% G. O) r5 |$ R. |4 F, p+ M

    ; D+ t7 E; L/ v3 }, J) v 其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片1 r( o, Z5 m) s
    9 U$ r: F7 T  U; Y4 g3 `! p

    ( p( i& W, Z4 E/ E3 _3 C$ X4 W" ~& l# x% G
    但是效果会存在色彩的失真,效果如下:
    ; F8 z  }* ~$ E5 y7 W0 n
    9 h7 R/ n; x% c: @" |: H$ x8 |7 y
    - {& ?$ f6 {/ ]9 Y8 n2 v/ V/ k5 l5 ~- i) K( F  A
    也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。
    2 k. E2 v; F9 ^4 z) K8 r( K5 ?& h! f4 H9 {
    这里简单提下PIL的九种不同图片模式:
    " X9 k6 H$ a5 l! T  r) [+ b5 n4 F( u% w; R/ c  E; O
    modes        描述
    2 p  Y$ [, u8 i- Y1        1位像素,黑和白,存成8位的像素4 m- M& V! ?0 p1 P5 V' @
    L        8位像素,黑白) q* M' I5 Q% Y1 n9 _% N
    P        8位像素,使用调色板映射到任何其他模式; `, I9 `" h* w$ s! v% M
    RGB        3× 8位像素,真彩: @2 Y$ V4 v4 y! O
    RGBA        4×8位像素,真彩+透明通道
    4 \, y! T/ F1 w' |: h3 J% vCMYK        4×8位像素,颜色隔离7 F' A% p- {4 z4 C9 T# p# _
    YCbCr        3×8位像素,彩色视频格式, Z3 {" Q3 Z4 X7 \% X. Z* _2 }+ k
    I        32位整型像素
    ! z. x# s5 s2 K! I( r; qF        32位浮点型像素
    * F1 s5 s/ y  r+ I; m4 L; R- b! N4.实现效果9 A, K" @, Q# e: e8 L) O9 }, t

    ! Z# M3 |/ A8 e/ r
    6 ~' v5 q+ _) m' n) o4 a" t9 j& n- H/ X

    3 p) n' a" y* t1 X9 o& c 可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。5 @! ^7 T5 v0 W) w- F/ s' `- }
    ————————————————' ]% b% E6 K( `( I
    版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。9 C+ l9 \) h1 @0 r
    原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288- O2 n3 a" D- u$ p+ _8 ~  H
    + r, Y8 @' |  z& H

    4 R6 E) m" ?% Y$ h, v3 f# H
    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-11 11:51 , Processed in 0.360884 second(s), 51 queries .

    回顶部