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

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;

据我了解,如果1/(255*12)src,则scale将为CV_8UC1。应用1/255可以将像素的强度标准化为[0,1],但是附加比例1/12呢?有什么作用?

最佳答案

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使用normalization,这导致:
double scale = 1 << (aperture_size - 1);

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

其余的内容很容易理解:如果要使用Scharr滤镜,则将光圈设置为CV_SCHARR,即-1(source),因此使用条件运算符将光圈设置为3。进一步将所有内容乘以2,这可能已经包含在将条件值设置为4的条件运算符中。因此,Scharr滤波器的归一化为1/8。再次,我不知道为什么。

终于if开始了,但是很容易理解:渐变的平方随后被求和,也就是说,您要添加block_size元素。为了规范化这些,您应该除以block_size*block_size。通过block_size*block_size缩放,然后取平方即可达到目的。

关于c++ - Sobel量表在搜索Harris角点时的意义,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54021876/

10-11 08:27