gpt4 book ai didi

opencv - 你如何计算平均梯度方向和平均梯度强度/幅度

转载 作者:太空宇宙 更新时间:2023-11-03 21:32:09 28 4
gpt4 key购买 nike

在 OpenCV 中,如何计算 Mat 中的平均梯度强度和平均梯度方向?

我已经通过谷歌搜索找到了以下方法,但我想在继续下一步之前确认我确实在正确地执行此操作。

这是正确的吗?

Mat img = imread('foo.png', CV_8UC); // read image as grayscale single channel

// Calculate the mean intensity and the std deviation
// Any errors here or am I doing this correctly?
Scalar sMean, sStdDev;
meanStdDev(src, sMean, sStdDev);
double mean = sMean[0];
double stddev = sStdDev[0];


// Calculate the average gradient magnitude/strength across the image
// Any errors here or am I doing this correctly?
Mat dX, dY, magnitude;
Sobel(src, dX, CV_32F, 1, 0, 1);
Sobel(src, dY, CV_32F, 0, 1, 1);
magnitude(dX, dY, magnitude);

Scalar sMMean, sMStdDev;
meanStdDev(magnitude, sMMean, sMStdDev);
double magnitudeMean = sMMean[0];
double magnitudeStdDev = sMStdDev[0];


// Calculate the average gradient direction across the image
// Any errors here or am I doing this correctly?
Scalar avgHorizDir = mean(dX);
Scalar avgVertDir = mean(dY);
double avgDir = atan2(-avgVertDir[0], avgHorizDir[0]);


float blurriness = cv::videostab::calcBlurriness(src); // low values = sharper. High values = blurry

最佳答案

从技术上讲,这些是获得两个平均值的正确方法。

计算平均方向的方法使用加权方向统计,这意味着没有强梯度的像素对平均值的影响较小。

然而,对于大多数图像来说,这个平均方向并不是很有意义,因为在所有方向上都存在边缘并相互抵消。

如果您的图像是单边的,那么这会很有效。

如果您的图像中有线条,包含相反方向的边缘,这将不起作用。在这种情况下,您想要平均双角(平均方向)。这样做的明显方法是将每个像素的方向计算为一个角度,将它们加倍,然后使用方向统计进行平均(即转换回矢量并对其进行平均)。将角度加倍会导致相反的方向映射到相同的值,因此平均不会抵消这些。

另一种简单的方向平均方法是取梯度场与自身外积得到的张量场的平均值,确定最大特征值对应的特征向量的方向。张量场的获取方式如下:

Mat Sxx = dX * dX;
Mat Syy = dY * dY;
Mat Sxy = dX * dY;

这应该是平均的:

Scalar mSxx = mean(sXX);
Scalar mSyy = mean(sYY);
Scalar mSxy = mean(sXY);

这些值形成一个 2x2 实值对称矩阵:

|  mSxx   mSxy  |
| mSxy mSyy |

确定其特征分解相对简单,并且可以通过分析来完成。我现在手头没有方程式,所以我会把它作为练习留给读者。 :)

关于opencv - 你如何计算平均梯度方向和平均梯度强度/幅度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50316026/

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