笔者曾经做过一个项目,后期是把matlab转化为opencv,在此过程中,遇到的比较大的问题是HOG特征的提取问题,由于两个不用语言写的函数其输入参数的格式和编程思想有较多不同,在调试过程中花费了较多时间,在此作对比,并详细讲述转化方法。
基本情况:Matlab所用的函数名是hogcalculator.m。opencv所用的函数为HOGDescriptor。
目标:调整各自输入参数,使相同的输入在各自的程序中具有相同的特征向量。
先看matlab:
函数如下:
function F = hogcalculator(img, cellpw, cellph, nblockw, nblockh,nthet, overlap, isglobalinterpolate, issigned, normmethod)
给输入参数编号:
(1)img, (2)cellpw, (3)cellph, (4)nblockw, (5)nblockh, (6)nthet, (7)overlap, (8)isglobalinterpolate, (9)issigned, (10)normmethod
按顺序解释输入参数:
(1)输入图像,必须是灰度图
(2-3)cell的水平和垂直方向的像素
(4-5)滑动块的水平和垂直方向的个数。(这里是个数,注意与像素区别,如果看英文会发现作者叙述这两个参数不准确,译为中文很容易让人误解)
(6)bin的数量
(7)重叠比例。(对应HOGDescriptor中的滑块步进值)
(8)全局插值or局部插值
(9)0~180度 or 0~360度
(10)归一化模式选择。共有'none','l1','l2','l1sqrt','l2hys'五种模式
后三个参数不影响特征向量的计算结果,可以不看。
CV_WRAP HOGDescriptor(Size _winSize, Size _blockSize, Size _blockStride, Size _cellSize, int _nbins, int _derivAperture=1, double _winSigma=-1, int _histogramNormType=HOGDescriptor::L2Hys, double _L2HysThreshold=0.2, bool _gammaCorrection=false, int _nlevels=HOGDescriptor::DEFAULT_NLEVELS)
这样看有点杂乱,举个具体的例子:
HOGDescriptor*hog=new HOG Descriptor(cvSize(16,48),cvSize(8,24),cvSize(8,8),cvSize(4,4),8);
按顺序,参数说明:(1)窗口宽高
(2)滑动块的宽和高
(3)步进的宽高(与overlap相区分)
(4)cell的宽高
(5)bin数量
当计算所得特征向量数量相当时,即意味着参数正确了,可以得到相同的结果。举例说明计算方法,带参Matlab代码如下:
imputimg = imresize(imputimg, [48 16]);%48高,16宽,别思维定势认为宽一定在前面,这里是反的
imputimg = rgb2gray(imputimg);
test_data=hogcalculator(imputimg,4,4,2,2,8,0,'localinterpolate','unsigned','l2hys');
按步骤详解:
(1)计算滑块的宽、高:
img的宽*高/nblockw*nblockh,即16*48/2*2=8*24
(2)计算在图像上可能存在的滑块数:
重叠率:这里的重叠率为0,意思为滑块步进值正好的滑块的宽和高。故可能的不同位置的滑块个数为16*48/8*24=2*2=4个
(若重叠率为0.5,易得步进是滑块的宽和高的一半,即为4*12,易得滑块在水平方向上有0~8、4~12、8~16共三种情况,同理的滑块在竖直方向也有三种情况。故可能的不同位置的滑块个数为9个。重叠率与滑块的水平与竖直方向的个数为既不充分也不必要条件。)
(3)计算单个滑块可含有的cell数:
每个滑块的宽高8*24/每个cell的宽高4*4=12个
(4)计算特征向量:将这些数据相乘,再乘以bins。
4*12*8=384个
举例说明计算方法,带参opencv代码如下:
resize(Img_temp,Img, Size(16,48));
HOGDescriptor*hog=new HOG Descriptor(cvSize(16,48),cvSize(8,24),cvSize(8,24),cvSize(4,4),8);
多数是一样的,但是有一些地方要做区别,尽管参数具体作用相似,但是用起来却差之毫厘谬以千里:
(1)计算有多少个windows:
这里把windows的窗口直接设置为图像的宽和高,就相当于hogcalculator.m输入一张图片。1个window。(这是个hogcalculator.m里没有的功能,opencv里除了设置滑块的步进,还可以设置windows的步进)
(2)计算滑块数量。
滑块的尺寸与步进的尺寸相同,意为overlap=0。16*48/8*24=2*2=4个滑块
(步进size_stride:这里不同于overlap,overlap意味着比例,此处意为滑动块的尺寸。滑动块尺寸size_block:nblockw, nblockh意为水平方向上的个数,这意为尺寸。)
(3)计算单个滑动块包含的cell数量。8*24/4*4=2*6=12个
(4)将这些数据相乘,再乘以bins。1*4*12*8=384个
最后,调试两个的程序,并分别查看test_data和descriptor的内存,看结果是否和自己所计算的一致。根据上述方法,便可实现HOG特征提取在matlab和opencv之间的转化。
附:(1)对opencv中的HOG的源码分析http://blog.csdn.net/mounty_fsc/article/details/51095044
推荐网址:
Matlab:http://blog.csdn.net/langb2014/article/details/45674725
Opencv:http://gz-ricky.blogbus.com/logs/85326280.html
http://blog.csdn.net/yangtrees/article/details/7463431