QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4143|回复: 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实现人脸捕捉与人脸识别(照片对比)
    . z7 E+ P! O- J! w) ^* R/ x2 q1 g6 y  O! J* G
    1.安装包依赖$ x& G  Y+ F8 p1 n$ p
    与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。
    * s1 V- J4 a2 y  U, {( [" a: u. D8 o6 m' y) X7 h
    在python 3以上版本tkinter是环境自带的,所以这里不需要安装) s" H0 }  e0 D

    - M' a% B$ e  o! W0 b# o( [2.代码示例
    2 I) j. v; r5 g/ Dimport os+ }) Y" V0 V% v. \$ J$ R
    import cv20 Q( ]6 k# y6 ]! J( O8 U+ F+ o
    import numpy as np5 d- t, ^4 N2 s& P' _/ K: T: w
    import face_recognition
    + R, \& k6 Z5 B! ^- [- S6 eimport tkinter as tk  
    / m( q) l4 s: F' [: n( limport tkinter.filedialog
    8 }/ Z' U% O6 d" D5 y) Vfrom PIL import Image,ImageTk + w  r  o0 d' a
    2 V/ I; W/ }( R, ]* P8 Q9 O
    classNames=[]
    + m& J& o# q: Y4 {2 b5 P; ~! Bimg_path='Picture'/ C# |- D; |$ p2 @. K- u
    img_recognition_path='Recognition'/ s1 H9 O$ P* l3 Z& }
    existsEncodeingList=[]
    " s; V. S* G9 @' X& G#对人脸集合进行编码进行处理  c* R' ~3 z% z. b! m
    def findEncodeings(images):6 O4 L6 n/ s8 U) L
        for img in images:. t: w# _: I) r- r) Q5 \
            #灰度处理4 M- X, m. S: S* X( x9 x* N3 l/ b$ B
            img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB). D$ V1 T$ r5 q& y+ h
            #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果8 U- L8 k$ |0 j3 d
            encode=face_recognition.face_encodings(img)[0]
    ' H7 w% s9 |- Y, |6 T2 Y        existsEncodeingList.append(encode)6 T: Y% H8 `) Z2 e# z* F6 F# t" Y

    . O, ~1 x, y' Y#获取当前存储的人脸编码集合) \; ]- A- G# m- m- I6 d
    def findExistsEncodeingList(img_path):6 c+ g: ?3 ?$ H! F4 Y4 ~/ f+ ^! I
        images=[]
    - ]% |( m, h! C8 u    #列出已经上传的所有图片
    & l6 @, u- h% ~/ I* e( @5 v+ \( u: _    imgList=os.listdir(img_path)
    ) ?% ~0 ?& s  |4 b* T    #处理存储的图片得到其人脸编码) \( c- i, K2 N+ a
        for pic in imgList:
    " j: n3 a  I3 z  s$ S        img=cv2.imread('{}/{}'.format(img_path,pic))
    ! s. w% j( W9 q3 }        images.append(img)2 ?. P+ a5 O, M, O- ~
            classNames.append(os.path.splitext(pic)[0]): W( {7 U' V& `5 c: c2 J
        findEncodeings(images)
    1 {6 {  U: D1 P1 v
    / K% z5 T6 Z& E#选择并对比图片4 v4 `+ ~1 c9 w. ^0 W; z# S$ I
    def choosepic():
      {$ g) W* k& e8 j9 @    choosepath = tkinter.filedialog.askopenfilename()) j8 S* L9 f5 U+ W: A' {4 r# i8 ?5 }
        path.set(choosepath)# `. E  q$ S& S, e) L
        img_open = Image.open(entry.get()).resize((530,750))3 q: f8 K. t7 o3 W( {* w; Q
        img = ImageTk.PhotoImage(img_open)
    / U+ e, Z# `" h    lableShowImage.config(image=img)( k; H' |9 O4 ?! j+ R* W% A" {5 \
        lableShowImage.image = img
    6 r/ c& ]) A2 a7 z9 ]    lableShowImage.place(x=30, y=70, width=530, height=750)
    : J* p: u% P' m, G    faceRecognition(choosepath)0 A0 Y1 |: ^  s8 _

    $ I8 l- A/ ~1 Q" }def faceRecognition(choosepath):
    $ ~9 c. p6 g5 ~1 A+ @+ e    frame=cv2.imread(choosepath)
    + Z, r' \; }0 S    frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)$ b. }2 |0 c& X- ?4 Q( I
        #对摄像头读取的检测人脸
    + n; H+ R8 o( y4 _    facesLocate=face_recognition.face_locations(frameRGB)& X; F% D( a/ m0 x  Y
        #进行特征编码& z$ b7 q& E+ d9 s
        faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)" t) K. ~0 h* f5 y
            #遍历检测的人脸和库中读取的图片进行对比,计算其相似度
    . R+ f# P9 l- `- V/ N    name='unknow'
    2 A4 v4 f2 Z: j0 I0 E! ?: u    for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):4 |& s9 [/ ^- y: |2 c
            #进行匹配
    3 [& v! c( A8 T5 Q7 J        matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)
    # ]3 q9 D% ^' J. O1 m        #计算相似度
    $ H' P# _  g; y1 c6 z        distance=face_recognition.face_distance(existsEncodeingList,face_encoding)
    4 I& E1 L/ A* m* m        lab='unknow'6 H, |) S9 X" \9 M, B7 [: u
            for index, item in enumerate(distance):
    % D5 @  h0 h1 j& i  o+ z. w           if item<0.5:
    2 b! a4 n: {* S7 ?( w7 T% R                if matchs[index]:7 B9 J( `8 k! N5 q- \8 b
                        #得到匹配到的图片名称与相似度值: r5 D3 j! c9 {7 r! c0 o
                        lab='name:{}; Similarity:{}'.format(classNames[index],item)
    8 k0 I! h; q; E5 d! a, G& e                    name=classNames[index]
    / Q5 C, |+ n) C                    break
    ( r2 G7 E/ H6 \' o$ a- V! n        #初始化面部捕捉框显示绿色' E' [0 ~2 G: h3 T9 L$ X1 t, I
            color1 =(0,255,0)
    : a$ p" R' \4 S        if name =='unknow':
    6 L1 W; [: ^8 k! o            #未能识别的时候显示蓝色
    . p6 c7 _6 I5 F# e            color1 =(255,0,0)
      F1 Y( w) Q9 Y" C- x+ S        #画面部捕捉框
    1 x, W  I1 b. ^% J, G        cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)
    3 v7 ~% G2 o  \& B        #在捕捉框上添加匹配到的图片信息
    + T0 p# L/ s% t        cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)
    6 i- I3 ^8 [$ y' ]7 E+ f' P3 y% g& g        cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)
      C) l. U+ X3 @- \    img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))
    ) j2 e& ~. X' t! p    img = ImageTk.PhotoImage(img_Recognition)
    - y$ Q+ j& m: W7 M    lableShowImage2.config(image=img)
    - z# K" B5 l2 P+ m7 _7 S    lableShowImage2.image = img
    , Y/ A" f+ G4 G    lableShowImage2.place(x=630, y=70, width=530, height=750)
    0 q4 _8 V) U) F/ P* h
    " @$ |- Y2 i8 o" ]  S+ }if __name__ == '__main__':6 t* i/ j6 t& ^6 v
        findExistsEncodeingList(img_path)
    : ~- j9 v$ L, R0 Q2 ?* E    #生成tk界面 app即主窗口
    7 m' s% r2 T1 |    app = tk.Tk()  
    9 a/ i( t. L. l    #修改窗口titile- }# ^9 Q+ S8 j- C! I
        app.title("show pictue")  
    + y, U' Y7 Z! v3 s3 M6 [    #设置主窗口的大小和位置7 @2 A& T6 k$ g4 d
        app.geometry("1200x900+200+50")
    " @. D0 A1 j* f1 ~# D    #Entry widget which allows displaying simple text., G9 J& l$ i2 x5 C( U
        path = tk.StringVar()
    ) @2 P7 m$ y$ J6 }: P    entry = tk.Entry(app, state='readonly', text=path,width = 100)4 P" v  a  W. |9 P7 x$ P) D
        entry.pack()
    & a, V* V# _. x    #使用Label显示图片7 e- Y' p  i+ m  L4 R- H$ v+ ?8 D+ U0 \8 o
        lableShowImage = tk.Label(app)% @5 b# J* w- P/ Q6 U& x* U
        lableShowImage.pack()
    ; W' f% ?; r& g3 E     #使用Label2显示处理后的图片
    ( b1 b8 Z  T8 J& |  B) I1 J' x    lableShowImage2 = tk.Label(app)
    - Q# [4 E; Y% Y0 n8 j, f    lableShowImage2.pack()
    / v. X& g7 a7 L+ V1 p5 l" o    #选择图片的按钮
    ; I/ z/ D1 g# H4 \4 w; P% g6 _    buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)
    ) e* Z+ x- _  b6 ?+ S. y" L$ A    buttonSelImage.pack()
    4 a$ r  s! \( B; ^0 O  q    app.mainloop()8 R" @' [1 o  V: M: f  B7 @
    ' i# A% W+ T/ b
    3.说明0 e$ p* ]8 L1 ~  ]3 g$ h4 j! x
    首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。
    0 t( p# j1 \7 g/ i' Y. G
    5 T; A' F6 R' v% I( a# A; q
    ( _! t9 C& D! @6 c" E! t3 m. R( @1 Z, V
    其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片# [# y5 U0 p" a. g0 l
    $ v2 g" q" g( V2 W! A/ g
    4 s5 J; q& \& V- D- G  @! |
    * ^9 y1 b! S: M# T! }: u" U" \
    但是效果会存在色彩的失真,效果如下:) w5 x- h+ t& P& m

    3 r0 r& x( t/ V7 k2 @. V" Z0 H; k

    & [. I" J( ?1 d# p- B也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。
    ! E" ?0 m! [' d3 E) n- M* F! t! T1 @$ j; F6 C& e
    这里简单提下PIL的九种不同图片模式:
    ' l7 y) H' z% c# J+ Q
    1 n1 y5 k1 ?" F/ nmodes        描述  `0 Q! x3 ^0 a7 v8 X. U2 |  i" P
    1        1位像素,黑和白,存成8位的像素" x" {8 _' ]  q: ^* b
    L        8位像素,黑白- O0 S6 x" r( Y7 M7 ^! N9 x
    P        8位像素,使用调色板映射到任何其他模式6 M/ L) J* N" Z
    RGB        3× 8位像素,真彩
    - M% |' K4 h; O6 @' {  H% eRGBA        4×8位像素,真彩+透明通道: ?  {) h- v) b, l$ j9 |5 r6 v3 r
    CMYK        4×8位像素,颜色隔离' g0 b; [; i! @- F
    YCbCr        3×8位像素,彩色视频格式: _9 E4 E! H, x7 a: ]2 X) u* M
    I        32位整型像素8 o$ Y2 z/ U8 W' N- R- N
    F        32位浮点型像素. O: {2 \; }; N( S8 P2 U
    4.实现效果
    0 E( k% U5 _2 _* R( E: l; M: P0 p" F. J
    / x" u. G4 O; W- n+ `. K+ s
    # l6 O, c8 ]  k  ]" h/ j7 l

    2 \$ _) n3 A6 J0 |6 _ 可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。0 s. V- W( j7 w9 S) t% J' X: n
    ————————————————
      x) V% I, ]' n; \版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。( I3 Q5 y9 I# l5 u4 E7 D
    原文链接:https://blog.csdn.net/qq_17486399/article/details/1266292882 U1 m9 K. s! ]
    ! Z& a, ]8 L8 U7 t( R& O
    , g! n9 I, i3 N
    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-10 00:52 , Processed in 0.310024 second(s), 51 queries .

    回顶部