首页 > 解决方案 > 搜索哈里斯角时索贝尔标度的意义

问题描述

对于corner.cppcornerEigenValsVec中的函数,我一直在理解局部变量传递到的效果(从第257行到第263行):scaleSobel

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)如果srcCV_8UC1。应用 1/255 会将像素的强度归一化为[0,1],但额外的比例如何1/12?它的作用是什么?

标签: c++opencvfeature-extractionfeature-detectionsobel

解决方案


3x3 Sobel 滤波器是通过将导数滤波器 [-1 0 1] 与平滑滤波器 [1 2 1] 矩阵相乘而获得的。当光圈变为 5x5 时,另一个平滑将应用于其他两个滤镜。这些滤波器的“正确”归一化,即使它们加起来等于 1 的归一化,对于导数应该是 1/2,对于平滑应该是 1/4。所以 3x3 过滤器应该按 1/8 归一化,5x5 按 1/128 归一化,7x7 按 1/2048 归一化。称r为光圈,缩放比例应为: 。更多细节可以在这里找到。

这个“应该”的代码是:

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(),所以使用条件运算符将光圈设置为3。奇怪的是还有一个if后来的更进一步将所有内容乘以 2,这可能已包含在将值设置为 4 的条件运算符中。因此,Scharr 过滤器的归一化为 1/8。我又不知道为什么。

终于block_size开始了,但很容易理解:梯度的平方后来被块求和,也就是说你正在添加block_size*block_size元素。为了使这些标准化,您应该除以block_size*block_size。按比例缩放block_size然后取正方形就可以了。


推荐阅读