树莓派3B+ 人脸识别(OpenCV)

2023-05-16

树莓派3B+ 人脸识别(OpenCV)


相信大家都看了前面的OpenCV安装人脸检测教程,已经跃跃欲试,想要进行人脸识别了,现在我们正式进入重头戏——人脸识别 的教程。
注意:该教程面向python2.7+OpenCV2.4.9(官方源)
其它版本需进行一些小的修改,文中会具体注明。

1.生成人脸识别数据

目录结构
./data 数据根目录
./data/generate 自动生成的人脸数据
./data/datamap.csv 人脸数据对应数据
./data/Mengcheng 人物一文件夹
./data/Kaixin 人物二文件夹
./data/Mengying 人物三文件夹
(这里三个人物可自行修改,文件夹为人物名,里面存放图片)

dir

// python脚本,请保存为genrate.py
#!/usr/bin/env python
#coding=utf-8
import cv2
import os  
import sys

face_cascade=cv2.CascadeClassifier('/usr/share/opencv/haarcascades/haarcascade_frontalface_default.xml')

def makedir(path):
    path=path.strip().rstrip('/')
    if os.path.exists(path) is False:
        os.makedirs( path );

def generate(root_argv,dirname):
    subject_dir_path = os.path.join(root_argv, dirname)
    print 'seek:'+subject_dir_path
    count=0
    for filename in os.listdir(subject_dir_path): 
        if filename == ".directory":
            continue
        imgPath = os.path.join(subject_dir_path, filename)
        try:
            print 'read:'+imgPath
            img = cv2.imread(imgPath)
            gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
            outdir=os.path.join(root_argv,'generate',dirname)
            makedir(outdir)
            faces=face_cascade.detectMultiScale(gray,1.3,5)
            for x,y,w,h in faces:
                f=cv2.resize(gray[y:y+h,x:x+w],(200,200))
                outPath=os.path.join(root_argv,'generate',dirname,'%s.pgm' % str(count))
                print 'write:'+ outPath
                cv2.imwrite(outPath, f)
                count+=1

        except:
            pass


if __name__ == '__main__':
    if len(sys.argv)==1:
        print ("USAGE: generate.py <人脸图片存放路径>")
        exit(0)

    root_argv=sys.argv[1]
    for dirname in os.listdir(root_argv):
        file_path = os.path.join(root_argv, dirname)  
        if os.path.isdir(file_path): 
            if dirname == 'generate':
                continue
            generate(root_argv,dirname)

在控制台执行python generate.py ./data即可自动生成人脸识别数据
生成后,请自行打开./data/generate/下生成人脸数据是否正常,如果不正常的,请清理掉,防止后续有干扰。如图:

这里写图片描述

2.生成人脸数据对应表

人脸数据生成了,还得有一个人物<->名称映射表,让机器知道人脸数据对应那个人物。

// python脚本,请保存为create_csv.py
#!/usr/bin/env python
#coding=utf-8
import sys
import os.path
#import Image
if __name__ == '__main__':
    if len(sys.argv) != 2:
        print "usage: create_csv.py <生成的人脸数据路径>"
        sys.exit(0)

    BASE_PATH=sys.argv[1]
    SEPARATOR=";"
    label = 0
    for dirpath, dirnames, filenames in os.walk(BASE_PATH): 
        for subdirname in dirnames:
            subject_path = os.path.join(dirpath, subdirname) 
            #print subject_path
            for filename in os.listdir(subject_path):
                image_filename = subject_path + "/"+ filename 
                #print(image_filename) 
                #img=Image.open(image_filename)
                ##  img=img.resize((92,112))
                #img.show()
                abs_path = "%s/%s" % (subject_path, filename) 
                print("%s%s%d"%(abs_path,SEPARATOR, label))
                # print("%s"%(abs_path)) 
            label = label + 1

然后执行python create_csv.py ./data/generate/ > ./data/datamap.csv
打开生成的datamap.csv文件,检查对应关系(如图所示):

datamap.csv

这样,人脸数据就准备好了。

3.人脸识别

使用样图,使用树莓派摄像头获取图片。

// python脚本,请保存为facerec.py
#!/usr/bin/env python
#coding=utf-8
### Imports ###################################################################

import multiprocessing as mp
import cv2
import os
import sys
import time
import numpy as np


### Setup #####################################################################

resX = 640
resY = 480

# The face cascade file to be used
face_cascade = cv2.CascadeClassifier('/usr/share/opencv/lbpcascades/lbpcascade_frontalface.xml')

