16

机器视觉实战3:基于Hog特征的目标检测

 4 years ago
source link: https://niyanchun.com/hog-object-detection.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

上篇文章《 机器视觉实战2:基于Haar特征的目标检测 》中介绍了如何使用Haar特征进行目标检测,本文介绍另外一种目标检测算法:基于HOG特征的目标检测。该算法是在Dalal和Triggs于2005年发表的论文 Histogram of Oriented Gradients for Human Detection 中提出的,他们当时正在研究行人检测。HOG特征和Haar特征类似,都是一种提取特征的算法,其原理都是选择一个窗口,然后使用这个窗口去滑过图片的所有区域(如下图),每滑动一次就会产生一个特征值,相比于Haar,HOG的特征值计算更加复杂一些,要进行投影、计算梯度等操作,细节参见 Wikipedia HOG

B32InyQ.gif

注:图片来自 这里 .

提取出特征之后,就可以使用一些分类算法进行模型训练了。当时论文作者使用线性SVM进行了模型的训练,所以现在HOG特征也都基本是和SVM一起使用的(记得以前有统计称普通机器学习算法中最受欢迎的就是SVM和随机森林了)。完整的流程如下( 图片来自HOG的原始论文 ):

A3Q3aa2.png!web

OpenCV也支持基于HOG特征的目标检测,并且预先训练了一些模型,下面我们通过一个例子进行介绍:

import cv2

// 初始化HOG及SVM分类器
hog = cv2.HOGDescriptor()
hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())
vs = cv2.VideoCapture("/Users/allan/Downloads/TownCentreXVID.avi")
threshold = 0.7

while True:
    grabbed, frame = vs.read()
    if grabbed:
        frame = cv2.resize(frame, (1280, 720))
        gray_frame = cv2.cvtColor(frame, cv2.COLOR_RGB2GRAY)

        rects, weights = hog.detectMultiScale(gray_frame)
        for i, (x, y, w, h) in enumerate(rects):
            if weights[i] < 0.7:
                continue
            else:
                cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)

        cv2.imshow("frame", frame)

    k = cv2.waitKey(1) & 0xFF
    if k == ord("q"):
        break

vs.release()
cv2.destroyAllWindows()

代码整体逻辑比较简单,和上篇文章代码非常相似。刚开始初始化HOG Descriptor,并设置SVM检测器为默认的行人检测器。然后从视频读取一帧帧的图片进行处理(文中的测试视频可在公众号回复" 机器视觉实战3 "获取)。

代码效果如下:

Zj67V33.png!web

这里对检测函数 detectMultiScale 的返回值稍作说明。我们知道分类算法的结果一般返回的是label,也就是告诉你目标属于哪个类别。而检测类算法要更进一步,不仅要解决图片中有没有目标出现,如果有,还要给出在哪里。所以不论是上节的Haar Cascades,还是这节的HOG,检测函数的返回值都很相似,HOG返回的信息更多,我们以HOG为例介绍。HOG返回了两个列表:rects和weights。检测到多少个目标,列表中就会有多少个值,即列表的大小回答了图片中有没有目标的问题。rects中的每个值是包含四个元素的元组,比如(952, 3, 77, 82),这四个值限定了图片中一个矩形,前两个值是矩形的一个顶点的坐标,后面两个值则是矩形的宽和高。而这个矩形就是检测出来的目标的位置,这些从代码中的 cv2.rectangle 也能看出来。相比于Haar,HOG还多返回了一个weights列表,这个列表的行和rects是一致的,它指的是识别出来的目标的权重,可以理解为可信度,DNN模型里面一般称为confidence。

对于目标检测来说,还有一个非常重要的知识点,就是NMS(Non Maximum Suppression),一般翻译为非极大值抑制。我们进行检测的时候,是用一个个滑框去获取特征值的,所以会产生大量的重复区域,效果就是最终返回的矩形有很多会产生重复。而NMS就是用来消除这些局部区域的极大值,最终获得最大值,从而消除重复,下面是一张效果图:

EVrE3eM.jpg!web

左侧是没有经过NMS处理的,右侧是经过NMS处理。这里推荐一篇文章: 非极大值抑制(Non-Maximum Suppression) . NMS的算法原理相对简单,需要的时候可以自己实现,也可以使用一些已有实现。这里推荐一个Python的:

# pip install imutils
from imutils.object_detection import non_max_suppression

rects = np.array([[x, y, x + w, y + h] for (x, y, w, h) in rects])
pick = non_max_suppression(rects, probs=None, overlapThresh=0.65)

Haar Cascades和Hog特征检测是DNN没有出来之前主要的目标检测算法,即使现在有很多基于DNN的模型,Haar Cascades和Hog在工业界依旧有很多应用场景。

References


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK