gpt4 book ai didi

c++ - 梯度幅度的单位和极限是多少?

转载 作者:太空宇宙 更新时间:2023-11-03 10:24:23 31 4
gpt4 key购买 nike

图像梯度幅度的单位和限制是什么?例如,我知道如何获取图像的梯度大小(请参见下文)。生成的Mat将包含源图像中每个边缘的边缘强度(大小)。

但是,“边缘强度/幅度”的单位是什么?梯度方向以度/弧度为单位,量级以什么单位?在OpenCV中,幅值的限制是什么?它是0到1,即一条边的强度/大小在0到1之间,而1完全垂直吗?

因此,如果我要在直方图中绘制幅度; x轴表示边缘强度/陡度,y轴表示具有该强度/陡度的像素数?我对么?

Mat sX, sY, mag;
Sobel(src, sX, CV_32F, 1, 0, 1);
Sobel(src, sY, CV_32F, 0, 1, 1);

magnitude(sX, sY, mag);

// So mag now contains the image gradient magnitude
// of the all the edges I pulled out by sobel.
// What are the units and limits of 'edge strength'/magnitude?
// For example are the limits 0 to 1?

最佳答案

单位

您正在获取函数的一些近似导数。如果函数是f(x),那么请记住,您正在看的是f的变化,而不是x的变化。假设函数是基于时间r(t)的位置,则导数的单位是位置(距离)与时间(时间)之差的差。那么图像的单位是什么?好吧,它们是某些位置的光度值。亮度值的变化只是亮度值,位置的变化是距离。因此,导数的单位是光度/距离。

梯度幅度

由于我们正在处理图像,因此最小的距离是一个像素,并且最大的变化可能是从白色到黑色(反之亦然),因此这些将对应于最大的渐变。但是Sobel可以使用其最小值和最大值可能在0到1或0到255之外的任意矩阵。

请注意,您可能会得到负值的斜率:以像素为单位的距离始终为正,但是从白色到黑色以及从黑色到白色的变化具有相反的符号。在Sobel计算了这些导数之后,您将与 Angular 分开计算幅度。您可以通过按每个方向上的渐变强度对xy方向加权来计算 Angular ,并且需要使用符号返回0到360之间的任意 Angular 。

如果您希望所有边的大小为正值,而非边为0,则可以采用L1范数,即abs(x) + abs(y),或者采用uct_a或Euclidean或L2范数,其the magnitude functionsqrt(G(x)^2 + G(y)^2),就像您将计算三角形的斜边。直接添加将意味着某些渐变是正的,有些则是负的,从而留下显示黑白边缘的灰色图像。

来自Sobel运算符的值

Sobel运算符只计算像素附近的导数,而不只是比较两个像素,而是比较六个像素,并对它们加权,然后将它们全部加起来,因此它可能比图像中的值高一点。而且,浮点图像不会在0或1处被截断,因此,您可以发送具有更大值的图像并获得更大的值。除了数据类型可以容纳的最大值外,运算符(operator)没有虚拟最大值。 Sobel运算符还可以在进行梯度计算之前进行一些平滑操作,以去除较小的边缘,但是平滑操作程序不会缩放值。

OpenCV docs for Sobel显示运算符(operator)将图像乘以的值。具体来说,对于x方向,每个3x3像素邻域将逐元素乘以

-1 0 1
-2 0 2
-1 0 1

并总结。如果图像类型的最大可能值为 M,最小值为 m,则渐变中的最大正值为
(1+2+1)*M - (1+2+1)*m = 4*M - 4*m

同样,最大的负值是
-(1+2+1)*M + (1+2+1)*m = -4*M + 4*m

每个方向上的渐变都是一样的。因此,从 Sobel到每个方向的渐变范围将是 [-4M+4m, 4M-4m]

规范运算符

您将以L1或L2范数以某种方式将这些幅度中的两个相加。假设您坚持使用L2范数,那么按照L2范数的定义,合并幅度的最大值将很简单,
MAX = sqrt((4*M - 4*m)**2 + (4*M - 4*m)**2) 
= sqrt(2 * (4*M - 4*m)**2)
= sqrt(2 * 16 * (M - m)**2)
= sqrt(32) * (M - m)

由于L1或L2范数将正值和负值视为相等(它们与0的距离很重要),因此Sobel运算符中的最小值在组合大小上给出的响应与最大值相同。当然,您的响应的某些点可能为0,这给出了Sobel响应,因此总和的幅度也为0,因此0将是最小值。

编辑:如该问题的 another answer所述,我们实际上不能同时在X和Y方向上达到最大值,并且如果计算出实际上可以达到的最大值,则最终会稍微小一些:
sqrt(20) * (M - n)

因此,您可以将梯度规格化为0至1w.r.t。您的图片类型除以最大值。这将允许您比较多个图像的边缘强度。

或者,您可以只使用 normalize函数,但是最终值将取决于您的图像,因此您无法在图像之间比较相等的值。

关于c++ - 梯度幅度的单位和极限是多少?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44081873/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com