学习OpenCV——Hog.detectMultiScale的心得

来源:互联网 发布:mysql 每天弹出dos 编辑:程序博客网 时间:2024/04/27 20:48

转自:http://blog.csdn.net/sangni007/article/details/7544401

 

这几天一直为一个问题挠头,搞得好几天没心情,今天想明白了一点赶紧记下来,省的以后忘了。

这几天一直折磨我的问题就是Hog.detectMultiScale()函数。

我看到网上的有些HoG的文章从一幅完整图像中检测出目标对象时,一个很NB的框框,框的还那么准,比如OpenCV自带的sample:http://blog.csdn.net/sangni007/article/details/7453987

我总是心生羡慕啊!于是我也试验试验,结果我就悲剧了!

我首先用从前的HoG+SVM的方式训练分类器,训练的时大众的Logo,负样本是乱七八糟。

http://blog.csdn.net/sangni007/article/details/7471222

之后保存xml文件,

定义一个HOGDescriptor hog1;

             hog1.load("SVM_DATA.xml");

             hog1.detectMultiScale(img,found);

却怎么都检测不出来!!!本来是detectMultiScale()不会使,后来好不容易会用了,这个结果又一直困扰我,不明白到底是没训练对还是函数有的不对~%>_<%~

今天才突然有点明白问题在哪:

我训练的xml的SVM的分类器,也就是说,输出的结果response只有1和0(相应的输出结果!!!),只能预测它是不是大众Logo,而不能检测目标,因为不是检测器。

其实这只是一个模糊的认识,希望有懂行的给点指导~~~

 

评论汇总:

1、检测器的原理其实就是滑动窗口加上分类器

2、二分类器输出的是0,1,多分类的可以是0,1,2......;那检测器应该也差不多,也是先建模型,在搜索判断是不是0或者1或2......检测器可以用来在一幅大图中检测目标物体,比如在图像中检测行人,这就要用到detector~。当然,可以用滑动窗口与分类器结合起来检测目标~

3、检测其它物体,我是这样做的,
HOGDescriptor* hog = new HOGDescriptor();
vector<float>* descriptors = new std::vector<float>();
hog->compute(imgT, *descriptors, Size(8, 8));//imgT是要检测的目标
hog->setSVMDetector(*descriptors);
....
hog->detectMultiScale(img, found, 0, Size(8,8), Size(32,32), 1.05, 2);
但是最终检测的结果并不准确,其中的imgT就是从img中抠出来的,现在也不知道怎么回事,难道,生成descriptors时就得需要多个的imgT?
 
回复:应该是先计算(也就是compute),再训练,最后检测目标图像~
 
4、OpenCV 的SVM不能做regression(回归,退化),所以只输出label~~建议使用svm_light 或者 libsvm + Opencv
5、第5个参数是指窗口边境填充大小
6、detectMultiScale() 的参数具体代表那些含义,可参考如下文档
http://docs.opencv.org/modules/gpu/doc/object_detection.html?highlight=detectmultiscale
void gpu::HOGDescriptor::detectMultiScale(const GpuMat& img, vector<Rect>& found_locations, double hit_threshold, Size win_stride, Size padding, double scale0, int group_threshold)
第四个参数是窗口步幅,是表示一次检测之后,窗口移动的幅度,即每次窗口移动的距离,在training的时候一般把sample大小设置成窗口大小一样,开始可能需要resize sample(为了处理多尺度问题,可以使用multi-scale hog feature,然后用PCA降维)~~
 
第五个参数,只是和CPU HOG的detectmultiscale函数的接口保持一致~~代表对要检测的image的边界填充,如果设置成为(0,0),检测窗口的中心不能从(0,0)开始扫描~~就和你用空间滤波器在图像上做滤波一样~~设置成(64,64)图像的row和col增加128,128,计算的hog feature自然会慢。
文档中的解释是用来保持CPU兼容的虚假参数,要求必须是(0,0),但是使用(64,64)或者其他一些参数也是可以的。
把sample中的(64,64)改成(0,0)发现运行时间缩短了,应该是CPU利用率之类。
 
7、detectMultiScale() 是做检测,而xml的SVM的分类器实际上在做识别
8、使用detectMultiScale() 必须构造一个线性的SVM检测器