使用 OpenCV 提取 HoG 特征

Posted

技术标签:

【中文标题】使用 OpenCV 提取 HoG 特征【英文标题】:Extracting HoG Features using OpenCV 【发布时间】:2012-07-22 11:48:42 【问题描述】:

我正在尝试使用 OpenCV 的 HoG API 提取特征,但我似乎找不到允许我这样做的 API。

我要做的是使用 HoG 从我的所有数据集(一组正负图像)中提取特征,然后训练我自己的 SVM。

我在 OpenCV 下查看了 HoG.cpp,但没有帮助。所有代码都隐藏在复杂性和迎合不同硬件(例如英特尔的 IPP)的需要中

我的问题是:

    是否有任何来自 OpenCV 的 API 可用于提取所有这些特征/描述符以输入到 SVM 中?如果有我如何使用它来训练我自己的 SVM? 如果没有,是否有任何现有的库可以完成同样的事情?

到目前为止,我实际上正在将一个现有的库 (http://hogprocessing.altervista.org/) 从 Processing (Java) 移植到 C++,但它仍然非常慢,检测至少需要 16 秒左右

有没有人成功提取HoG特征,你是怎么解决的?你有任何我可以使用的开源代码吗?

提前致谢

【问题讨论】:

我认为这个页面可以帮助你:geocities.ws/talh_davidc 【参考方案1】:

你可以在opencv中使用hog类如下

HOGDescriptor hog;
vector<float> ders;
vector<Point> locs;

此函数为您计算 hog 特征

hog.compute(grayImg, ders, Size(32, 32), Size(0, 0), locs);

grayImg 计算的HOG 特征存储在ders 向量中,形成一个矩阵,以后可以用于训练。

Mat Hogfeat(ders.size(), 1, CV_32FC1);

for(int i=0;i<ders.size();i++)
    Hogfeat.at<float>(i,0)=ders.at(i);

现在您的 HOG 特征存储在 Hogfeat 矩阵中。

您也可以使用hog对象来设置窗口大小、单元格大小和块大小,如下所示:

hog.blockSize = 16;
hog.cellSize = 4;
hog.blockStride = 8;

// This is for comparing the HOG features of two images without using any SVM 
// (It is not an efficient way but useful when you want to compare only few or two images)
// Simple distance
// Consider you have two HOG feature vectors for two images Hogfeat1 and Hogfeat2 and those are same size.

double distance = 0;
for(int i = 0; i < Hogfeat.rows; i++)
    distance += abs(Hogfeat.at<float>(i, 0) - Hogfeat.at<float>(i, 0));

if (distance < Threshold)
    cout<<"Two images are of same class"<<endl;
else
    cout<<"Two images are of different class"<<endl;

希望有用:)

【讨论】:

目前我无法测试它,因为 XCode 4.4 不知何故削弱了大多数已安装的库。当我设法解决这个问题时,我会通知你 你可以使用简单的欧几里得距离作为匹配器......我编辑了答案,看到上面相同的答案:) @Sistu 谢谢,我终于可以提取特征了,但我仍然需要输入我自己的 SVM。 我使用的是 OpenCV 2.3.1,但在这个版本中我没有 HOGDescriptor::compute()。您在此答案中使用了哪个 OpenCV 版本? 抱歉,刚刚发现它也适用于 OpenCV 2.3.1。我使用的是cv::gpu::HOGDescriptor 而不是cv::HOGDescriptor。谢谢!【参考方案2】:

在上面的文章的帮助下,我还编写了 2 hog 特性的程序。 我应用这种方法来检查 ROI 区域是否发生变化。 请参阅此处的页面。 source code and simple introduction

【讨论】:

只有链接不能被接受为答案,请在答案中描述链接的所需部分。【参考方案3】:

这里也是 GPU 版本。

cv::Mat temp;
gpu::GpuMat gpu_img, descriptors;

cv::gpu::HOGDescriptor gpu_hog(win_size, Size(16, 16), Size(8, 8), Size(8, 8), 9,
                               cv::gpu::HOGDescriptor::DEFAULT_WIN_SIGMA, 0.2, gamma_corr,
                               cv::gpu::HOGDescriptor::DEFAULT_NLEVELS);
gpu_img.upload(img);
gpu_hog.getDescriptors(gpu_img, win_stride, descriptors, cv::gpu::HOGDescriptor::DESCR_FORMAT_ROW_BY_ROW);
            descriptors.download(temp);

【讨论】:

【参考方案4】:

OpenCV 3 对用户使用 GPU 算法(即 CUDA)的方式进行了一些更改,请参阅Transition Guide - CUDA。

要将答案从 user3398689 更新到 OpenCV 3,下面是一段代码:

#include <opencv2/core/cuda.hpp>
#include <opencv2/cudaimgproc.hpp>

[...]

/* Suppose you load an image in a cv::Mat variable called 'src' */

int img_width  = 320;
int img_height = 240;
int block_size = 16;
int bin_number = 9;

cv::Ptr<cv::cuda::HOG> cuda_hog = cuda::HOG::create(Size(img_width, img_height),
                                                    Size(block_size, block_size),
                                                    Size(block_size/2, block_size/2),
                                                    Size(block_size/2, block_size/2),
                                                    bin_number);

/* The following commands are optional: default values applies */
cuda_hog->setDescriptorFormat(cuda::HOG::DESCR_FORMAT_COL_BY_COL);
cuda_hog->setGammaCorrection(true);
cuda_hog->setWinStride(Size(img_width_, img_height_));

cv::cuda::GpuMat image;
cv::cuda::GpuMat descriptor;

image.upload(src);

/* May not apply to you */
/* CUDA HOG works with intensity (1 channel) or BGRA (4 channels) images */
/* The next function call convert a standard BGR image to BGRA using the GPU */
cv::cuda::GpuMat image_alpha;
cuda::cvtColor(image, image_alpha, COLOR_BGR2BGRA, 4);

cuda_hog->compute(image_alpha, descriptor);

cv::Mat dst;
image_alpha.download(dst);

然后,您可以根据自己的喜好使用“dst”变量中的描述符,例如 G453 建议的那样。

【讨论】:

以上是关于使用 OpenCV 提取 HoG 特征的主要内容,如果未能解决你的问题,请参考以下文章

opencv进阶-HOG+SVM行人检测(已训练好的分类器)

OpenCV与图像处理

HOG + SVM(行人检测, opencv实现)

OpenCV + HOG +SVM:SVM 单特征向量需要帮助

如何在 Python 中使用 OpenCV 3.0 中的 HOG 功能训练 SVM 分类器?

OpenCV 例程 300篇248. 特征描述之HOG描述符