搜索哈里斯角时索贝尔尺度的意义

Significance of sobel's scale when searching Harris corners

对于 corner.cpp 中的函数 cornerEigenValsVec,我坚持理解局部变量 scale 传递给 Sobel 的效果(从第 257 行到第 263 行):

int depth = src.depth();
double scale = (double)(1 << ((aperture_size > 0 ? aperture_size : 3) - 1)) * block_size;
if( aperture_size < 0 )
    scale *= 2.0;
if( depth == CV_8U )
    scale *= 255.0;
scale = 1.0/scale;

据我了解,如果 srcCV_8UC1,则比例将为 1/(255*12)。应用 1/255 会将像素的强度标准化为 [0,1],但额外的比例 1/12 又如何呢?它的作用是什么?

3x3 Sobel 滤波器是由导数滤波器[-1 0 1] 与平滑滤波器[1 2 1] 矩阵相乘得到的。当孔径变为 5x5 时,将对其他两个滤波器应用另一次平滑处理。这些滤波器的 "correct" 归一化,即使它们相加为 1 的归一化,导数应为 1/2,平滑应为 1/4。因此,3x3 滤波器应按 1/8 归一化,5x5 应按 1/128 归一化,7x7 应按 1/2048 归一化。调用 r 光圈,缩放比例应该是: 。 可以找到更多详细信息 here.

这个 "should" 的代码是:

double scale = 1 << (2 * aperture_size - 3);

出于某种原因我真的无法理解,OpenCV 使用归一化 ,这导致:

double scale = 1 << (aperture_size - 1);

意味着缩放比例对于 3x3 为 1/4,对于 5x5 为 1/16,对于 7x7 为 1/64。

剩下的就很容易理解了:如果要使用Scharr滤镜,光圈设置为CV_SCHARR,也就是-1(source),所以要用到条件运算符将光圈设置为 3。奇怪的是,后面有一个 if,它进一步将所有内容乘以 2,这可能已经包含在条件运算符中,将值设置为 4。所以 Scharr 过滤器的归一化是 1/8 .我又不知道为什么。

最后 block_size 开始了,但它很容易理解:梯度的平方随后被块求和,也就是说你正在添加 block_size*block_size 元素。为了规范化这些你应该除以 block_size*block_size。按 block_size 缩放然后取正方形就可以了。