QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4013|回复: 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实现人脸捕捉与人脸识别(照片对比)$ G" w3 _- U; O, D9 ?' |0 }" B- z
    2 G7 H6 |" c' P$ z* p6 O: Z& A
    1.安装包依赖) s& D8 i( j/ ^% L% H$ y0 N+ u
    与上篇通过摄像头动态识别人脸一样,先下载好opencv-python、face-recognition,这里因为使用的是照片对比的方式,特意使用tkinter画了一个简单的GUI方便操作。
    4 u3 x9 q- @! n" F2 f4 w  D/ A8 h0 Q: j- U1 \  F5 @
    在python 3以上版本tkinter是环境自带的,所以这里不需要安装2 S( E1 E* t- G! I8 q
    & L8 u8 Q% y$ k! U
    2.代码示例3 f1 M2 L  I+ K* f
    import os) {  e# f7 x5 O$ k1 Q- k
    import cv2
    0 w8 M8 y! g4 \8 Timport numpy as np* D7 }- N% {- q( \7 k6 R4 n
    import face_recognition
    ) }( D9 v2 l; m- Z( Wimport tkinter as tk  - |5 ~2 m8 p5 h/ t/ l# Q" X
    import tkinter.filedialog+ n7 b$ h4 _& v8 y- M  Z, V+ f
    from PIL import Image,ImageTk 8 Z0 [- Q$ H3 g

    + b5 ], M* d) @1 v3 d3 HclassNames=[]
    7 k) k* v+ s3 X% W2 uimg_path='Picture'+ r. Y6 ]- N2 H9 }0 \! g% t3 B
    img_recognition_path='Recognition'
    5 h! f$ P4 C4 e( h0 X% LexistsEncodeingList=[]8 f0 T$ r8 r2 w' j2 {, C3 ~  I
    #对人脸集合进行编码进行处理
    ; k  Y9 P  A8 Hdef findEncodeings(images):. C1 X7 u3 \" o: j) B* ?
        for img in images:6 G6 ~* A; e' ]/ n; B
            #灰度处理3 F( a5 w6 N- n. T6 M$ W" b/ ~
            img=cv2.cvtColor(src=img,code=cv2.COLOR_BGR2RGB)6 @. X$ j5 G4 b5 [  ^
            #face_encodings对图片对象a_images进行编码并返回数组0位置编码结果. E7 o' K, I7 Z8 m
            encode=face_recognition.face_encodings(img)[0]
    6 u6 `4 x6 c; W. h! P' X        existsEncodeingList.append(encode)# R* C+ ], i: I, }. V
    1 n% y% F1 j) s% j# R1 R3 {4 j
    #获取当前存储的人脸编码集合
    7 V: f# m' L) Bdef findExistsEncodeingList(img_path):8 ~& T2 @0 K7 T% R" l2 g
        images=[]
    : k5 q$ y! s; E! q) v. p    #列出已经上传的所有图片; @- M" W0 z" c# j6 }; r8 n  {7 A
        imgList=os.listdir(img_path)* a" p- K: |. ?% Y: N8 j' n8 @
        #处理存储的图片得到其人脸编码
    $ i! {3 D  l8 C    for pic in imgList:
    5 [% G9 \7 S5 ?! s        img=cv2.imread('{}/{}'.format(img_path,pic))) e, z) g9 M+ w- s  L1 }% O' A
            images.append(img), x0 J% v: ?( \8 D
            classNames.append(os.path.splitext(pic)[0])/ x- Q6 O4 b7 ^) w
        findEncodeings(images)
    + H8 G9 l5 O) i3 A) @; f5 V! s) L7 n  e, g3 _: ^
    #选择并对比图片
    + y3 H3 p# s2 Kdef choosepic():! A0 W4 h" U. m0 t& v( S
        choosepath = tkinter.filedialog.askopenfilename()" J& Y8 j/ f+ R/ A+ l& e; s8 o
        path.set(choosepath)
    2 K9 u; P( ^* A; c  T    img_open = Image.open(entry.get()).resize((530,750))5 _  z; u* I) `
        img = ImageTk.PhotoImage(img_open)
    8 X: @/ u5 b  [) \    lableShowImage.config(image=img), @4 [- ?: x& S/ g
        lableShowImage.image = img
    % k& H  d$ W% r7 p4 D; q    lableShowImage.place(x=30, y=70, width=530, height=750)
    1 B  I2 X$ Y1 f    faceRecognition(choosepath)+ }: |: O- f7 u9 Q/ Y, \
    / G# _7 c3 ?8 A8 u$ D% d
    def faceRecognition(choosepath):: N5 V  I$ i& I2 {1 U& e
        frame=cv2.imread(choosepath)
    ! d( `! j6 R% O  p    frameRGB=cv2.cvtColor(src=frame,code=cv2.COLOR_BGR2RGB)/ Z4 {6 u1 Z; _2 P/ g
        #对摄像头读取的检测人脸
    " b" z3 v  X$ b  E; t  L7 w6 b: ?    facesLocate=face_recognition.face_locations(frameRGB)& ?2 R/ i0 T( b* X( _5 y1 U
        #进行特征编码' A' s: B' v, O; g4 n
        faceEncoded=face_recognition.face_encodings(frameRGB,facesLocate)
    : f9 ?# r! F& W9 Y# c* T        #遍历检测的人脸和库中读取的图片进行对比,计算其相似度, E- [3 ^0 q0 G! c6 G+ ]4 d5 J, w
        name='unknow'
    % n3 D2 r$ W0 A! i7 k' P    for (top,right, bottom,left),face_encoding in zip(facesLocate,faceEncoded):' y, f' f& d8 |5 t8 G' S# |
            #进行匹配
    ( T, [6 B% W/ d3 k% S+ d        matchs=face_recognition.compare_faces(existsEncodeingList,face_encoding)& o0 \+ r+ h+ C: ]7 j2 ]& ^& @
            #计算相似度
    , y/ a3 j# j( E* F& a. D        distance=face_recognition.face_distance(existsEncodeingList,face_encoding). J5 B$ p% x4 J3 \  x
            lab='unknow'$ v; o' k3 H$ y
            for index, item in enumerate(distance):" O1 o! E1 T0 [) A& {
               if item<0.5:
    5 A' T  s3 Y6 ^8 E8 k/ W- P                if matchs[index]:
    0 S% k3 y- q+ y% x) ?8 f. C4 w0 G( n/ l                    #得到匹配到的图片名称与相似度值; F% z' |2 a4 w8 o8 \; p8 p
                        lab='name:{}; Similarity:{}'.format(classNames[index],item)5 |' {8 A" A0 K
                        name=classNames[index]% o! w0 ]4 D0 z* K
                        break. k3 r% P5 L" `8 n& J5 l0 B
            #初始化面部捕捉框显示绿色. v; \9 {& H! N: a6 q
            color1 =(0,255,0)
    4 l* C$ v4 }! Q/ r( J3 Q        if name =='unknow':
    7 m4 c7 W5 v( L& i% v, b            #未能识别的时候显示蓝色
    0 ]- c  ?% o6 b1 X/ ?- k            color1 =(255,0,0)
    1 U. k- K5 ]9 j        #画面部捕捉框
    4 p$ a3 `! w* U        cv2.rectangle(img=frame,pt1=(left,top),pt2=(right,bottom),color=color1,thickness=3)
    9 {  P/ f3 C7 x4 f& F' Y  l: q        #在捕捉框上添加匹配到的图片信息
      x6 j% l, g) E- N) }4 Q+ p        cv2.putText(frame, lab, (left,top-8),cv2.FONT_HERSHEY_SIMPLEX, 0.7, color1, 2)
    5 W& M# [5 ]2 G: V        cv2.imwrite('{}/{}.png'.format(img_recognition_path,name),frame)
    ' C# S( m2 j2 k- `    img_Recognition = Image.open('{}/{}.png'.format(img_recognition_path,name)).resize((530,750))( B' P8 b9 [$ T8 D# j; v3 u
        img = ImageTk.PhotoImage(img_Recognition)
    5 `0 O: i5 y' s/ y/ m; f    lableShowImage2.config(image=img)! O% n8 z. ?7 c1 A) J
        lableShowImage2.image = img
    7 u. y" v5 t0 U" R/ O- O3 h- [/ o    lableShowImage2.place(x=630, y=70, width=530, height=750)
    , x7 l% I3 e5 d1 `7 I% c+ g( |5 J/ Q7 @1 N1 d7 J
    if __name__ == '__main__':
    . H" H/ u. y( D, x    findExistsEncodeingList(img_path)2 y! i, w, B* X5 L1 J7 @
        #生成tk界面 app即主窗口
    . H6 ~% i& w: f( T; f) {    app = tk.Tk()  , @  P, ?" h/ M7 }6 }6 }' O, j
        #修改窗口titile
    " H9 P8 L" q# k9 t3 }    app.title("show pictue")  
    6 l! R5 ]- ~, N; _7 k) `5 c    #设置主窗口的大小和位置# v: h$ [* F, Z; z6 ~4 ]
        app.geometry("1200x900+200+50")" b2 d- O, ?1 W: B1 l( g6 |
        #Entry widget which allows displaying simple text.4 O: t( d, m8 h3 c6 H
        path = tk.StringVar()
    2 s; H0 J) K9 A& O1 _9 ~8 q    entry = tk.Entry(app, state='readonly', text=path,width = 100)
    " R1 a! D  q3 w9 W, h; e+ Z' Q. Y    entry.pack()1 d0 W  {8 G/ N" b9 v
        #使用Label显示图片
    + U7 i8 T7 a! b, I3 Z0 \2 P2 v    lableShowImage = tk.Label(app)) V4 M# a2 E" Z+ ~) [: Z
        lableShowImage.pack(), O% t2 D* j* z4 m: ]* p! e" v
         #使用Label2显示处理后的图片. W- r  ?. ]7 e" k  d1 `9 h
        lableShowImage2 = tk.Label(app)
    + x9 V2 E9 s8 j7 E( A    lableShowImage2.pack()
    ' @  T7 n# [. C1 t7 G    #选择图片的按钮# K$ @- F/ ]4 X; w& [
        buttonSelImage = tk.Button(app, text='choose picture', command=choosepic)
    9 l3 x4 y  z2 i  z/ @    buttonSelImage.pack()
    * y; _% V1 g. Z8 f# _    app.mainloop()
    ; M  m% l, j4 ~
    # U! p' I2 W/ }) @0 |3.说明' ^+ a9 `( u. {; `8 i1 \
    首先我将需要被识别的人脸的照片预设到项目目录的Picture文件夹下,然后创建一个Recognition目录存放识别过的图片,这样方便在一个界面上展示对比结果照片。
    3 `( e  |* N' N/ f$ k* G$ z9 U2 F, x) f) ^

    ' m! W0 I. [9 D7 T1 T: |( o6 B! @% A1 r' |* v8 U, M, L0 o
    其实对比结果也可以不用存,直接将处理后的图片缓存直接展示在界面上,这里需要改一下此处的代码,将上述代码注释掉,然后换成下面的那行,通过数组直接转成图片
    " E# n( F7 R. I3 k# ~1 y$ d* N* x  D( b
    " B# ~6 g4 \* V/ f/ |

    % m9 J! ~! ^6 R4 r% U& A) l! S4 C 但是效果会存在色彩的失真,效果如下:# V0 C0 O8 T- P( ~1 E# K
    0 V7 ^' A& |3 _
    - {7 Y5 s. v3 E! V2 ?

    ! H" {# ~9 q* A- z2 @也尝试了PIL的九种不同图片模式: 1,L,P,RGB,RGBA,CMYK,YCbCr,I,F,最终效果也没达到,大概与我resize((530,750))这个有关,也没继续纠结,有兴趣的同学可以尝试一下。
    $ M$ N/ V9 W4 [4 k% n8 ~" k8 N, b% B: T4 J* a; N' L
    这里简单提下PIL的九种不同图片模式:
    3 l: q# @- w4 O- {. L3 r- N# T
    6 [0 M8 p- T% Mmodes        描述
    2 _4 l& b, o7 z. D' F% e1        1位像素,黑和白,存成8位的像素  a6 r( h4 n5 O( Y( U# ^+ e
    L        8位像素,黑白
    9 \3 T! S* R4 z- u. nP        8位像素,使用调色板映射到任何其他模式" U" y" [5 \. c0 R5 _9 g
    RGB        3× 8位像素,真彩) u$ A5 ^6 T, t8 x, a
    RGBA        4×8位像素,真彩+透明通道
    5 L0 I5 e* k( o% A5 kCMYK        4×8位像素,颜色隔离
    $ I, c: _- g$ ]7 C/ w) U/ J1 R+ jYCbCr        3×8位像素,彩色视频格式
    1 y- i0 \7 W* A. b6 v- n6 EI        32位整型像素
    3 V8 a6 o4 U9 G  X2 EF        32位浮点型像素
    . ]8 f+ y" Y; i4.实现效果
    4 m  X) W7 F$ Y& |1 H$ @% X8 W/ i" \# l2 U- p: |
    9 H2 y( n: T5 y( ?5 i
    $ C( j" T# Y% m

    ' }4 |" s* s$ k+ e3 R3 _- ?, Q 可以实现简单的人脸对比,Similarity代表相似度值,值越小代表人脸与预设的图片越相似。
      D* F% ]9 w; M————————————————
    + m4 C6 u: h* s7 C版权声明:本文为CSDN博主「物联网_咸鱼」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。. R- {. a; V2 D. j
    原文链接:https://blog.csdn.net/qq_17486399/article/details/126629288
    ( Y* C; l/ _6 d. T1 t% S$ w% m4 Q3 t. |3 M

    . w4 \* J8 z* O% ]6 u
    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, 2025-12-25 04:21 , Processed in 0.771322 second(s), 50 queries .

    回顶部