QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4058|回复: 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实现人脸捕捉与人脸识别(照片对比)
    4 U* V+ K3 k2 m8 V) }! z( U8 }& w6 t/ V5 a$ g
    1.安装包依赖
    ) x' U) b/ `5 f" H! e/ y1 ?与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。% ~1 D1 e, t0 Y+ F5 {! Y" l5 ~

    " l9 V+ b) @$ Z2 d* }& d* d在python 3以上版本tkinter是环境自带的,所以这里不需要安装
    1 ]9 w3 K  ^$ J
    9 n/ |( K' e* Q2 R+ s" u9 y2.代码示例
    $ d( a6 P0 J0 O% Y! n2 rimport os$ M3 \' n- x. z
    import cv2: ]$ m* ^- _5 L3 G" z8 b
    import numpy as np
    : u1 C4 @/ M3 P  A9 zimport face_recognition9 I0 c. b( W# T. F0 o% F9 G! L" ~
    import tkinter as tk  
    : [+ E2 o/ i9 A( k( G% Pimport tkinter.filedialog
    0 e1 Z1 v4 R9 r2 Vfrom PIL import Image,ImageTk , h0 g# M2 {1 a& z5 o9 G; S

    % K" V: \# p( D. tclassNames=[]
    5 W' z4 U' r: k* y7 v) Q9 Gimg_path='Picture'! a- ~8 U/ `5 `3 I. y8 b& l- ]
    img_recognition_path='Recognition'
      W) Y( J' t4 e# ?: c1 [/ \% b- rexistsEncodeingList=[]
    , [) V5 b; U( G( i4 C5 J+ l" j#对人脸集合进行编码进行处理/ J$ A; j2 B4 `. T
    def findEncodeings(images):6 p) X6 e) O" n; W
        for img in images:2 F7 @# ]* D" W! H) ?. S( F
            #灰度处理. @/ e3 D9 r6 R" T, v0 i2 p0 V
            img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB), O: k; L* ~" A0 M
            #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果
    # W+ h8 C- ?: H. g        encode=face_recognition.face_encodings(img)[0]5 b8 k6 {% i! T0 u, d; @4 s$ j
            existsEncodeingList.append(encode)
    : [! N" T8 c' p0 t" e: z: P* ^! i7 ^8 e+ i3 T, d8 |  B
    #获取当前存储的人脸编码集合2 c) c0 P/ r$ ~8 ~4 S
    def findExistsEncodeingList(img_path):
    # \2 ]% [. V) m: m- D  F6 V  w    images=[]& ^5 M5 F, {& ]5 R$ M
        #列出已经上传的所有图片
    . s% g; ?( M( \5 t    imgList=os.listdir(img_path)
    ' z8 F6 x! M9 v( k) s, J9 O" O    #处理存储的图片得到其人脸编码
    ; \/ I  e- Q7 v    for pic in imgList:* g2 c  H' x& w2 I" u3 k
            img=cv2.imread('{}/{}'.format(img_path,pic))0 c% Z3 ^/ |9 a  K6 X9 `- j- l
            images.append(img)7 p7 I) x, ~0 j9 O
            classNames.append(os.path.splitext(pic)[0])3 {. b4 }4 M, {, o, X' b
        findEncodeings(images)
    3 Q  S9 L& v2 a( `0 ?7 m" l; N7 `4 S) @( \7 j1 l5 x
    #选择并对比图片
    5 }( s- T0 B) `def choosepic():% ~% m: z. D, X' n0 z5 A# y
        choosepath = tkinter.filedialog.askopenfilename()
    7 ]- Q4 |+ l1 N  P    path.set(choosepath)
    ) h2 Q# C+ ?/ ]( ?4 r    img_open = Image.open(entry.get()).resize((530,750))& ?  e8 v; S' L$ }/ ~* `! R
        img = ImageTk.PhotoImage(img_open)
    - b, S1 R% v' U$ A. z6 x    lableShowImage.config(image=img). p+ ?$ A6 `% }- x
        lableShowImage.image = img
    4 q# u2 g6 ?/ t8 Z5 y- B0 f    lableShowImage.place(x=30, y=70, width=530, height=750)
    / X: K% f% R* Y; d8 z& [" a    faceRecognition(choosepath)/ o& H2 }& ?1 Q. ]
    & h% q. t" q% n! V1 A: Q5 `5 f
    def faceRecognition(choosepath):
    / b+ _3 ~( P/ N  ]    frame=cv2.imread(choosepath)1 j: T5 b, {. S/ T  H8 O1 r  E
        frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
    , d$ L5 ]( I) ]/ f/ T6 m    #对摄像头读取的检测人脸, n4 n% w- @8 ?4 A" h1 M4 i2 G
        facesLocate=face_recognition.face_locations(frameRGB), I7 ]* Q: x# _+ ]  B+ ?
        #进行特征编码1 T! |7 b9 D1 @, l& D: D5 G5 m0 h& D
        faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)
    4 D& c! c9 f2 @        #遍历检测的人脸和库中读取的图片进行对比,计算其相似度
      F0 j- T6 {( F: z8 N3 p5 y8 `' z0 L3 W    name='unknow'  @+ z: \$ h7 H2 A
        for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):( Y' ^$ P! Q# R
            #进行匹配) G! n) E+ _+ H+ u" k) }
            matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)
    % V1 q7 ]9 `; e% [* y        #计算相似度
    + B2 l, a* O! G" _% o+ F, }        distance=face_recognition.face_distance(existsEncodeingList,face_encoding)# i$ {% W$ r" u8 y# ]
            lab='unknow'
    ; _; ^0 k" D: |/ j5 P        for index, item in enumerate(distance):1 N/ E1 l- h9 B6 p0 c6 H
               if item<0.5:/ M9 J5 w- w8 W: c
                    if matchs[index]:
    ) Q9 \/ n/ m4 C: ]                    #得到匹配到的图片名称与相似度值: Z- R0 ?' {4 i5 t* v6 }, l
                        lab='name:{}; Similarity:{}'.format(classNames[index],item)
    ' ?& j9 o: B: t: x+ E" ~  O                    name=classNames[index]
    . q2 Q4 S* r$ f! M) }% C+ v* A                    break
    1 h8 }# ]6 i0 R0 Q* C, h* p        #初始化面部捕捉框显示绿色
    1 v/ I( h) q+ R( B) ?# c        color1 =(0,255,0)4 d  F6 B9 w7 L9 M# }; v; y* F
            if name =='unknow':' \8 |* V  _6 z' p/ \' s) N: M! q, S$ ^
                #未能识别的时候显示蓝色
    " Y$ H9 r0 l2 f& W6 I            color1 =(255,0,0)7 ~- m' J% l! `8 ^* i  J
            #画面部捕捉框( e1 b, V4 W1 P& A. r
            cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)
    9 R" N5 ]% [4 _1 K, E/ g        #在捕捉框上添加匹配到的图片信息
    4 w6 d* N' S* Q9 e+ q        cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)+ `4 O: ^! m7 i& [! ^, }$ N0 V" |
            cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)
    # k5 ~0 `% b2 u( t    img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))9 h6 I! Y0 H2 b$ b
        img = ImageTk.PhotoImage(img_Recognition)
    : W  _7 o  K& J    lableShowImage2.config(image=img)/ a' c$ Y! V1 {
        lableShowImage2.image = img
    " k$ g  \9 t+ G9 t    lableShowImage2.place(x=630, y=70, width=530, height=750)
    - X( I. a# n" z& O
    ! b- v$ R' ~8 y0 B0 Y, ^/ Bif __name__ == '__main__':
    & I/ T3 c7 V, m: G$ H- D    findExistsEncodeingList(img_path)
    1 L9 d8 c2 t+ m    #生成tk界面 app即主窗口
    0 k) `* b+ N$ `    app = tk.Tk()  7 _6 p$ @3 P% h$ L% {
        #修改窗口titile
    ' ]  U, |$ A9 J" I! q1 k1 u    app.title("show pictue")  1 j) n# ^" U+ m4 n+ N' V
        #设置主窗口的大小和位置
    * b  |9 `6 _) T- m- F    app.geometry("1200x900+200+50")
    + {7 `5 F! S* f" k& q: Y    #Entry widget which allows displaying simple text.4 l4 |- y5 \) n5 K+ M
        path = tk.StringVar()8 U1 r) I; U$ {
        entry = tk.Entry(app, state='readonly', text=path,width = 100)* u0 T3 r2 m9 G& B5 W
        entry.pack(): R3 R. M. q. K' E1 N: b2 M& p0 A
        #使用Label显示图片' A. f" l. R) w, R6 z/ d
        lableShowImage = tk.Label(app); h& b: P- Z: S' C1 D
        lableShowImage.pack()
    ! X% K: l1 K* [     #使用Label2显示处理后的图片
    5 t4 e0 B7 z* G* R    lableShowImage2 = tk.Label(app)
    ( a1 X' ]4 M# T, Z& }+ j    lableShowImage2.pack()
    3 H! o9 b$ O  p/ `) t" I    #选择图片的按钮1 {  y: k; B6 t, O* D$ |
        buttonSelImage = tk.Button(app, text='choose picture', command=choosepic): V  H; }' `( d  p; C  F
        buttonSelImage.pack()" n/ b9 H2 a4 |1 i8 b
        app.mainloop()+ ]! Q* r2 H8 X7 ?
    , J5 z0 }5 A, S& [4 Q6 j
    3.说明$ F, h0 P+ x  L9 j8 b
    首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。# f* |! Y' w, Q& M

    * f: y, O: e! v- @4 r+ a! C5 i  ]" i+ A7 ]+ V

    4 E. h2 o8 k1 g 其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片9 ?4 r" V+ M; o- M
    2 P1 u8 q1 f$ J$ s  l3 C/ b3 u
    1 m" D2 H* Y4 R) H& j

    ( Q2 W& ~7 G- `( C 但是效果会存在色彩的失真,效果如下:
    $ l  G0 l2 C% B- ^' l; w9 M
    0 e3 b5 q1 h! @+ y
    % V5 Y! k, e: g3 |3 P. z  o: k  @- _* b5 w2 J
    也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。; n& l' q! ]! b1 Q' S- f
    $ ~) g: Q0 i; J: s8 f; k
    这里简单提下PIL的九种不同图片模式:! |4 I6 x1 M9 e6 x2 \7 E
    : N5 Q" R# h9 H3 f7 v
    modes        描述3 \& `8 V3 F5 Z% J* w: I% i, ]
    1        1位像素,黑和白,存成8位的像素
    3 U9 U: J& X3 G/ a# V& f' fL        8位像素,黑白' Y  m' ]" s+ d" u7 f
    P        8位像素,使用调色板映射到任何其他模式
    ! ^! \5 _9 G6 K- d  D8 C' WRGB        3× 8位像素,真彩6 H% J1 v' x' f6 k6 l' j; B  T( \
    RGBA        4×8位像素,真彩+透明通道' Q3 D) g" U* k
    CMYK        4×8位像素,颜色隔离
    7 y9 N' @4 Q& ]- _: Y" p: k) gYCbCr        3×8位像素,彩色视频格式, I2 w" [1 t2 I! k# [# v# v* {
    I        32位整型像素; N" V" }$ ~  X2 L+ _9 G' x; q( b
    F        32位浮点型像素
    " q  H; w% u+ u/ c4.实现效果+ q, n  C/ F& `$ Q

    0 F. P5 H+ E( Z  u2 i, {' V8 a
    1 [/ D& q. D. T/ w0 D8 u/ u$ ]
    * t! d3 Z" Y+ W& Z6 `' h- E) o. M, \/ q9 [
    可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。
    1 t1 d- P- i# Y- U————————————————
    * |2 N* r! u) H& m3 d/ s2 ~版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    ( q: d' a& m+ V/ j4 B2 a/ F, p7 `原文链接:https://blog.csdn.net/qq_17486399/article/details/1266292888 u1 C5 z# j0 Q# c
    3 @1 L8 I" N) g, t; R" }5 ]% z- a

    1 w9 w3 h7 Z4 U- {0 A5 A( a
    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-1-3 17:22 , Processed in 1.477274 second(s), 50 queries .

    回顶部