#三种识别算法
#model = cv2.createEigenFaceRecognizer()
model = cv2.createFisherFaceRecognizer()
#model = cv2.createLBPHFaceRecognizer()

t_start = time.time()
fps = 0


### Helper Functions ##########################################################

def normalize(X, low, high, dtype=None):
    """Normalizes a given array in X to a value between low and high."""
    X = np.asarray(X)
    minX, maxX = np.min(X), np.max(X)
    # normalize to [0...1].
    X = X - float(minX)
    X = X / float((maxX - minX))
    # scale to [low...high].
    X = X * (high-low)
    X = X + low
    if dtype is None:
        return np.asarray(X)
    return np.asarray(X, dtype=dtype)


def load_images(path, sz=None):
    c = 0
    X,y = [], []
    for dirname, dirnames, filenames in os.walk(path):
        for subdirname in dirnames:
            subject_path = os.path.join(dirname, subdirname)
            for filename in os.listdir(subject_path):
                try:
                    filepath = os.path.join(subject_path, filename)
                    if os.path.isdir(filepath):
                        continue
                    img = cv2.imread(os.path.join(subject_path, filename), cv2.IMREAD_GRAYSCALE)
                    if (img is None):
                        print ("image " + filepath + " is none")
                    else:
                        print (filepath)
                    # resize to given size (if given)
                    if (sz is not None):
                        img = cv2.resize(img, (200, 200))

                    X.append(np.asarray(img, dtype=np.uint8))
                    y.append(c)
                # except IOError, (errno, strerror):
                #     print ("I/O error({0}): {1}".format(errno, strerror))
                except:
                    print ("Unexpected error:", sys.exc_info()[0])
                    raise
            print (c)
            c = c+1


    print (y)
    return [X,y]

def get_faces( img ):

    gray = cv2.cvtColor( img, cv2.COLOR_BGR2GRAY )
    faces = face_cascade.detectMultiScale(gray, 1.3, 5)

    return faces, img, gray

def draw_frame( faces, img, gray ):

    global xdeg
    global ydeg
    global fps
    global time_t

    # Draw a rectangle around every face
    for ( x, y, w, h ) in faces:

        cv2.rectangle( img, ( x, y ),( x + w, y + h ), ( 200, 255, 0 ), 2 )
        #-----rec-face
        roi = gray[x:x+w, y:y+h]
        try:
            roi = cv2.resize(roi, (200, 200), interpolation=cv2.INTER_LINEAR)
            params = model.predict(roi)
            sign=("%s %.2f" % (names[params[0]], params[1]))
            cv2.putText(img, sign, (x, y-2), cv2.FONT_HERSHEY_SIMPLEX, 0.5, ( 0, 0, 255 ), 2 )
            if (params[0] == 0):
                cv2.imwrite('face_rec.jpg', img)
        except:
            continue


    # Calculate and show the FPS
    fps = fps + 1
    sfps = fps / (time.time() - t_start)
    cv2.putText(img, "FPS : " + str( int( sfps ) ), ( 10, 15 ), cv2.FONT_HERSHEY_SIMPLEX, 0.5, ( 0, 0, 255 ), 2 )

    cv2.imshow( "recognize-face", img )


### Main ######################################################################

