QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4150|回复: 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实现人脸捕捉与人脸识别(照片对比)
    # K7 |  n0 a% C+ w
      J6 R* f2 m( m5 x4 v! |6 K- g1.安装包依赖
    " j" g" ]# p8 F) x2 U: N与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。5 e2 p( ^$ U7 B  l" ~

    1 d% O' w0 i7 `在python 3以上版本tkinter是环境自带的,所以这里不需要安装
    - {# [$ H, Z7 a& \
    7 ^' v; E& Q. l( f$ X8 S2.代码示例
    % U+ \$ o! G. {import os, d8 |1 D3 {7 ~6 g; u3 e% c* {
    import cv2) i6 _: c) D& V! Z" W* P
    import numpy as np
    % |: E3 Q$ |7 zimport face_recognition+ e% \$ C. q% T8 B# d, P
    import tkinter as tk  
    4 R# D5 a) V5 U! I2 P8 d* y/ Simport tkinter.filedialog
    # z8 E9 D0 I0 f/ ?3 o6 G6 xfrom PIL import Image,ImageTk + K! O( q7 u: V1 S6 [
    . x! n5 j7 n) F9 v% t! ?
    classNames=[]  H; _/ A! H6 c0 H! l% R2 k
    img_path='Picture'
    2 r2 e0 Q! h! X6 Rimg_recognition_path='Recognition'
    + m1 l$ ~# A" R! vexistsEncodeingList=[]
    + d2 D4 s* n: p. U& N* ?$ I#对人脸集合进行编码进行处理" u; X% ^: J" y# m! U5 k
    def findEncodeings(images):/ G$ H$ ~' i. H# l
        for img in images:" Q" k/ k2 |8 M& O4 u& j
            #灰度处理( ?0 |% B( B2 A- G3 O  P8 Z
            img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)# ]0 m1 R% F5 s
            #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果. y% S3 T8 k6 t
            encode=face_recognition.face_encodings(img)[0]
    . w! \) b$ m' Q  X3 l- a2 z# N        existsEncodeingList.append(encode)
    * j& {  C' I; b8 {8 z$ a/ w6 Q: A: F- z4 o
    #获取当前存储的人脸编码集合1 v; t: w/ M3 H5 g  T
    def findExistsEncodeingList(img_path):2 H, D2 k) W4 y3 w( h0 S% D4 W1 e
        images=[]- j9 s4 n# `! j: k" e9 S( f
        #列出已经上传的所有图片& R: E8 o+ l+ C- s' `
        imgList=os.listdir(img_path)
    3 x( r- c/ [9 [4 ~. n: B    #处理存储的图片得到其人脸编码
    ' H- ^" l8 Z% d* C! A    for pic in imgList:
    ; i7 u# G) F6 x. f0 Q  R0 U" k        img=cv2.imread('{}/{}'.format(img_path,pic))1 t4 I9 M$ |$ D) X+ u! h5 A2 t
            images.append(img)
    ) e$ [0 A! |+ B1 W- A0 X& p        classNames.append(os.path.splitext(pic)[0])
    ) f% v2 k* A; Y" P5 g6 a    findEncodeings(images)
    * O; H3 }% Z2 J( o& d% v. B- E6 P* B: {6 C; U  g
    #选择并对比图片
    : T4 I* F# v/ K1 Idef choosepic():
      P" ^- o" l  N9 @& u    choosepath = tkinter.filedialog.askopenfilename()
    + |# X' y0 R! K+ m% Q    path.set(choosepath)
    6 ]0 P/ ?0 @+ t: N9 ?+ y    img_open = Image.open(entry.get()).resize((530,750))
    , b1 M- [+ l" V6 J6 u3 j    img = ImageTk.PhotoImage(img_open)
    6 ?. T9 b4 n8 K$ @7 |( h! m    lableShowImage.config(image=img)) A$ D" w  u$ N% _7 o/ j) s- M
        lableShowImage.image = img3 [9 y' y2 ?/ M
        lableShowImage.place(x=30, y=70, width=530, height=750): Q. y: {+ r: Z$ ^9 x
        faceRecognition(choosepath)
    3 O, c3 Q3 R! z; H- X3 M
    7 H+ v+ w; T0 ]' p/ {1 Edef faceRecognition(choosepath):
    % R+ I8 H( `) l6 L$ X; o4 l/ }    frame=cv2.imread(choosepath)
    , B, Q2 s7 z9 k4 i    frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
    # C4 K4 W2 C# ~- I- p2 R' R    #对摄像头读取的检测人脸& `( M9 X5 n5 A& z+ ?2 u
        facesLocate=face_recognition.face_locations(frameRGB)
    7 H. S0 z! |6 X; j$ Z6 w( N* |; P    #进行特征编码
    4 s% D" b" F2 U$ g+ I    faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)9 B1 g% W% X- S% m
            #遍历检测的人脸和库中读取的图片进行对比,计算其相似度& k# g7 C) V2 k0 w+ T( T
        name='unknow'5 C4 T5 A) u, y/ B8 ?6 M3 a
        for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):
    ! H2 q! I) W! x) J2 V        #进行匹配2 ]2 I: k8 X( O6 q/ N% b' U. G
            matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)
    ! W9 M, K- V% X( j- N/ E& C8 H, U        #计算相似度
    * R$ M+ T6 w# \; W5 ^% y        distance=face_recognition.face_distance(existsEncodeingList,face_encoding)" _6 ]7 B' z* ]
            lab='unknow'; |4 Q; |- N9 p" P
            for index, item in enumerate(distance):
    4 G) `2 V4 g3 H! L3 ?8 i- s           if item<0.5:! l* q* b) v$ I; c. l' {) Z2 V8 a7 o
                    if matchs[index]:
    2 u( a6 L" z+ u% p( p0 o                    #得到匹配到的图片名称与相似度值5 [+ a9 x5 @) w, u4 n7 E
                        lab='name:{}; Similarity:{}'.format(classNames[index],item)
    2 e* |) |: x0 v. ~% i. D                    name=classNames[index]/ t& C3 p/ M; }& m1 {$ D
                        break; e) ^" n) R5 N2 W% {
            #初始化面部捕捉框显示绿色' ]) }( L" C4 S
            color1 =(0,255,0)
    ( P" y0 ^9 T5 S" o8 d        if name =='unknow':, B  l3 n: ^* w( j, Y$ W. ~
                #未能识别的时候显示蓝色8 N7 t1 E2 ^2 T, v
                color1 =(255,0,0): _2 r, a, X7 l& @
            #画面部捕捉框$ _3 K6 ~# w6 [2 i' U6 o! f
            cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)  t- K2 d9 _/ b) l* \
            #在捕捉框上添加匹配到的图片信息( I) i7 o- w2 T: G
            cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)
    & ?& ~! V  P! U+ d* y# H4 r, x! B: I( H        cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame); R' G/ t7 h& `% M4 O  @
        img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))0 j$ Z5 c2 {7 p+ _" U, k
        img = ImageTk.PhotoImage(img_Recognition)
    8 l% [' C# z* M/ \* G0 y8 F    lableShowImage2.config(image=img)
    * d) `; U6 x  R1 Z4 {8 o6 j    lableShowImage2.image = img
    ; U% t5 c1 y& P    lableShowImage2.place(x=630, y=70, width=530, height=750)- x- l5 Y/ C4 y' n, c- a
    ' e8 t1 `2 F9 J
    if __name__ == '__main__':
    6 L* x7 |0 P$ U  P) w7 Z; k  v    findExistsEncodeingList(img_path)
    % {4 h, n  q' `& S1 @! P! i    #生成tk界面 app即主窗口
    - m; _) D8 Y- ~. D    app = tk.Tk()  
    1 H  ]  b! X8 H% Q* A% p( U    #修改窗口titile1 H2 ?/ R0 `2 Y1 L# p1 d
        app.title("show pictue")  " w8 V( `# d& a3 C3 ]; S
        #设置主窗口的大小和位置$ X# ~2 f) [. Z- D2 Y
        app.geometry("1200x900+200+50")3 ?+ O! h+ R! z. l' ^! M. w, C. _! y
        #Entry widget which allows displaying simple text.6 E0 Y% k5 S9 e3 e: }* Q
        path = tk.StringVar()9 C( E# S( J9 |
        entry = tk.Entry(app, state='readonly', text=path,width = 100)
    0 \4 T; B( K. e6 y& t  l  H( [6 h    entry.pack()
    / |- s6 B9 q4 k# C. @    #使用Label显示图片" P8 Q+ w; V4 u1 A* M9 O
        lableShowImage = tk.Label(app)9 g+ H& ~% Y( V7 n6 Q# b  a
        lableShowImage.pack()
    + a/ @, m% O" h9 P  b+ K( G+ h     #使用Label2显示处理后的图片
    : N- ^* D9 k, I    lableShowImage2 = tk.Label(app)
    6 z7 W) p6 V1 u    lableShowImage2.pack()6 X. v. @  ]& U, j  v6 s
        #选择图片的按钮5 R0 z/ F" R$ O( f5 V/ Y
        buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)
    3 p( V- c7 t3 T$ X    buttonSelImage.pack()) M; f& D- B- K  e8 V1 o. d+ {: M5 `* a4 [
        app.mainloop()
    7 n  r4 ^! f6 B' Y0 R) r' q
    3 Z; t" H# ]" a: w7 \: T3.说明/ u6 L& Q5 _5 j+ i* e
    首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。
    # y* m1 P3 e0 t; x/ Z5 H- F$ n7 w$ Q6 S" ]
    - Q- {. N+ G& P8 d: s6 n2 i
    7 d- k& P4 K$ D) F
    其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片
    # v! c, |8 C% [! i, a$ }
    ) n8 t& D) i0 A( ]3 G* u: d7 \2 e
    + D$ Y4 Y* T% h% u7 U; m' P" [6 f6 W% l5 D1 \
    但是效果会存在色彩的失真,效果如下:- f) q; L1 r5 K
    9 p5 n% N8 B# E4 F( _  E" X/ K

    7 w6 E! R: m& }1 l( U
    + y2 n7 S, E& \, l2 q也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。
    . `5 L5 z# Y4 S2 Z
    ! E; ~: y; R1 Z这里简单提下PIL的九种不同图片模式:
    3 I0 o) Y8 d3 ]5 m3 Z3 S, Y. M& R" P! D) \: w: |* u) M
    modes        描述
    6 B- z8 I+ c5 p1        1位像素,黑和白,存成8位的像素# C' ?+ n9 j5 q% d
    L        8位像素,黑白" e5 c0 f7 C4 `* o  l8 [
    P        8位像素,使用调色板映射到任何其他模式
    . @9 X4 c+ E; x( o4 sRGB        3× 8位像素,真彩
    3 u% b8 m7 ^% k; [& @9 pRGBA        4×8位像素,真彩+透明通道
    # ]' o  i! s9 {7 U: K0 uCMYK        4×8位像素,颜色隔离( [9 y% O# ]9 d, z7 s
    YCbCr        3×8位像素,彩色视频格式
    7 Y# q2 E5 G7 R5 l5 nI        32位整型像素
    - ^- g* A' M3 ~F        32位浮点型像素8 F# s, v; Y! H1 F
    4.实现效果% e# C1 }! P2 U
      m, u5 n# A7 I; A( D" d5 D
    ) N0 V% l; P4 O2 A" U
    6 C/ V4 C6 T1 w) {( n
    . q. Z* e  I( ^& R
    可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。$ ^/ d8 [# M: j( v+ Q
    ————————————————
    & B/ v' K1 G0 k5 X  }& d- v1 J版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。  b( m1 B# c  Z& r0 T
    原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288) C! Q. q1 E7 t# C5 L8 I- O; F. i

    % b1 t' p$ j3 t' T8 S& Z9 o+ G2 ^. I% a* n0 m% [' V" o+ i  n0 j9 e
    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-21 04:40 , Processed in 0.401620 second(s), 51 queries .

    回顶部