c++ - 搜索哈里斯角时索贝尔标度的意义
问题描述
对于corner.cppcornerEigenValsVec
中的函数,我一直在理解局部变量传递到的效果(从第257行到第263行):scale
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
是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为光圈,缩放比例应为: 。更多细节可以在这里找到。
这个“应该”的代码是:
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
然后取正方形就可以了。
推荐阅读
- node.js - 如何在 nodejs 的 microsoft bot 模拟器中显示加载选项?
- angular - 如何获取数组响应以保存到文本文件
- c# - 使用Epplus的Excel时间格式
- javascript - 与 streetViewService 异步 - 回调使用失败
- android - 在 gradle 窗口中,它只是说“没什么可显示的”
- java - @Inject 和 @ValueMapValue 注解的区别
- powershell - 将控制台输出写入文件 - 文件意外为空
- jquery - Amazon S3 文件上传:抛出 403
- azure - 如何将密钥保管库的访问权限授予用户分配的身份?
- android - 使用 SnapHelper 选择项目时在 Viewholder 中调用函数