对于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;
据我了解,如果1/(255*12)
为src
,则比例将为CV_8UC1
。应用1/255会将像素强度归一化为[0,1]
,但是附加比例1/12
又如何呢?有什么作用?
答案 0 :(得分: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
缩放然后平方即可达到目的。