我试图优雅地构建一个SIFT特征描述符,如在MATLAB中的Lowe的paper中所描述的。我见过的大多数方法都比较混乱,我想找到一种优雅的方法。我将关键点作为插值(x,y)坐标,并且我使用以下方法确定了图像中所有像素的渐变幅度和方向:
[Gmag,Gdir]=imgradient(image)
我可以通过切片Gdir
轻松找到关于每个关键点的16x16渐变窗口。我现在需要构建每个单元格的直方图。我使用以下代码获取每个方向/幅度的bin编号:
binned=discretize(local_Gdir,[-180:45:180])
binned
现在是一个索引矩阵,对应于每个单元格的特征向量(填充数字1-8; binned
的索引对应于局部梯度索引)。 / p>
为了构建128元素特征描述符,我需要确定16个单元格的特征向量(直方图)。我一直试图将binned
矩阵分割成16个单元格,同时保留索引,以便我可以快速参考局部梯度幅度矩阵,在将每个单元格附加到最终描述符之前,对每个单元格中的梯度求和,但我找不到干净的方法来做到这一点。
如何使用索引矩阵构建16个单元格的16个特征向量?也许更一般地说,在不丢失原始行/列索引的情况下,将索引矩阵拆分为16个子矩阵的好方法是什么?
答案 0 :(得分:0)
16 * 16窗口中有16个4 * 4子窗口,16 * 16窗口的所有元素都具有1到8的值,因此每个子窗口应分别创建一个直方图。这意味着在循环中应该调用hist
函数16次。
相反,我们可以为每个子窗口添加一个数字,然后每个子窗口的值变得与其他子窗口不同。
例如,对于第一个子窗口,我们将0添加到分箱值,因此值范围从1到8.
对于第二个子窗口,我们将8添加到分箱值,因此值范围从9到16。
为第三个窗口添加16 .....
然后只调用一次hist
函数并计算128个值。
% exmaple of a 16 * 16 window
binned_16 = randi([1 8],16 ,16);
% the values to be added to each 16* 16 window ;this matrix only one time needs to be computed
values_to_add = kron(reshape((0 : 15), 4, 4)*8 , ones(4));
% values added to the window
binned_added_values = values_to_add + binned_16;
% histogram computed
h = hist(binned_added_values(:), 1:128);