QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3692|回复: 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实现人脸捕捉与人脸识别(照片对比)
    # L/ `# i6 S& a: ~" ]- V
    7 G2 P* G! t* D: i1.安装包依赖
    ! H+ k0 H) ~" I( K$ o& z0 W与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。5 `4 v- V! o  t; q( L( i
    8 U. ]% S2 n" Z
    在python 3以上版本tkinter是环境自带的,所以这里不需要安装
    1 Y7 v) e) R* g3 v* Z3 W
    ( F: a% Z- ~5 T2.代码示例
    2 E+ m9 B0 ?% X: O( L: w% Iimport os- [1 v. x3 D: n
    import cv2' ~& L; [3 w3 \
    import numpy as np
    " ]" r& w- z- c3 |# o, ~0 Timport face_recognition/ D6 ?1 x, x* H3 |  o, w( z
    import tkinter as tk  
    . O" c" C& T! o4 bimport tkinter.filedialog8 P% b* A! k( m
    from PIL import Image,ImageTk
    3 }& j, ]2 C6 \$ [5 ~6 S1 w8 _9 I4 p8 r1 u$ e6 q: T
    classNames=[]
    % q/ w1 r. |/ @% @( u& |img_path='Picture'6 F! M2 p0 f, ]
    img_recognition_path='Recognition'
    0 P0 K% z- N) [7 q1 v7 UexistsEncodeingList=[]0 i: r3 j6 s# d6 F% U! ?6 E
    #对人脸集合进行编码进行处理
    2 X2 k0 A& b* j2 t, H/ B, |2 m0 pdef findEncodeings(images):5 r# f% F( j, |9 B
        for img in images:
    1 u6 n" `0 s* B) C* z2 S- X. l        #灰度处理
    0 o, N9 J1 K, b+ s: D, M( D* ~        img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)
    6 Z  D4 u/ u, Y& Q        #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果
    5 q6 N' A& `+ \, S6 y, P" c2 s        encode=face_recognition.face_encodings(img)[0]
    ( ]) U5 [4 ~' J2 x; C* H. X        existsEncodeingList.append(encode)
    3 T4 Q- r& o2 K( X% W: O4 _4 X/ Y: L8 k
    0 X" |/ f; r$ s! R#获取当前存储的人脸编码集合
    * R( i( B4 @1 ]5 G' bdef findExistsEncodeingList(img_path):
    / N- ]* t1 ?( L+ Q. t( [: W/ D    images=[]. k! m! p( G* C2 H0 b% }
        #列出已经上传的所有图片
    * D5 M0 j; O. x9 R$ Q    imgList=os.listdir(img_path)
    & h8 X9 D$ Z/ [, F& r9 Z/ W    #处理存储的图片得到其人脸编码
    % @& J9 E( d  e% k' l- {% ~, m    for pic in imgList:
    6 g' X4 [3 T! N1 W        img=cv2.imread('{}/{}'.format(img_path,pic))
    ( E* O2 R; w. L        images.append(img), \, U7 J! T; `3 \! X$ j
            classNames.append(os.path.splitext(pic)[0])
    - w1 F' I: a6 G9 c# L    findEncodeings(images). M* ]1 J) H  I4 V$ q

    5 m) t; `/ @) i#选择并对比图片
    4 A* a4 ^/ T( @def choosepic():& Z( P1 F* U3 B
        choosepath = tkinter.filedialog.askopenfilename()' I# {6 G3 p7 w. ^- L4 Y0 o9 _% X
        path.set(choosepath)
    # ~& K' \8 f9 P    img_open = Image.open(entry.get()).resize((530,750))0 y3 e7 K  q. `( O
        img = ImageTk.PhotoImage(img_open)
    # C0 O# l, Y3 G+ A6 s4 z* W    lableShowImage.config(image=img)
    " a! L! [3 Y6 B+ {4 s  h: A    lableShowImage.image = img& x  V% Y$ J" m, ^* U
        lableShowImage.place(x=30, y=70, width=530, height=750)
    # k$ V- V$ Y. p. k* V" [, a    faceRecognition(choosepath)
    ( m* m6 d3 f6 K) _
    $ i" o/ q9 v1 N1 q2 Sdef faceRecognition(choosepath):1 ]! l6 D8 C+ Z4 t! v
        frame=cv2.imread(choosepath)
    + B6 x1 d" p: I+ _    frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)' b+ p0 Q1 M# @' l
        #对摄像头读取的检测人脸
    % z4 `: A2 _* Z' x$ ?    facesLocate=face_recognition.face_locations(frameRGB)
    7 a4 N1 U% r! N* A    #进行特征编码
    * `* a4 Y# V/ ^2 s  s& Y; u% C8 |6 }    faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)
    % S5 n- C, c7 k- |7 z' |        #遍历检测的人脸和库中读取的图片进行对比,计算其相似度4 {2 r' w9 r  D( Z- {( N9 V
        name='unknow'3 n) ^! K2 E  P8 G
        for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):8 |$ f% P" x6 ?* r7 u2 e
            #进行匹配! ]) V( w  t& |! \: {- I7 d# o
            matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)) \) N9 j% [3 A) J( H
            #计算相似度" F6 |* E; k, o- J% @4 p
            distance=face_recognition.face_distance(existsEncodeingList,face_encoding)- o/ \; j* T& x7 O, ]$ o
            lab='unknow'' Z, u4 L9 j9 U$ b5 }2 v' ?: a* h
            for index, item in enumerate(distance):* M5 i$ ]* b- s7 ?" k- b  K
               if item<0.5:
    ' w' c3 m' {; ~                if matchs[index]:
    % \. z9 }! t$ {4 n                    #得到匹配到的图片名称与相似度值: y( T" s6 j5 l" b8 D( P! Y0 m
                        lab='name:{}; Similarity:{}'.format(classNames[index],item)
    / Q$ R/ F8 h/ g2 j                    name=classNames[index]  \  ^4 {* a. U) @! E* |1 J+ G) x
                        break. I# ~3 i, b' ~* @3 d# \$ R
            #初始化面部捕捉框显示绿色2 R$ R$ h$ `& g' W: G
            color1 =(0,255,0)
    ! W2 ^: N8 N& t6 f        if name =='unknow':2 w% Z5 R  n6 c# q
                #未能识别的时候显示蓝色/ w8 }3 f" X; i4 |3 ^1 R, i2 J( u3 ~
                color1 =(255,0,0)
    + G! T/ ]$ v6 q( \6 G        #画面部捕捉框
    # k: l/ _. u: W& \7 O  `7 [        cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)# e0 M5 Z5 ?  S8 A2 U; h
            #在捕捉框上添加匹配到的图片信息
    6 M4 z. N0 M% M+ ?  j- |        cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)
    # L! E" @2 a/ h. e8 O) P# U: h        cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)
    8 y9 x4 N4 D& S2 Z: {3 t4 q. y, i    img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))! i" @+ U2 e, q
        img = ImageTk.PhotoImage(img_Recognition)
    : j3 b2 a0 R7 F5 m+ }+ C2 f* X    lableShowImage2.config(image=img)8 D7 x" w0 D' A# T! G* i; d: m* s
        lableShowImage2.image = img7 m" R* x  W1 v% M4 C$ p7 E
        lableShowImage2.place(x=630, y=70, width=530, height=750)# f1 p( C# l" L0 I8 h
    ; N2 f; x' w* o! ]) W: O, m
    if __name__ == '__main__':
    2 R8 V! U2 j% U2 v2 p    findExistsEncodeingList(img_path)8 k0 N% p- `3 D' h) J
        #生成tk界面 app即主窗口: g% f0 ]' D% v# i/ e7 D2 U$ {
        app = tk.Tk()  " F0 D7 X9 V. o; v6 _% `
        #修改窗口titile
    . u7 V6 N8 \3 p6 l. n    app.title("show pictue")  $ z! S, h+ y- N4 G3 T7 ?
        #设置主窗口的大小和位置
    . x- `+ g& ]$ T/ u- }& ]% m    app.geometry("1200x900+200+50"), W" g+ ^9 W. U4 u* t, K5 R2 D; T; o
        #Entry widget which allows displaying simple text.' u! [$ o, P% \) L+ X( \
        path = tk.StringVar()
    4 t) U0 F* k, |    entry = tk.Entry(app, state='readonly', text=path,width = 100)
    7 b: ]9 B0 ]! B- `# _: N  }! m    entry.pack()
    ! `3 B# h. I9 \3 d/ G; Y  h' q# T$ p6 @9 ?    #使用Label显示图片# `5 j0 b2 g3 E/ ?5 f
        lableShowImage = tk.Label(app)
    4 N' W8 O) S+ c) m4 U( }    lableShowImage.pack(); J7 H2 m( l2 t) X- z6 T) L! W( W  h
         #使用Label2显示处理后的图片
    & @' n5 n: \/ @    lableShowImage2 = tk.Label(app)
    ' ], h6 e! K' g% p    lableShowImage2.pack()7 {/ W  a- O9 ?& g; N1 W6 O' N% N
        #选择图片的按钮
    9 D; O4 b5 M# T+ E& D7 ^- U  `    buttonSelImage = tk.Button(app, text='choose picture', command=choosepic), ^8 k* w" Z6 i- U* h) N3 k( J5 i
        buttonSelImage.pack()) D; \4 ?. A8 W. Z8 y
        app.mainloop()
    : G4 z/ [# C# B
    ' h9 w8 ~5 A; ]/ Z$ P$ l3.说明7 K# J+ h# s9 Y. W. x- D; s
    首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。  K" b) K  K4 H/ }; a7 h5 ~
    ; S- b$ B# H, F! l' i% b
    4 M3 m8 J8 |  b& y2 {. z
    / F/ x# G+ F/ o. ]) E
    其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片- [+ G. B9 D  g' l0 k& y
    ( ?; v/ m, b! x0 T
    6 y; [* J3 E9 v/ {, @6 z. {
    # e: F: B! }% q0 U
    但是效果会存在色彩的失真,效果如下:# ~7 ?; @! i9 }% @9 {" R+ \
    " }7 F1 p4 R* j+ u: c  J
    & s" j3 {5 N/ \8 B1 z( T, d
    . ~: M; f+ R9 h6 V: ?1 S
    也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。  g% l9 q) o& _& \+ r6 M

    * q# v1 @' }% o8 b1 r# p这里简单提下PIL的九种不同图片模式:
    9 n9 C7 c) h2 K# f3 G. L& |
    # o+ t/ S6 d& Z7 A0 Z% |7 lmodes        描述
    2 Q7 e! F4 `% S% P1 i  D7 G1        1位像素,黑和白,存成8位的像素
    + w3 y+ x4 n8 ~" s' ?$ }L        8位像素,黑白
    . ]/ s- T( C! \3 u  P, ZP        8位像素,使用调色板映射到任何其他模式
    * G7 U+ c8 e1 x5 I4 d" v0 U+ g4 p0 `* V. @RGB        3× 8位像素,真彩+ G$ W$ N) M% d3 P4 @8 l. J1 B
    RGBA        4×8位像素,真彩+透明通道! _. s& ~- C* X4 {1 q# E6 B
    CMYK        4×8位像素,颜色隔离
    3 J$ Y5 K- ]; M5 N5 ^YCbCr        3×8位像素,彩色视频格式
    / t4 Q; A0 M& ]; |# q' nI        32位整型像素7 @! C3 R. m0 s/ ~" O: g, x
    F        32位浮点型像素0 J: H7 i  `, {0 F8 L
    4.实现效果
    $ U8 ]) S& {4 W. X- y
    9 z, a; V. E. Z! p9 p' G" B, Z8 B1 V; v
    + v$ y$ M. b6 x% s' N
    * n1 K' y+ Q6 E# a  h
    可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。. P. C) a1 J( n/ s, W+ h9 x" \
    ————————————————
    % Q) |) @1 p/ _. j) m3 p0 U' X1 c( K版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    5 {& X3 ~, I0 N% @( w" p原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288  e+ r7 G/ Q1 `: K% d

    % k* u  q, ^; D- w  d( ~8 F; F  [, ~  c9 g2 ]5 m( u. {
    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, 2025-11-8 04:07 , Processed in 1.227669 second(s), 51 queries .

    回顶部