if __name__ == '__main__':

    camera = cv2.VideoCapture(0)
    camera.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH,resX)  
    camera.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT,resY) 

    pool = mp.Pool( processes=4 )

    # -----------init-rec----------
    # 人名要与datamap.csv里面的对应,不要弄错了顺序
    names = ['Mengying', 'Kaixin', 'Mengcheng']
    if len(sys.argv) < 2:
        print ("USAGE: facerec.py <人脸数据存放路径> [<数据对应表>]")
        sys.exit()

    [X,y] = load_images(sys.argv[1])
    y = np.asarray(y, dtype=np.int32)

    if len(sys.argv) == 3:
        out_dir = sys.argv[2]

    model.train(np.asarray(X), np.asarray(y))
    # ------init finish---------

    read, img = camera.read()
    pr1 = pool.apply_async( get_faces, [ img ] )   
    read, img = camera.read()
    pr2 = pool.apply_async( get_faces, [ img ] )  
    read, img = camera.read() 
    pr3 = pool.apply_async( get_faces, [ img ] )   
    read, img = camera.read()
    pr4 = pool.apply_async( get_faces, [ img ] )    

    fcount = 1
    while (True):
        read, img = camera.read()

        if   fcount == 1:
            pr1 = pool.apply_async( get_faces, [ img ] )
            faces, img, gray=pr2.get()
            draw_frame( faces, img, gray )

        elif fcount == 2:
            pr2 = pool.apply_async( get_faces, [ img ] )
            faces, img, gray=pr3.get()
            draw_frame( faces, img, gray )

        elif fcount == 3:
            pr3 = pool.apply_async( get_faces, [ img ] )
            faces, img, gray=pr4.get()
            draw_frame( faces, img, gray )

        elif fcount == 4:
            pr4 = pool.apply_async( get_faces, [ img ] )
            faces, img, gray=pr1.get()
            draw_frame( faces, img, gray )
            fcount = 0

        fcount += 1

        if cv2.waitKey(1000 // 12) & 0xff == ord("q"):
            break

    camera.release()
    cv2.destroyAllWindows()

注意:这里对于OpenCV3的版本需要修改如下内容:
cv2.createEigenFaceRecognizer()
—>cv2.face.createEigenFaceRecognizer()
cv2.rectangle()
—>img=cv2.rectangle()


然后执行python facerec.py ./data/generate ./data/datamap.csv,此时,摄像头会自动打开,在显示屏上可以看到画面,如图:

result

如果想测试得更理想,应选择脸型差别比较大的来测试,其次是素材高清一些,摄像头成像清晰一些。

4.扩展资料

对于OpenCV有三种人脸识别方法,它们分别基于三种不同的算法:Eigenfaces、Fisherfaces和Local Binary Pattern Histogram(LBPH)。

首先,所有的方法都有类似的过积,即都使用了分好类的训练数据集(人脸数据库,每 个人都有很多样本)来进行“训练”,对图像或视频中检测到的人脸进行分析,并从两方面来确定:是否识别到目标,目标真正被识别到的置信度的度量,这也称为置信度评分。

  • Eigenfaces是通过PCA来处理的。PCA是计算机视觉中提到最多的数学概。PCA的本质是识别某个训练集上(比如人脸数据库)的主成分,并计算出训练集(图像或帧中检测到的人脸)相对于数据库的发散程度,并输出一个值。该值越小,表明人脸数据库和检测到的人脸之间差别就越小;0值表示完全匹配。

  • Fisherfaces是从PCA衍生并发展起来的概念,它采用更复杂的逻辑。尽管计算更加密集,但比Eigenfaces更容易得到准确的效果。

  • LBPH粗略地(在非常高的层次上)将检测到的人脸分成小单元,并将其与模型中的对应单元进行比较,对每个区域的匹配值产生一个直方图。由于这种方法的灵活性.LBPH是唯一允许模型样本人脸和检测到的人脸在形状、大小上可以不同的人脸识别算法。个人认为这是最准确的算法,但是每个算法都有其长处和缺点。

5.扩展书籍

看较多网友对此文章有较多疑问,但我也没有较深入去研究具体原理。故无法对你们的提问作出准确的解答,在此推荐一本书给大家,相信能化解你们的疑问![本文章代码也有部分来自此书]
OpenCV 3计算机视觉 Python语言实现(第二版)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

树莓派3B+ 人脸识别(OpenCV) 的相关文章

  • 如何使图像呈现出陈旧、布满灰尘、颜色褪色的外观?

    我有旧画的图像 这些画很旧 布满灰尘 颜色褪色 如图所示here https i stack imgur com xuoEF jpg 如何赋予任何图像这种 旧 外观 我找不到任何过滤器或 openCV 函数来实现这种类型的外观 EDIT 我
  • 收据褪色部分可以恢复吗?

    我有一些包含一些扫描收据的文件 我需要使用 OCR 从中提取文本 由于收据上打印的文字在一段时间后会褪色 导致收据上的某些文字不清晰 影响OCR结果 褪色单词的一些示例 有什么方法可以恢复褪色的部分 以便提高 OCR 结果吗 我在OpenC
  • 在 Python 3.5 64 位上通过 pip 安装 OpenCV

    我尝试安装 OpenCV 但找不到任何合适的 pip 软件包 我决定上网查找有关如何安装它的官方文档 并发现this https opencv python tutroals readthedocs io en latest py tuto
  • 使用 openCV 和 python 检测物体

    我正在尝试使用 OpenCV 和 Python 检测下图中的白点 我尝试使用函数 cv2 HoughCircles 但没有成功 我需要使用不同的方法吗 这是我的代码 import cv2 cv import numpy as np impo
  • opencv中矩阵的超快中值(与matlab一样快)

    我正在 openCV 中编写一些代码 想要找到一个非常大的矩阵数组 单通道灰度 浮点数 的中值 我尝试了几种方法 例如对数组进行排序 使用 std sort 和选择中间条目 但与 matlab 中的中值函数相比 它非常慢 准确地说 在 ma
  • 使用 opencv warpPerspective() 生成道路的自上而下视图

    我正在尝试实施逆透视映射计算与道路上另一辆车的距离 我知道在应用该函数之前我需要生成一个包含源点和目标点的变换矩阵warpPerspective 但我不知道如何计算目的地点 我在这个论坛和其他网站中搜索 但无法将第一张图片转换为第二张图片
  • 如何在给定目标大小的情况下在 python 中调整图像大小,同时保留纵横比?

    首先 我觉得这是一个愚蠢的问题 对此感到抱歉 目前 我发现计算最佳缩放因子 目标像素数的最佳宽度和高度 同时保留纵横比 的最准确方法是迭代并选择最佳缩放因子 但是必须有更好的方法来做到这一点 一个例子 import cv2 numpy as
  • 如何删除树莓派的相机预览

    我在我的 raspberryPi 上安装了 SimpleCv 并安装了用于使用相机板的驱动程序 uv4l 驱动程序 现在我想使用它 当我在 simpleCV shell Camera 0 getImage save foo jpg 上键入时
  • OpenCV的拼接模块可以拼接平行运动相机拍摄的图像吗?

    我想知道是否缝合 http docs opencv org modules stitching doc stitching html http docs opencv org modules stitching doc stitching
  • 如何使用 Python 将我的 GoPro Hero 4 相机直播连接到 openCV?

    我在尝试从我的新 GoPro Hero 4 相机捕获实时流并使用 openCV 对其进行一些图像处理时遇到麻烦 这是我的试用 创建的窗口上没有显示任何内容 import cv2 import argparse import time imp
  • 如何将 mat 转换为 array2d

    我为dlib http dlib net face landmark detection ex cpp html那里的面部地标代码使用 array2d 来获取图像 但我喜欢使用 Mat 读取图像并转换为 array2d 因为 dlib 仅支
  • OpenCV 仅围绕大轮廓绘制矩形?

    第一次发帖 希望我以正确的方式放置代码 我正在尝试检测和计算视频中的车辆 因此 如果您查看下面的代码 我会在阈值处理和膨胀后找到图像的轮廓 然后我使用 drawContours 和矩形在检测到的轮廓周围绘制一个框 我试图在 drawCont
  • BASH 脚本编译多个 C++ 文件 - OpenCV

    请参见在C 和OpenCV中调用其他文件中的函数 https stackoverflow com questions 24442836 call functions in other files in c and opencv 对于最初的问
  • 从图像坐标获取对象的世界坐标

    I have been following this http docs opencv org modules calib3d doc camera calibration and 3d reconstruction html docume
  • 如何使用 python、openCV 计算图像中的行数

    我想数纸张 所以我正在考虑使用线条检测 我尝试过一些方法 例如Canny HoughLines and FLD 但我只得到处理过的照片 我不知道如何计算 有一些小线段就是我们想要的线 我用过len lines or len contours
  • OpenCV 2.4.3 中的阴影去除

    我正在使用 OpenCV 2 4 3 最新版本 使用内置的视频流检测前景GMG http docs opencv org modules gpu doc video html highlight gmg gpu 3a 3aGMG GPU算法
  • 如何使用 Python 裁剪图像中的矩形

    谁能给我关于如何裁剪两个矩形框并保存它的建议 我已经尝试过这段代码 但效果不佳 import cv2 import numpy as np Run the code with the image name keep pressing spa
  • 在 Python 中将 OpenCV 帧流式传输为 HTML

    我正在尝试从 opencv Pyt hon 中的 URL 读取视频 然后逐帧处理它 然后将其发送到 HTML 页面 But I am only getting the first frame after that the program g
  • cv2.drawContours() - 取消填充字符内的圆圈(Python,OpenCV)

    根据 Silencer的建议 我使用了他发布的代码here https stackoverflow com questions 48244328 copy shape to blank canvas opencv python 482465
  • 二值图像中骨架上两点之间的最短路径

    我有一个二进制图像 其中包含图像的一个像素宽度骨架 您可能基本上知道 在这个二值图像中 我在骨架上有 1 在其他地方有 0 如何找到骨架上两个非零元素之间的最短距离 路径也应该在骨架本身上 我想使用 A star 算法的 C 实现 我找到了

随机推荐