QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1517|回复: 0
打印 上一主题 下一主题

[其他资源] Python 基于OpenCV+face_recognition实现人脸捕捉与人脸识别(照片对比)

[复制链接]
字体大小: 正常 放大
杨利霞        

5250

主题

81

听众

16万

积分

  • 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实现人脸捕捉与人脸识别(照片对比)
    5 P1 x% B3 K4 ^0 u; H* ]! W6 n7 h! Z  F: |$ _  I
    1.安装包依赖
    , _+ P0 n; O0 t5 i) e. W1 u与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。
    8 O/ R  m# G( G  q* N5 g4 G
    . `& V0 N' L" E1 c$ ^# E在python 3以上版本tkinter是环境自带的,所以这里不需要安装! E0 I0 X. p" v! u7 \" {. e# C
    / i5 e3 y1 j* _% G$ R2 y, e
    2.代码示例
    4 o, h' Q: a0 y% Z% Zimport os
    1 ]: A% `2 m6 J: mimport cv2
    4 N7 M% `* d, h8 A0 t. Jimport numpy as np
    9 K$ I% d' y" V$ R7 g# Mimport face_recognition
    4 ]2 q) g3 N7 Uimport tkinter as tk    [5 J  x+ y# c6 Y) \
    import tkinter.filedialog1 i( N  ]# ]. v# ]* _" _; G/ v
    from PIL import Image,ImageTk ( o4 B/ w! @6 c- i4 n  Y2 |
    ) o6 u9 @$ B* j$ [
    classNames=[]3 X4 l' k0 S  _1 |1 t
    img_path='Picture'# p* C/ l( N$ ]" {2 ~, w
    img_recognition_path='Recognition'
    3 T5 I2 Q" b; t! {, xexistsEncodeingList=[]" ?- w1 x' ?) ~2 F: J- H$ |
    #对人脸集合进行编码进行处理
    3 [$ O3 V3 X% i' I/ o( fdef findEncodeings(images):7 j8 v, G' U3 s0 B
        for img in images:
    9 J/ G# o' I' w* C4 d4 Z        #灰度处理( c5 ]2 I- l; e
            img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB); t" m8 S3 m7 R, A
            #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果5 i+ X. T/ T! x( c! R
            encode=face_recognition.face_encodings(img)[0]
    : |: l8 A' g' H! g        existsEncodeingList.append(encode)
    5 B% F$ R% R" t6 y1 m& o
    9 ]0 W. z" a4 D0 O- x6 b) N#获取当前存储的人脸编码集合
    8 w" @2 s+ q4 x, ]3 B' qdef findExistsEncodeingList(img_path):
    % y% r' d) i* p% }    images=[]( S% r" @& `! t/ Z1 C( @+ X8 k' F& i
        #列出已经上传的所有图片
    , e# C- z6 r# f% [1 ?3 Y% ~    imgList=os.listdir(img_path)
    0 Y* p4 |6 ]; b3 R. y" W9 P    #处理存储的图片得到其人脸编码
    2 m5 r1 s  O0 B9 @7 D    for pic in imgList:. d& q; i! C) s+ u& r8 a: g
            img=cv2.imread('{}/{}'.format(img_path,pic))
    ' W- _+ m2 `3 l( r9 @        images.append(img): f1 f' i. V8 i8 w5 I& p: r
            classNames.append(os.path.splitext(pic)[0])
    6 f/ b4 b/ d* H4 s3 s    findEncodeings(images)3 E; R* n% L9 a# Y' M
    / p  X4 y6 ^7 R" w1 b4 s
    #选择并对比图片
    8 ~% r9 l$ e: Z" }- X0 d2 ~def choosepic():6 V& m0 d! R3 `9 N6 M0 q; A' l  Y
        choosepath = tkinter.filedialog.askopenfilename()- M+ W, B7 ]3 E3 ]& |, U  F/ J7 C6 Y
        path.set(choosepath)7 b7 e7 z: E1 Z( ^3 ?( R, i
        img_open = Image.open(entry.get()).resize((530,750))
    % ]0 B7 V  t6 `    img = ImageTk.PhotoImage(img_open)
    ' m% F/ Q& ~$ _  S# B    lableShowImage.config(image=img)  R! i5 p- g7 T* y$ m8 I
        lableShowImage.image = img& q% n; D, K* d% y
        lableShowImage.place(x=30, y=70, width=530, height=750)
    & A& h" z7 a. F2 y    faceRecognition(choosepath)( h9 D7 H. V& ?# _! k' d

    ) z# U; o7 A7 \; Xdef faceRecognition(choosepath):
    # [* v5 g8 ]' b; Z: S) \    frame=cv2.imread(choosepath)! J+ y3 F8 }' w8 j% p4 x
        frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)- l+ R& ]0 r8 U; ?8 Y- T4 [; k6 _
        #对摄像头读取的检测人脸7 t8 ?9 w7 q$ W7 ^
        facesLocate=face_recognition.face_locations(frameRGB)9 \# Y% S* V/ G; g. d, X! |
        #进行特征编码
    ! D  f3 b" v& e/ I$ ^    faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)+ L! _; r: y' x: [
            #遍历检测的人脸和库中读取的图片进行对比,计算其相似度+ Q8 N5 d" o3 E& E
        name='unknow'
    ; D8 C7 L% o# w5 d$ h    for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):8 q" \+ v; |3 @9 R) L1 X: k
            #进行匹配
    / [: }: o* `3 h8 A9 n0 m/ N        matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)
    0 N4 m* @! {$ V0 `        #计算相似度
    0 _; q/ k4 r2 {; i        distance=face_recognition.face_distance(existsEncodeingList,face_encoding)
    ! D0 E8 V5 i3 w6 |9 K3 }        lab='unknow'
    ' m& @- o, v4 M; d/ M1 L$ I' g& Y9 h        for index, item in enumerate(distance):5 L. R$ t7 S) I- J; j
               if item<0.5:6 ]. B; o! L6 a/ D* o9 k* Y
                    if matchs[index]:0 q+ Q3 m: |& c9 Y, }' r- _
                        #得到匹配到的图片名称与相似度值
    0 @3 ~. u& q! ^7 M* F1 c% ^, N$ }                    lab='name:{}; Similarity:{}'.format(classNames[index],item)0 ]. D# T8 o  Q/ b  z- ^
                        name=classNames[index]
    ) z. T* C( G$ c8 ~# N+ V3 N                    break* }1 s2 l. t7 I6 N' Z
            #初始化面部捕捉框显示绿色
    0 E) A# f$ O) [$ u% b        color1 =(0,255,0)/ m- F# j/ K4 z) V8 S6 q% \1 x, X1 F
            if name =='unknow':
    0 @- K" w& F4 g# I# `8 l            #未能识别的时候显示蓝色
    - Q8 u9 m8 }4 M            color1 =(255,0,0)) u) I6 p8 A" K5 V7 }# n' ?
            #画面部捕捉框
    8 j2 b$ h+ k+ {/ A+ {        cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)
    4 y* M3 q) u- g4 T/ u4 x        #在捕捉框上添加匹配到的图片信息3 H- r& A, j! V- c6 I+ S0 o
            cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)
    6 g2 w- e; S' s( v9 p5 J, g# w( _        cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)
    ' V, c$ P, }2 I: i* P0 W# r    img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))
    - N# p4 N' z# \    img = ImageTk.PhotoImage(img_Recognition)! m  Z/ y, ]0 s1 h- G
        lableShowImage2.config(image=img)' X+ ^' m  h. V; c4 r2 ]1 P
        lableShowImage2.image = img
    5 o0 w& I) v3 S- O2 V, g1 p. c5 B    lableShowImage2.place(x=630, y=70, width=530, height=750)
    " x* W1 X9 l# @: r' i/ U. q! T1 h1 l. M9 d% W
    if __name__ == '__main__':0 q; \) o% G0 C& Z! m$ p
        findExistsEncodeingList(img_path)
    # p2 [. q* \8 A7 [2 k. @) W  t    #生成tk界面 app即主窗口
    4 H- B0 g' ~1 I/ @' n# y    app = tk.Tk()  ( I% \5 b" |' p" e* w
        #修改窗口titile! l4 u$ t& A$ y; `: w
        app.title("show pictue")  
    - ]/ i, ~) z* N/ D2 k  ~) x0 H6 V    #设置主窗口的大小和位置. l: _6 E+ ~& Q) @, ^9 x! `
        app.geometry("1200x900+200+50")
    ; A* k0 x' _: z3 g( D, K    #Entry widget which allows displaying simple text.1 l; `3 t$ q( b0 I, \3 S' D6 ~8 J
        path = tk.StringVar()5 E% {* R- u0 E( e0 l. W
        entry = tk.Entry(app, state='readonly', text=path,width = 100)
    1 ]. N- Y9 K# ]$ R    entry.pack()
    6 N. N! F2 a" N8 Q! k    #使用Label显示图片$ b9 Q( y$ Z5 q+ n' K3 M
        lableShowImage = tk.Label(app)
    : n$ b7 ~% L  T0 L( K2 A& e+ K    lableShowImage.pack()( y, _2 }# [* n3 r
         #使用Label2显示处理后的图片$ R! ~1 @" L  z* M0 n, V
        lableShowImage2 = tk.Label(app)
    % ]8 \8 W1 w! [4 v3 ~4 c    lableShowImage2.pack()
    1 s' r5 p7 N0 N' h  J2 l% K    #选择图片的按钮
    & [6 _  n) D9 k, G  H  b. d/ w    buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)6 S# Y+ @, Y/ N" S$ U5 q
        buttonSelImage.pack()
    ! `6 y- ]. B# G: w    app.mainloop()
    ) U3 v: g) a6 j+ f% y. l, R1 [% S
    7 V3 \) U- t, B7 e. }5 N  A2 z3.说明
    * m4 w) m6 j" _  ^+ g* A首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。
    $ s$ W/ I5 A$ [1 w8 x3 e! Z4 f. p, t. x9 |
    2 R& m" [; ?) ?
    ) O) p7 M- V5 h( m6 a; }* X
    其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片
    : s7 W1 o; y) i3 j) I* f  x
    7 q) o9 ?1 j9 e+ @5 a- c+ z6 v0 p0 O- f+ s1 M# v1 B
    . k' r3 z. V) y1 H0 o
    但是效果会存在色彩的失真,效果如下:: @* A/ d7 e9 o( q3 m1 D
    2 r6 Z7 [, \0 s% n5 k

    3 a9 m( M1 K( a( Y* q0 b( T7 r. _/ I# j/ ^2 H$ ]% S
    也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。
    ; E# A3 O# J1 j6 m+ S# _3 i$ Z: U1 i$ ~0 v( N- N2 S
    这里简单提下PIL的九种不同图片模式:
      \% Y- [9 q0 }# D) `
    6 e1 o5 z) |( s% o' ]. emodes        描述( ?& J" X. l: V( [% z6 H
    1        1位像素,黑和白,存成8位的像素
    ; D. {! L; y: s+ q6 o8 `2 f$ fL        8位像素,黑白, ?' Z9 A$ e: n5 u
    P        8位像素,使用调色板映射到任何其他模式- S7 c# M! V+ P
    RGB        3× 8位像素,真彩
    % W# L! J$ a/ H% I2 DRGBA        4×8位像素,真彩+透明通道& \& n" ~8 v2 P
    CMYK        4×8位像素,颜色隔离8 ]' h# }$ p2 f0 C' H
    YCbCr        3×8位像素,彩色视频格式
    * p1 i. Z9 W2 }4 k, _, c$ tI        32位整型像素: |: u2 f; O2 H' G
    F        32位浮点型像素
    4 i. j2 A8 c4 l, u4.实现效果/ P1 C! z: \+ {( ~+ z8 G" X  j! H( T
    0 {* {$ ]6 x3 s- N5 p% J3 _: \' {
    # I5 _( j/ \' t! B. p( r+ u9 Y" \
    ! I( p. y6 W6 E

    ) [0 J' B+ `6 O 可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。- w1 g2 U: v9 ]( S4 q5 W% [
    ————————————————
    8 K. B* |8 W( K, t& O; h8 p版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。; y" h! a" c3 g7 C' x* j- W
    原文链接:https://blog.csdn.net/qq_17486399/article/details/1266292888 I6 f1 W2 g# ]. q6 s/ h6 e8 r; i

    / r* [: c; Z/ C) i; _2 b& B0 ^) j2 m8 U# V* K  {
    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, 2024-4-26 21:12 , Processed in 0.275430 second(s), 50 queries .

    回顶部