【问题标题】:Significance of sobel's scale when searching Harris corners搜索哈里斯角时索贝尔标度的意义
【发布时间】:2019-05-30 00:26:15
【问题描述】:
对于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;
据我了解,如果src 属于CV_8UC1,则规模将为1/(255*12)。应用 1/255 会将像素的强度归一化为 [0,1],但额外的比例 1/12 怎么样?它的作用是什么?
【问题讨论】:
标签:
c++
opencv
feature-extraction
feature-detection
sobel
【解决方案1】:
3x3 Sobel 滤波器是通过将导数滤波器 [-1 0 1] 与平滑滤波器 [1 2 1] 矩阵相乘而获得的。当光圈变为 5x5 时,另一个平滑将应用于其他两个滤镜。这些滤波器的“正确”归一化,即使它们加起来为 1 的归一化,对于导数应该是 1/2,对于平滑应该是 1/4。因此,3x3 过滤器应按 1/8 归一化,5x5 应按 1/128 归一化,7x7 应按 1/2048 归一化。调用 r 光圈,缩放应该是:
。
更多详情请见here。
这个“应该”的代码是:
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 缩放,然后取平方即可。