快捷搜索:  as  test  1111  test aNd 8=8  test++aNd+8=8  as++aNd+8=8  as aNd 8=8

新黄金城xhjc.667722:【OpenCV 2.4+ C++教程】行人检测示例



HOG特性描述

首先我们来懂得一下HOG特性描述子。

HOG特性描述子(HOG descriptors)是由Navneet Dalal和 Bill Triggs在2005年的一篇先容行人检测措施的论文提到的特性描述子(论文以及演讲可拜见参考资料1、2)。

其主要思惟是谋略局部图像梯度的偏向信息的统计值,来作为该图像的局部特性值。

如上图,归一化图像后,因为颜色数据对我们没有赞助,以是将图片转为灰度图。

然后将图片瓜分成必然“块”数,称作细胞单元。

谋略每个细胞单元的梯度大年夜小偏向。

获得每个单元的梯度偏向组成一个图片的特性向量。

将这个特性向量交给SVM来进修或辨认。

SVM的简单先容可以参考:OpenCV 2.4+ C++ SVM翰墨识别。

算法阐发

梯度谋略

OpenCV 2.4+ C++ 边缘梯度谋略中,先容了Sobel算子和Scharr滤波器的梯度谋略措施,然则论文作者应用这些繁杂措施的效果并不好,最好的是应用简单的一维梯度算子:[-1, 0, 1],进行卷积谋略,分手算出x偏向梯度Gx与y偏向梯度Gy。然后使用下面两个公式谋略梯度大年夜小和偏向:

平滑处置惩罚

论文作者应用了高斯隐隐进行平滑处置惩罚,结果效果变差了。其可能缘故原由是:许多有用的图像信息是来自变更剧烈的边缘,而在谋略梯度之前加入高斯滤波会把这些边缘滤除掉落。

细胞偏向选择

细胞的统计偏向,由细胞中的每一个像素点投票取得。

票箱是0 - PI(无向)角度范围等分为9个角度,即PI/9为每个票箱的角度范围。

每个投票像素点的投票权重,由其梯度幅值谋略出来,可采纳幅值本身(实验效果最佳),或者他的函数来表示这个权重。

局部通知变更或者前景和背景的比较变更,可能使梯度强度孕育发生剧烈变更,但我们关注的不是这些信息,以是必要对这些信息弱化处置惩罚。使用数个细胞单元组成空间上连通的块。这样,HOG描述就成了由各个块所有细胞单元的直方图组成的一个向量,这些区域是相互重叠的。这样就减小了这些剧烈变更的影响。

每个细胞是8*8个像素点,以四个细胞组成一个块。

再由块组成检测窗新黄金城xhjc.667722。

块向量归一化

着末是使用L2-norm或者L1-norm进行归一化。

设v是未被归一化的向量,| vk |是k阶范数,ε为随意率性小常数,当k=2时,L2-norm为:

当k=1时,L1-norm为:

还有一种归一化要领L2-Hys:

首先辈行L2-norm,然落后行截短(即值被限定为v - 0.2v之间),然后再归一化。

HOGDescriptor API

gpu::HOGDescriptor::HOGDescriptor

创建HOG描述符和检测器。

C++: gpu::HOGDescriptor::HOGDescriptor(Size win_size=Size(64, 128), Size block_size=Size(16, 16), Sizeblock_stride=Size(8, 8), Size cell_size=Size(8, 8), int nbins=9, double win_sigma=DEFAULT_WIN_SIGMA, doublethreshold_L2hys=0.2, bool gamma_correction=true, int nlevels=DEFAULT_NLEVELS)

参数

win_size – 检测窗大年夜小。必要和块的大年夜小、步长匹配。

block_size – 块的大年夜小。必要和细胞大年夜小匹配。今朝只支持(16,16)的大年夜小。

block_stride – 块的步长,必须是细胞大年夜小的整数倍。

cell_size – 细胞大年夜小。今朝只支持(8, 8)的大年夜小。

nbins – 投票箱的个数。今朝只支持每个细胞9个投票箱。

win_sigma – 高斯平滑窗口参数。

threshold_L2hys – L2-Hys归一化紧缩率。

gamma_correction – 伽马校对新黄金城xhjc.667722预处置惩罚标志,必要或不必要。

nlevels – 检测窗口的最大年夜数目。

gpu::HOGDescriptor::getDescriptorSize

返回分类所需的系数的数目。

C++: size_t gpu::HOGDescriptor::getDescriptorSize() const

gpu::HOGDescriptor::getBlockHistogramSize

返回块直方图的大年夜小。

C++: size_t gpu::HOGDescriptor::getBlockHistogramSize() const

gpu::HOGDescriptor::setSVMDetector

设置线性SVM分类器的系数。

& detector)">C++: void gpu::HOGDescriptor::setSVMDetector(const vector& detector)

gpu::HOGDescriptor::getDefaultPeopleDetector

返回人的分类练习检测(默认的窗口大年夜小)的默认系数。

gpu::HOGDescriptor::getDefa新黄金城xhjc.667722ultPeopleDetector()">C++: static vector gpu::HOGDescriptor::getDefaultPeopleDetector()

gpu::HOGDescriptor::getPeopleDetector48x96

