人脸检测与跟踪

文章目录

  • 实验目的

  • 算法原理概述

  • 实验内容

  • 结果分析

  • 存在不足

  • 总代码

  • 总结


实验目的

        图像处理(image processing),用计算机对图像进行分析,以达到所需结果的技术。图像处理将会是物联网产业发展的重要支柱之一。

        本实验旨在让学生加深本课程中图像预处理、人脸检测、后处理等重要的知识点的理解和实践,并实现针对视频中的人脸检测和追逐算法,最终生成标注后的视频/流媒体。


算法原理概述

        利用OPENCV中训练好的人脸检测模型haarcascade_frontalface_alt2.xml进行人脸检测,将其获得的第一个人脸方框作为目标跟踪的ROI区域;

ROI区域转化到HSV空间中,并计算出ROI区域中的直方图;

对视频逐帧进行以下处理:

(1)对图片进行高斯滤波降噪;

(2)将图片转化到HSV空间中;

(3)利用ROI区域的直方图对图片进行反向投影;

(4)利用OPENCV均值迁移meanShift() 计算出目标区域,并在图片中进行标定;

(5)利用OPENCV中训练好的人脸检测模型haarcascade_frontalface_alt2.xml进行人脸检测,并在图中进行标定出人脸方框;

实验内容

一、问题描述 

        从摄像头中获得视频流,检测出视频中出现的人脸,对其进行追踪,生成追踪轨迹并进行标注输出;

二、算法步骤

目标跟踪ROI区域获取:利用OPENCV中自带的人脸检测器,获得第一个检测出的人脸区域,作为目标ROI区域;

1.while flag:
2.    ref, frame = capture.read()
3.    gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
4.    faceRects = classifier.detectMultiScale(gray)
5.    # 读取到的人脸
6.    if len(faceRects) > 0:
7.        flag = False
8.        for faceRect in faceRects:
9.            x_roi, y_roi, w_roi, h_roi = faceRect
10.            break

高斯滤波:为了减小噪声对于目标追踪与人脸检测影响,在进行追踪与检测前先进行高斯滤波处理,削弱噪声影响;

1.    frame = cv.GaussianBlur(frame, (5, 5), 0)

将ROI区域转化到HSV色彩空间中:为了计算出ROI区域的直方图与直方图的反射投影,先得将ROI区域的色彩空间由RGBHSV进行转化;

1.hsv_roi = cv.cvtColor(roi, cv.COLOR_BGR2HSV)

计算出ROI区域内直方图:获取ROI图像中HSV通道的高低值,通过inRange() 提取出来ROI区域内容作为掩模 mask,利用该掩模计算出ROI的直方图;

1.low = 15
2.high = 255
3.mask = cv.inRange(hsv_roi, (low, low, low), (high, high, high))
4.cv.imshow('b', mask)
5.#cv.waitKey(1000)
6.roi_hist = cv.calcHist([hsv_roi], [0], mask, [180], [0, 180])
7.cv.normalize(roi_hist, roi_hist, 0, 255, cv.NORM_MINMAX)
8.term_crit = (cv.TERM_CRITERIA_EPS | cv.TERM_CRITERIA_COUNT, 10, 1)

利用ROI区域直方图进行反向投影:将图片转化到HSV色彩空间中,利用ROI区域的直方图,对图片进行反向投影;

1.hsv = cv.cvtColor(frame, cv.COLOR_BGR2HSV)
2.# 直方图反向投影
3.dst = cv.calcBackProject([hsv], [0], roi_hist, [0, 180], 1)

均值迁移更新目标区域:利用OPENCV中自带的均值迁移meanShift(),进行目标区域更新;

1.ret, track_window = cv.meanShift(dst, track_window, term_crit)
2.# 绘制窗口
3.x, y, w, h = track_window
4.cv.rectangle(frame, (x, y), (x + w , y + h+100), 255, 2)

人脸检测:利用OPENCV中自带的人脸检测器,将图片中所有人脸检测出来,并在图片中进行标定;

1.faceRects = classifier.detectMultiScale(hsv)
2.f len(faceRects) > 0:
3.     for faceRect in faceRects:
4.         x, y, w, h = faceRect
5.         if w > 100:
6.         #标定出人脸方框
7.              cv.rectangle(frame, (x, y), (x + w, y + h), color, 2)

结果分析

目标跟踪ROI区域获取:获得第一个检测出来的人脸区域;

人脸检测与跟踪_第1张图片人脸检测与跟踪_第2张图片

