QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4146|回复: 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实现人脸捕捉与人脸识别(照片对比)$ F2 x) A4 f$ D
    5 S$ Y8 G# A! k. p: @# @
    1.安装包依赖
    $ h( {- G8 J0 L" ~与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。% w. s9 I! R% `% L2 R2 Q4 y: q0 H
    9 @7 A/ P/ i+ o" u$ H4 ~" N
    在python 3以上版本tkinter是环境自带的,所以这里不需要安装
    - h# K) B2 L3 A6 ?1 i* Q( L7 T( G2 O4 E# U* C% b5 a/ T8 Q* m* B
    2.代码示例% ?( \+ j7 c$ s! y$ |* D
    import os
    8 w) x$ N; \! j. R& B- c0 aimport cv21 T0 B, O9 K( O7 ?- x
    import numpy as np
    2 h8 q& m3 a1 p/ R& x7 p5 Wimport face_recognition8 r& m  L( ]3 [/ k5 X, I# T% M
    import tkinter as tk  
    " t' k4 h/ o( Z& a+ _& Y+ nimport tkinter.filedialog& b' b: J3 E. o0 T1 a. g
    from PIL import Image,ImageTk & H& E8 u2 z( r3 C# i- d8 A

    * v; x3 v3 I- u+ O0 B( O" `classNames=[]
    . o" a; M% O8 r- }/ q/ zimg_path='Picture'2 h% [- P4 V) h6 U2 i0 W9 H9 T1 G
    img_recognition_path='Recognition'+ q4 y: Y5 N6 F
    existsEncodeingList=[]  ^& o3 J3 M9 l  U/ r
    #对人脸集合进行编码进行处理. S8 f$ T9 `/ `; Q. [: ]7 L2 o( x
    def findEncodeings(images):
    4 q7 [% v  _! t8 a& v    for img in images:
    $ l3 W( A; _+ Q/ \8 V        #灰度处理8 g1 X1 [. {/ l' n, ?2 i9 f! e7 u
            img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)
    / w! V5 |" y, h. Y7 ^  ~        #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果
    ( ?% t5 @+ m: u7 Z        encode=face_recognition.face_encodings(img)[0]
    & _5 u1 R4 f/ }4 n& u- ?* l+ B7 I        existsEncodeingList.append(encode)
    8 |: K1 g9 _, F# g1 v% w7 S' o$ A2 T5 Q  i) }9 d
    #获取当前存储的人脸编码集合
    # Y0 F* y4 l" {, r- qdef findExistsEncodeingList(img_path):
    . d5 L0 Z+ n  o" M. E0 ~) K    images=[]" C# B9 `" ]+ B5 @; S* d" p
        #列出已经上传的所有图片' c2 A. C7 S% V: a7 i5 u8 Q  i
        imgList=os.listdir(img_path)
    / {8 Q/ v* B: s7 e    #处理存储的图片得到其人脸编码
    * M/ {& p+ T* w1 J# A5 o    for pic in imgList:) z- U: u6 C9 @* X4 N0 Z& N& Y
            img=cv2.imread('{}/{}'.format(img_path,pic))
    / Z2 R% Z; c# Q        images.append(img)  q2 K: U: u3 m$ o. B0 L
            classNames.append(os.path.splitext(pic)[0])
    4 z/ {+ T6 h2 \* b; c" f# r    findEncodeings(images)0 o* Y% P8 q6 f3 A9 a0 P
      t; j5 L0 V! ]+ q! m" z2 b  J6 L
    #选择并对比图片
    , j5 _0 [  q7 S: e0 ]def choosepic():; a" k/ Y+ g, J4 `% R) F& {
        choosepath = tkinter.filedialog.askopenfilename()
    ' W2 U% P" \' S3 `! a. v    path.set(choosepath)
    + b+ j: Q6 k7 Z( e; a" p/ n) I  N    img_open = Image.open(entry.get()).resize((530,750))
    " B3 d3 c" F6 R    img = ImageTk.PhotoImage(img_open)
    9 h: m  O& ~) A+ K+ G. H    lableShowImage.config(image=img), a" `4 p* n3 w7 ^8 c4 J
        lableShowImage.image = img) Q1 s% M) S! G
        lableShowImage.place(x=30, y=70, width=530, height=750)
    / q, l1 ^) o* r9 `- b9 N3 F$ ~    faceRecognition(choosepath)& A. L& t  l5 J# y, B0 ~; I
    9 n( ]! C7 e9 f3 a3 R. W0 x/ p- g
    def faceRecognition(choosepath):
    9 g! D$ {' }  {* |. V1 q    frame=cv2.imread(choosepath)
    * u% E5 Z0 Y4 Q  q+ A+ }+ `    frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)9 d# O3 ~: I9 Z5 U7 k% I1 s' J
        #对摄像头读取的检测人脸
    . ^! I' I% y  `" Y- v: k    facesLocate=face_recognition.face_locations(frameRGB)- w! S7 [3 q: P+ `# U) ?
        #进行特征编码8 k0 q1 A5 Y; j2 a* N- T# E  H$ M' _
        faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)
    , c1 h  N. A) {8 l& M4 f& ?. h+ Q        #遍历检测的人脸和库中读取的图片进行对比,计算其相似度" R0 R3 T9 w; X) e- |% b; S
        name='unknow'
    5 C6 K3 s- A' e1 K* x    for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):7 `: v  k. Q  X: W  ~4 Z4 S0 H$ j
            #进行匹配# v* C8 {# q, h! K* o& t6 U
            matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)  o7 \4 L, P  k* T+ {" ]6 b8 u6 c
            #计算相似度
    ! `# C1 C) _- M) m0 q# }2 G        distance=face_recognition.face_distance(existsEncodeingList,face_encoding)
    $ P: T! ]) r9 c- d8 i4 F/ T( K        lab='unknow'
    2 S' ~1 m! ]- k  J; k! |, G        for index, item in enumerate(distance):; F/ f% F5 J* R3 z) M1 v6 M
               if item<0.5:
    & ^* W: [+ t! \1 X: t  S- K: j6 E) Q                if matchs[index]:
    " B6 F. ^) N' z9 Z                    #得到匹配到的图片名称与相似度值
    5 _! \/ d/ l. m# z/ _2 Q                    lab='name:{}; Similarity:{}'.format(classNames[index],item)! f1 g0 T4 L8 E5 j: d
                        name=classNames[index]
      E  {1 b+ i9 M; }                    break5 c$ R/ p" `8 e, q- {9 {
            #初始化面部捕捉框显示绿色$ Y  k$ V- f$ M
            color1 =(0,255,0)
    * \. }) {+ b% _% K& I" q. |        if name =='unknow':
    1 o; w9 B4 i; u$ B1 Z            #未能识别的时候显示蓝色
    & ]( q2 v+ A/ }6 _' v            color1 =(255,0,0)
    & K9 x3 l' w- I4 V" {! X0 P# J        #画面部捕捉框2 `( g2 f7 e) O( E% B+ c
            cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)' e( ~; |6 q( R+ j
            #在捕捉框上添加匹配到的图片信息+ l6 h5 B* c' T9 n$ g7 P
            cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)! I# {8 D. k% Z
            cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)6 P( v9 Z" O( J; x
        img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))$ ~" \6 j: Y1 l0 d. |' F8 R
        img = ImageTk.PhotoImage(img_Recognition)
    1 l2 k3 B  M4 p    lableShowImage2.config(image=img)5 O. o( Q& L7 ?  M
        lableShowImage2.image = img4 l+ d- s0 O- D- H
        lableShowImage2.place(x=630, y=70, width=530, height=750)
    ) G( }/ r1 S  `& R. A7 P: u- n0 o
    if __name__ == '__main__':% P2 Y, E8 T, F% c- n( d4 E" a
        findExistsEncodeingList(img_path)( ~. U/ i6 B0 p
        #生成tk界面 app即主窗口; z- t& N. P6 D9 e( u7 l7 d
        app = tk.Tk()  
    9 f1 n& c  E/ V2 m    #修改窗口titile5 Z1 D- N! U6 {, ~
        app.title("show pictue")  ) O- {+ J6 j4 C" T; g" o' O
        #设置主窗口的大小和位置
    ! k  p6 c8 @  d0 G8 e% P    app.geometry("1200x900+200+50")) U/ {; j2 q& D% D. j: D& N9 Z
        #Entry widget which allows displaying simple text.
    ' W. F9 x# o8 U+ ?0 }4 {* i( ~    path = tk.StringVar()& x' S7 l5 i6 n* _  Z* k4 O
        entry = tk.Entry(app, state='readonly', text=path,width = 100)
    7 D4 ?$ |) I, B9 `1 P    entry.pack()
    0 F' l0 O9 O7 e% N    #使用Label显示图片* {) T1 b. b* X6 ]- ~5 Y7 c7 R
        lableShowImage = tk.Label(app)2 b9 C9 B0 O2 k: J) l- ]# r* d
        lableShowImage.pack()
    9 P3 T( j4 d4 E9 e  o! A     #使用Label2显示处理后的图片
    ! E  V* V8 t6 u* s( ]    lableShowImage2 = tk.Label(app)
    : l+ d; R  b: C7 O, c    lableShowImage2.pack()
    & ~) A& d/ ?# j7 ~- j4 k% }. \    #选择图片的按钮
    - D9 T. v4 b, c0 J1 [4 P  L. G    buttonSelImage = tk.Button(app, text='choose picture', command=choosepic); n3 U6 `3 t) j
        buttonSelImage.pack()5 y/ `0 n9 R/ ~8 t
        app.mainloop()
    , j2 Y/ Z3 p5 O6 @3 }' }3 z7 v5 a4 @
    3.说明
    5 B: V) ^, ~5 y# M. c7 t$ n8 p) y首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。
    ; I8 m1 C" O. t, q9 [& R$ o
    ! P3 c8 r: ~6 z
    % l0 W. l% h4 V, @: L/ l3 Z$ m$ C+ O: [; w
    其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片
    # ?: {: F8 Z0 S) R4 x0 ~8 t$ \2 {7 T$ c6 |! V) y% |

    6 }% _# z" F' I5 y! ]) u, I3 [: n* }
    但是效果会存在色彩的失真,效果如下:5 P5 ]5 E# l% t9 G) Z
    . ?2 E) L6 D" q3 n" K! i3 c9 ?  u

    9 A& A8 s5 |  L; B  b0 G  G
    3 T+ z  K& u% h) w5 C也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。
    # X  y: j3 b& i
    ! ^+ y8 t1 q7 u5 ^0 X  k" Y7 n这里简单提下PIL的九种不同图片模式:% f  t+ k( J; A5 j% d

    & @% [6 Z( K1 \0 wmodes        描述
    4 Y0 A4 i7 W1 L1        1位像素,黑和白,存成8位的像素
    0 d5 z5 V% ?: V% J8 K  w2 U/ JL        8位像素,黑白
    / b9 Y$ }4 Q3 Q7 vP        8位像素,使用调色板映射到任何其他模式
    2 Y2 i( B' q% {0 cRGB        3× 8位像素,真彩. e* m6 b; y" D0 N& ~0 c
    RGBA        4×8位像素,真彩+透明通道
    8 a7 g& A8 n% }! u" _: Q% \1 zCMYK        4×8位像素,颜色隔离0 `7 p3 Z8 b% ^" Y; k4 O2 k8 q2 _
    YCbCr        3×8位像素,彩色视频格式
    % L$ Y/ }: v! J" h# H1 X6 mI        32位整型像素
    1 ]1 t4 M& a5 g0 S* ]4 [8 ?; MF        32位浮点型像素
    ( x7 G9 T. ], B" ^7 h4.实现效果6 v- P, t3 y& t  N! |  z3 N

      S! q. ?4 e* I" q* k8 n; i6 u
    , W) L  _* u8 ~( M+ i- z
    - S6 b- D& }: F
    & a7 Y: K6 z' {- s 可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。
    - H# j  F) W' \————————————————  a6 w, Y4 }$ G
    版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。$ T' l" z0 C. \! y( e( {
    原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288
    3 O  z2 O7 j, g/ m$ U
      k/ b" Z# K% x& v  {" I
    # D# Q  q1 T3 u7 ]6 }
    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-4-12 07:37 , Processed in 0.557845 second(s), 52 queries .

    回顶部