QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4207|回复: 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 K3 ]# }2 H4 E9 e9 w$ T
    8 a& x2 Q* V+ p
    1.安装包依赖
    1 a' P/ z0 F% Q0 j# Q' J5 U& e与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。
    2 {+ \: N# N9 @5 e# `0 L; f" G. z. R2 ^* F9 _0 {" ?6 e" @5 \
    在python 3以上版本tkinter是环境自带的,所以这里不需要安装9 _, m; j% r. N$ c

    $ |5 r8 a1 b' B8 q; O0 H2.代码示例
    0 ]/ Q. C9 j0 Q: x$ b0 F2 mimport os0 A/ i) v0 C6 m) B
    import cv2
    * d3 e- r+ L" C: R* }; u$ Timport numpy as np- c! I* J! p' A( c8 x$ t0 I
    import face_recognition* `6 s6 Q9 R8 m" K2 c
    import tkinter as tk  / W; ^! U' d8 I
    import tkinter.filedialog
    $ d/ u9 R/ N. z+ O9 ?9 O' Bfrom PIL import Image,ImageTk + N' g* `# h4 [# x! w  ?3 ?

    1 `5 ]. H5 ^, T( ^# XclassNames=[]
    , I9 E+ y! s, t/ w3 L2 j) |' C3 nimg_path='Picture'' g3 D" Z. }- G% s0 \, W
    img_recognition_path='Recognition'
    % o, g0 n' o; PexistsEncodeingList=[]
    4 C- B" P. W" Z$ N5 z4 b- i- ?% X#对人脸集合进行编码进行处理! g# R  b0 @( e# S5 e1 i/ H
    def findEncodeings(images):
    4 t' K4 l. E( y2 h0 H' n    for img in images:
    4 L) s. h/ P8 a/ f  x$ f1 P% h) w        #灰度处理$ o5 S3 M" k' l
            img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)
    * e  D- e  `/ o' h7 k- |" D        #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果3 P. P, `& H  ~, t2 b
            encode=face_recognition.face_encodings(img)[0]8 n5 j" P# n  b& p2 e2 y& R
            existsEncodeingList.append(encode)
    & q  v6 I3 A7 M8 J: W& g8 ^& r+ j4 e
    % v1 D- b3 i. k9 v#获取当前存储的人脸编码集合
    0 C2 C; |3 V! J5 ~" p' f* ~def findExistsEncodeingList(img_path):
    1 K8 V% P  h& C. `. |3 i1 J* B    images=[]/ G! ~! M: x# Q
        #列出已经上传的所有图片& R. ~( Y0 f" H/ B- ]' v
        imgList=os.listdir(img_path)
    0 Z: l+ s( L' i; _1 `    #处理存储的图片得到其人脸编码) B; f6 O; u1 c7 c; d- ~
        for pic in imgList:
    . f' @/ {; {# N+ {; Y9 u( d, T        img=cv2.imread('{}/{}'.format(img_path,pic))! x* w; y3 a2 o( N/ C
            images.append(img)+ D0 s# P. `' }0 X3 k9 U% ~
            classNames.append(os.path.splitext(pic)[0])
    8 E! C  \4 i2 D5 F6 x    findEncodeings(images)) s+ @! j+ Y" `# l. ^3 x; X8 p
    6 j  |5 |+ Y9 x
    #选择并对比图片
    4 H. Z3 S8 S5 i% ^6 wdef choosepic():- w  V, W* Q' Z( h( T7 \
        choosepath = tkinter.filedialog.askopenfilename()8 E: N2 u, E/ F3 h9 y
        path.set(choosepath)
    " U$ m* w' S0 f+ S  v( J& e    img_open = Image.open(entry.get()).resize((530,750))
    4 k! n' E. f/ m" `4 ~0 M    img = ImageTk.PhotoImage(img_open)
    ( r+ q0 q+ [, l+ ?7 X% S3 H    lableShowImage.config(image=img)
    $ C, d) S; D' X$ V. d    lableShowImage.image = img
    ; V* c& `4 ~7 K* G1 G! w) U! b    lableShowImage.place(x=30, y=70, width=530, height=750)! _( p2 h$ j( F3 Q: B! m- \1 a
        faceRecognition(choosepath)
    , g8 L; m4 u7 ]! s9 u- Z! l  a4 V" N0 k* d
    def faceRecognition(choosepath):
    4 h2 Y/ G2 V3 H2 N7 F7 t    frame=cv2.imread(choosepath)
    - w4 Y7 d% D) I% `    frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)
    + U7 Q1 C1 w8 v$ f3 d    #对摄像头读取的检测人脸
    0 x. T3 J7 g5 ~% ~+ ]  A, `% _: W) }    facesLocate=face_recognition.face_locations(frameRGB)
    / V  Y0 u; [) ]* d) q+ R% k    #进行特征编码6 J3 \0 Y- w+ Q4 C3 M
        faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)1 \4 _% r/ f8 b, Z0 n4 c
            #遍历检测的人脸和库中读取的图片进行对比,计算其相似度9 y! N$ j% t; U2 T$ I" o
        name='unknow') }1 P5 M- j' A
        for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):
    ) H4 z* ?9 j, `, L2 |3 F8 I2 ]" r% H        #进行匹配
    # Q: R. D" z3 s8 l% I        matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)
    ' G% q2 [/ ~7 H, B9 Q8 z% \2 Y/ I        #计算相似度
    8 Z0 A& V% T5 [+ K2 R        distance=face_recognition.face_distance(existsEncodeingList,face_encoding)# _4 T+ J! d  K  E8 Y6 Q$ L
            lab='unknow'$ b- y5 m2 A" {" B- ]3 B
            for index, item in enumerate(distance):
    5 [0 |/ e0 w) p9 |7 W           if item<0.5:% ?* V( b7 S0 S6 U- Q
                    if matchs[index]:
    ) h- k' k5 J' L/ V. j& P                    #得到匹配到的图片名称与相似度值6 \- c4 o$ w- x4 i2 K
                        lab='name:{}; Similarity:{}'.format(classNames[index],item)
    $ E! K( _  \/ v- y                    name=classNames[index]
    9 n) Y3 r+ R# G! s3 M% y                    break
    2 x. F, a9 v" w, d& y( E/ q$ {        #初始化面部捕捉框显示绿色: u7 i! ?7 a$ G
            color1 =(0,255,0)
      P5 n, k5 k- t, k, S        if name =='unknow':
    * r( U9 U6 F5 m$ ~- F' A+ Z% L5 l            #未能识别的时候显示蓝色
    : p/ O3 j+ _4 u7 H3 `$ ?            color1 =(255,0,0)
    + ]6 x% T% F9 Z: S        #画面部捕捉框
    7 [! ?6 a- ]0 U        cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)
    : \8 ~+ w: h8 }  J7 y        #在捕捉框上添加匹配到的图片信息; @4 j! t9 z1 l2 d7 E
            cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)9 F6 _3 H& H9 k6 L  P3 B/ D
            cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)- Q$ G0 `) r2 _# B! C
        img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))
      A2 a, l4 \: C" p) O, W' q    img = ImageTk.PhotoImage(img_Recognition)+ v% D( W2 {  M3 B- J$ W
        lableShowImage2.config(image=img)$ _7 Y9 Q3 i. c
        lableShowImage2.image = img
    4 u* D( a) J) a, W3 {    lableShowImage2.place(x=630, y=70, width=530, height=750)+ f- l* I) W. {! |/ Y* H# [  V7 [

    6 ?' f  \/ B2 Y% A5 pif __name__ == '__main__':
    2 M- N2 l% d5 w& ~" \0 N, I    findExistsEncodeingList(img_path)8 s+ h. d0 V* C% X* n$ W4 G: k! @
        #生成tk界面 app即主窗口
    , u: c) ]5 k: X0 E2 o9 y) ]    app = tk.Tk()  * b7 j5 _5 ]  i# ?2 ~- Z
        #修改窗口titile
    4 U0 H) A% K# y( j, `2 s7 V    app.title("show pictue")  % ~+ X; u: m0 S& l+ W& o; E
        #设置主窗口的大小和位置8 r" d% _1 t" ^
        app.geometry("1200x900+200+50")  D  M* B2 W! z- x
        #Entry widget which allows displaying simple text.6 o$ W1 w8 B8 T$ ]0 m2 `4 ^* @
        path = tk.StringVar()/ k$ \6 d2 j9 ?/ y9 h# x+ j" ]
        entry = tk.Entry(app, state='readonly', text=path,width = 100)
    % f% W: M, L' ~8 N( I$ N    entry.pack()3 z5 P' F( ?2 |
        #使用Label显示图片) G6 b2 j" I* S7 M- {: R1 G
        lableShowImage = tk.Label(app)& \: {. D; G/ m" _; i" w+ z* H' z% z
        lableShowImage.pack()  V, d0 X( C' T& Q( e
         #使用Label2显示处理后的图片% Z! U' d; v; v1 a2 F8 M
        lableShowImage2 = tk.Label(app): A* \% M3 z3 `2 N
        lableShowImage2.pack()$ g# E; `) ~2 Z2 u+ X
        #选择图片的按钮  U2 m$ ?8 ?  G. b" c% |1 p
        buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)
    - O& s3 e) h$ E" t    buttonSelImage.pack()) ]3 @; g' L" H
        app.mainloop()5 S: Q: w* y% u, o5 i( a$ H
    9 U. O7 `/ ^. u; M+ Q8 G" f$ N
    3.说明/ A" ]% l/ I& u) U8 A
    首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。4 N$ h! }3 k$ k3 T
    1 B5 x2 E) S+ Z! ~

    - y0 m3 D& `- H/ B& `! O
    6 i+ F  w( N: Z0 b( }6 F1 i( h 其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片
    $ B( N) U" c# I# m. C7 F9 d0 K5 J* H% l3 ?0 y2 `8 q; ~! C; S1 t6 k

    ( e% K. H! M% v1 S+ [" V4 q8 U" S: R4 N0 W6 P
    但是效果会存在色彩的失真,效果如下:
    : n$ _6 ~7 D2 ]# t# Y" v# g. M3 C" I
    . C2 F# `9 l0 Q, O
    % j; w1 U0 `4 F8 n1 ?: S+ i
    6 ?2 ^$ l/ G3 c3 J" x也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。! S1 h3 Q, Q$ I# g+ D9 C* a: u
    4 y5 f/ {; p1 b8 ^: ~7 Q6 y0 h
    这里简单提下PIL的九种不同图片模式:. I4 n+ ]6 V/ o; d4 l1 \8 v; ~

    : c) l0 t& C: r% p* @; \modes        描述% |; E/ }! G3 N8 @
    1        1位像素,黑和白,存成8位的像素( R7 w* h5 i6 q; D! {
    L        8位像素,黑白, N7 ]0 u6 a2 W* u4 F
    P        8位像素,使用调色板映射到任何其他模式
    , ]; i+ f$ U. r. a4 ]RGB        3× 8位像素,真彩
    8 r' i' e/ n4 X% a2 [RGBA        4×8位像素,真彩+透明通道  N* j( _" n# _( E& u; v7 `
    CMYK        4×8位像素,颜色隔离' q* P  k$ E8 O& ?0 Q, F; H
    YCbCr        3×8位像素,彩色视频格式
    5 H/ W* q2 `4 T! f( U3 HI        32位整型像素
    ) G' s9 S* s5 B1 fF        32位浮点型像素5 S" M9 z9 n6 G3 U& T
    4.实现效果" C; N3 ~+ ^# y" l+ k0 l
    ! ]! F5 }; j# ]2 o, x* p/ W. K# \
    / v' d# X6 N7 Q  K* e+ m8 d

    8 @9 [" q: a  t- ?/ g% A
    4 l% ?2 E* z+ e3 Y 可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。! ?5 m0 k1 N% E
    ————————————————$ D8 y  S/ o* Z8 |
    版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    1 p3 o. }. c2 F8 z( c% }( A6 ~. f原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288
    $ ]7 u+ ?9 n. t) s2 M9 T* Q( q/ `( y3 D) W% @! x0 E2 g% Q* L# O
      W  k) @- V. z- p1 z: {- _
    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-8-24 04:26 , Processed in 0.495941 second(s), 51 queries .

    回顶部