得到ROI区域掩模并计算出掩模内的直方图:设定阈值low、high,对ROI区域内进行二值化处理,在low与high之间的像素设置为255,不在之间的设为0;并计算出掩模内的直方图;

 人脸检测与跟踪_第3张图片人脸检测与跟踪_第4张图片

 

 利用均值移动进行目标跟踪:将图片转移到HSV空间中,利用ROI区域内直方图,对图片进行反向投影,并利用OPENCV中自带的meanShift()进行目标区域更新;

人脸检测与跟踪_第5张图片

 

 人脸检测:利用OPENCV中自带人脸检测器进行图片人脸检测;

存在不足

        当存在一些干扰时,如戴上口罩,或者存在一些非人物体时,会导致人脸检测失效,这是由于OPENCV自带的人脸检测精度不高,因此我们可以训练一个精度更高的人脸检测模型;

人脸检测与跟踪_第6张图片

 

        均值迁移对于目标跟踪也存在着一些问题:一旦目标脱离出目标框,只有当目标重新出现在框内目标框才会重新跟踪,运动过快的目标也会导致目标框脱离;

人脸检测与跟踪_第7张图片人脸检测与跟踪_第8张图片人脸检测与跟踪_第9张图片

 

        目标检测的关键在于: ROI区域内对于目标物体特征提取的效果;在本实验体现为掩模的制定,这个二值化处理的双阈值的设定,容易受到环境亮度的影响,因此可以寻找一种更好的特征提取的办法进行改进;

总代码

import cv2 as cv

CADES_PATH = 'D:/computer_view_exercise1/venv\Lib/site-packages/cv2/data/haarcascade_frontalface_alt2.xml'

'''
face_test:将摄像头人脸检测,并进行标注
'''


def face_test():
    color = (0, 255, 0)
    capture = cv.VideoCapture(0, cv.CAP_DSHOW)
    classifier = cv.CascadeClassifier(CADES_PATH)
    flag = True
    #存检测点的列表,大小为M
    points = []
    M = 15

    # 读取ROI区域的坐标
    while flag:
        ref, frame = capture.read()
        gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
        faceRects = classifier.detectMultiScale(gray)
        # 读取到的人脸
        if len(faceRects) > 0:
            flag = False
            for faceRect in faceRects:
                x_roi, y_roi, w_roi, h_roi = faceRect
                break

    roi = frame[y_roi:y_roi+h_roi, x_roi:x_roi+w_roi]
    #cv.imshow('a', roi)
    #cv.waitKey(1000)
    hsv_roi = cv.cvtColor(roi, cv.COLOR_BGR2HSV)
    cv.imshow('m', hsv_roi)
    track_window = (x_roi, y_roi, w_roi, h_roi)
    #设置阈值
    low = 16
    high = 95
    mask = cv.inRange(hsv_roi, (low, low, low), (high, high, high))
    cv.imshow('b', mask)
    #cv.waitKey(1000)
    roi_hist = cv.calcHist([hsv_roi], [0], mask, [180], [0, 180])
    cv.normalize(roi_hist, roi_hist, 0, 255, cv.NORM_MINMAX)
    term_crit = (cv.TERM_CRITERIA_EPS | cv.TERM_CRITERIA_COUNT, 10, 1)

    # 目标跟踪
    while True:
        ret, frame = capture.read()
        #frame = cv.GaussianBlur(frame, (5, 5), 0)
        if ret is False:
            break;
        hsv = cv.cvtColor(frame, cv.COLOR_BGR2HSV)
        cv.imshow('hsv', hsv)
        # 直方图反向投影
        dst = cv.calcBackProject([hsv], [0], roi_hist, [0, 180], 1)
        # 均值迁移,搜索更新roi区域
        ret, track_window = cv.meanShift(dst, track_window, term_crit)
        # 绘制窗口
        x, y, w, h = track_window
        cv.rectangle(frame, (x, y), (x + w , y + h+100), 255, 2)
        x_center = int(x+w/2)
        y_center = int(y+h/2+50)

        if len(points) < M:
            points.append((x_center, y_center))
        else:
            for i in range(M-1):
                points[i] = points[i+1]
            points[-1] = (x_center, y_center)
        radius = 10
        points_color = (0, 0, 255)



        #绘制点轨迹
        if len(points) == M:
            for point in points:
                cv.circle(frame, point, radius, points_color, -4)


        #检测人脸
        faceRects = classifier.detectMultiScale(hsv)
        if len(faceRects) > 0:
            for faceRect in faceRects:
                x, y, w, h = faceRect
                if w > 100:
                    #标定出人脸方框
                    cv.rectangle(frame, (x, y), (x + w, y + h), color, 2)

        cv.imshow('picture', cv.flip(frame, 1))
        cv.waitKey(60)
    cv.destroyAllWindows()

if __name__ == '__main__':
    face_test()


总结

你可能感兴趣的:(python,开发语言)