OpenCV:如何将 HOGDescriptor::detectMultiScale() 与自定义 SVM 一起使用?
Posted
技术标签:
【中文标题】OpenCV:如何将 HOGDescriptor::detectMultiScale() 与自定义 SVM 一起使用?【英文标题】:OpenCV: how to use HOGDescriptor::detectMultiScale() with custom SVM? 【发布时间】:2014-04-05 06:37:37 【问题描述】:我已经用我自己的正负样本训练了一个关于 HOG 特征的 CvSVM:
CvSVMParams params;
params.svm_type = CvSVM::C_SVC;
params.kernel_type = CvSVM::RBF;
CvSVM svm;
svm.train_auto(descriptors, labels, cv::Mat(), cv::Mat(), params,
SVM_CROSS_VALIDATION_K);
我可以很好地对图像进行分类:
cv::HOGDescriptor hog;
hog.winSize = cv::Size(HOG_PARAMS.width(), HOG_PARAMS.height());
//compute the HOG features
hog.compute(image, ders,
cv::Size(HOG_PARAMS.stride(),HOG_PARAMS.stride()),
cv::Size(0,0), locs);
//convert the feature to a Mat
cv::Mat desc_mat;
desc_mat.create(ders.size(), 1, CV_32FC1);
for(unsigned int i = 0; i < ders.size(); i++)
desc_mat.at<float>(i, 0) = ders[i];
float response = svm.predict(desc_mat);
现在我想使用 HOGDecripor::detectMultiScale() 来检测图像中感兴趣的对象。要将 CvSVM 转换为 HOGDescriptor 需要的原始形式,我使用https://***.com/a/17118561/2197564 建议的方法:
detector_svm.h:
#ifndef DETECTOR_SVM_H
#define DETECTOR_SVM_H
#include <opencv2/core/core.hpp>
#include <opencv2/ml/ml.hpp>
class Detector_svm : public CvSVM
public:
std::vector<float> get_primal_form() const;
;
#endif //DETECTOR_SVM_H
detector_svm.cpp:
#include "detector_svm.h"
std::vector<float> Detector_svm::get_primal_form() const
std::vector<float> support_vector;
int sv_count = get_support_vector_count();
const CvSVMDecisionFunc* df = decision_func;
const double* alphas = df[0].alpha;
double rho = df[0].rho;
int var_count = get_var_count();
support_vector.resize(var_count, 0);
for (unsigned int r = 0; r < (unsigned)sv_count; r++)
float myalpha = alphas[r];
const float* v = get_support_vector(r);
for (int j = 0; j < var_count; j++,v++)
support_vector[j] += (-myalpha) * (*v);
support_vector.push_back(rho);
return support_vector;
但是,当我尝试设置 SVM 检测器时
HOGDescriptor hog;
hog.setSVMDetector(primal_svm); //primal_svm is a std::vector<float>
我的断言失败:
OpenCV Error: Assertion failed (checkDetectorSize()) in setSVMDetector, file /home/username/libs/OpenCV-2.3.1/modules/objdetect/src/hog.cpp, line 89
terminate called after throwing an instance of 'cv::Exception'
what(): /home/username/libs/OpenCV-2.3.1/modules/objdetect/src/hog.cpp:89: error: (-215) checkDetectorSize() in function setSVMDetector
我试过用 OpenCV 2.3.1 和 2.4.7 运行它;结果是一样的。
我做错了什么?
【问题讨论】:
你解决过这个问题吗?我有同样的问题 我还没解决。我通过编写自己的多尺度检测器解决了这个问题。 【参考方案1】:您训练的向量大小可能太小。您需要确保训练时的窗口大小与描述符大小相匹配 win_size=大小(64, 128) block_size=大小(16, 16) block_stride=大小(8, 8) cell_size=尺寸(8, 8) nbins=9
【讨论】:
【参考方案2】:如果(您的)primal_svm.size()
与 hog.getDescriptorSize()
不同,则会引发该错误
我在您的代码中没有立即看到任何错误,但显然缺少一些样板。
【讨论】:
【参考方案3】:你需要像 hog(cv::Size(64, 64), cv::Size(16, 16), cv::Size(8, 8), cv::Size(8, 8) 一样初始化你的 hog ), 9),并确保参数的值与您的匹配。
【讨论】:
【参考方案4】:我无法再访问原始代码。
为了解决这个问题,我编写了自己的多尺度检测器,这比获取原始 SVM 形式的工作量少。
我现在对有类似问题的人的建议是尝试升级到 OpenCV 3.x。
【讨论】:
【参考方案5】:我有同样的问题。我意识到我给 HogDescriptor 函数提供了错误的 winSize。 winSize 应该与训练图像的尺寸相匹配。在我的例子中,我使用了 32x64 图像(用于训练),所以我需要使用 winSize=(32x64)。我设置检测器的代码如下所示。
vector<float> primal;
svm.getSupportVector(primal);
cv::HOGDescriptor hog(cv::Size(32, 64), cv::Size(8, 8), cv::Size(4, 4), cv::Size(4, 4), 9);
hog.setSVMDetector(primal);
【讨论】:
以上是关于OpenCV:如何将 HOGDescriptor::detectMultiScale() 与自定义 SVM 一起使用?的主要内容,如果未能解决你的问题,请参考以下文章
iOS 上的 OpenCV 对象检测 (HOGDescriptor)
cvSVM 训练对 HOGDescriptor 产生较差的结果