返回人的分类练习检测(48*96窗口大年夜小)的系数。

gpu::HOGDescriptor::getPeopleDetector48x96()">C++: static vector gpu::HOGDescriptor::getPeopleDetector48x96()

gpu::HOGDescriptor::getPeopleDetector64x128

返回人的分类练习检测(64*128窗口大年夜小)的系数。

gpu::HOGDescriptor::getPeopleDetector64x128()">C++: static vector gpu::HOGDescriptor::getPeopleDetector64x128()

gpu::HOGDescriptor::detect

在没有多尺度的窗口履行工具检测

C++: void gpu::HOGDescriptor::detect(const GpuMat& img, vector

& found_locations, double hit_threshold=0, Sizewin_stride=Size(), Size padding=Size())

Parameters:

img – 源图像。只支持CV_8UC1和CV_8UC4数据类型。

found_locations – 检测出的物体的边缘。

hit_threshold – 特性向量和SVM划分超平面的阀值间隔。平日它为0,并应由检测器系数抉择。然则,当系数被省略时,可以手动指定它。

win_stride – 窗口步长,必须是块步长的整数倍。

padding – 模拟参数,使得CUP能兼容。今朝必须是(0,0)。

gpu::HOGDescriptor::detectMultiScale

在多尺度窗口中履行工具检测。

& found_locations, double hit_threshold, Size win_stride, Size padding, double scale0, int group_threshold)">C++: void gpu::HOGDescriptor::detectMultiScale(const GpuMat& img, vector& found_locations, double hit_threshold=0, Size win_stride=Size(), Size padding=Size(), double scale0=1.05, int group_threshold=2)

参数

img – 源图像。只支持CV_8UC1和CV_8UC4数据类型。

found_locations – 检测出的物体的边缘。

hit_threshold – 特性向量和SVM划分超平面的阀值间隔。平日它为0,并应由检测器系数抉择。然则,当系数被省略时,可以手动指定它。

win_stride – 窗口步长,必须是块步长的整数倍。

padding – 模拟参数,使得CUP能兼容。今朝必须是(0,0)。

scale0 – 检测窗口增长参数。

group_threshold – 调节相似性系数的阈值。检测到时,某些工具可以由许多矩形覆盖。 0表示不进行分组。

gpu::HOGDescriptor::getDescriptors

返回全部图片的块描述符。

C++: void gpu::HOGDescriptor::getDescriptors(const GpuMat& img, Size win_stride, GpuMat& descriptors, intdescr_format=DESCR_FORMAT_COL_BY_COL)

参数

img – 源图像。只支持CV_8UC1和CV_8UC4数据类型。

win_stride – 窗口步长,必须是块步长的整数倍。

descriptors – 描述符的2D数组。

descr_format –

描述符存储款式:

DESCR_FORMAT_ROW_BY_ROW - 行存储。

DESCR_FORMAT_COL_BY_COL - 列存储。

这个函数主要用于分类进修。

检测代码

#include

#include#include

#include

using namespace cv;

int main(int argc, char** argv){

Mat img;vector found;

img = imread(argv[1]);

if(argc != 2 || !img.data){

printf("没有图片\n");return -1;

}

HOGDescriptor defaultHog;defaultHog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());

//进行检测

defaultHog.detectMultiScale(img, found);

//画长方形,框出行人for(int i = 0; i

Rect r = found[i];rectangle(img, r.tl(), r.br(), Scalar(0, 0, 255), 3);

}

namedWindow("检测行人", CV_WINDOW_AUTOSIZE);

imshow("检测行人", img);

waitKey(0);

return 0; }

这段代码虽然可以检测出行人,然则可能会呈现,一小我身上有几个框框。例如下图左边的行人:

以是我们必要对found进行筛选,把那些被嵌套的长新黄金城xhjc.667722方形去除。

#include

#include#include

#include

using namespace cv;

int main(int argc, char** argv){

Mat img;vector found, foundRect;

img = imread(argv[1]);

if(argc != 2 || !img.data){

printf("没有图片\n");return -1;

}

HOGDescriptor defaultHog;defaultHog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());

//进行检测

defaultHog.detectMultiScale(img, found);

//遍历found探求没有被嵌套的长方形for(int i = 0; i

Rect r = found[i];

int j = 0;for(; j

//假如时嵌套的就推出轮回if( j != i 新黄金城xhjc.667722&& (r & found[j]) == r)

break;}

if(j == found.size()){foundRect.push_back(r);

}}

//画长方形,圈出行人

for(int i = 0; iRect r = foundRect[i];

rectangle(img, r.tl(), r.br(), Scalar(0, 0, 255), 3);}

namedWindow("检测行人", CV_WINDOW_AUTOSIZE);imshow("检测行人", img);

waitKey(0);

return 0;

}

PS:输入图片不能比检测窗还小,这样会抛出差错的。

参考资料

Histograms of Oriented Gradients for Human Detection . Navneet Dalal & Bill Triggs . 2005

Histograms of Oriented Gradients for Human Detection Talk . Navneet Dalal & Bill Triggs

OpenCV HOGDescriptor 参数图解 . Excalibur . 2011-03-11

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

您可能还会对下面的文章感兴趣: