gpt4 book ai didi

image - Matlab梯度和OpenCV梯度给出不同的结果

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

我正在尝试将 Matlab 代码转换为 OpenCV,它对输入图像进行梯度计算。但是对于完全相同的输入图像,结果矩阵是不同的。

这是我要转换的 Matlab 代码:

gradientsigma = 1;
sze = fix(6*gradientsigma); if ~mod(sze, 2); sze = sze + 1; end
f = fspecial('gaussian', sze, gradientsigma); % Generate Gaussian filter
[fx, fy] = gradient(f); % Gradient of Gaussian

Gx = filter2(fx, im); %Gradient of the image in x
Gy = filter2(fy, im); % ... and y

这是我写的 OpenCV 代码:

cv::Mat grad_x, grad_y;
cv::Sobel(im, grad_x, CV_32FC1, 1, 0, 3, 1, 0, cv::BORDER_DEFAULT);
cv::Sobel(im, grad_y, CV_32FC1, 0, 1, 3, 1, 0, cv::BORDER_DEFAULT);

但是,Gx 的输出是这样的:

% first four pixels
[-27.1851 -13.4271 -3.9532 -0.0000 ... ]
% last four pixels
[... -1.7701 2.3386 12.1671 26.4513]

这是 grad_x 的输出:

// first four pixels
[0, 0, 0, 0 ...]
// last four pixels
[... 20, 18, 14, 0]

是什么导致了这种差异?先感谢您。

最佳答案

Matlab 的梯度算法在某种程度上不同于 Sobel 滤波。有关用于 Matlab 的详细算法,请查看 here .

因此,您可以像这样在 OpenCV 中轻松实现该算法:

//image is your input image, I assume it is of float type
//xGradient is the gradient output calculated along x-direction
//yGradient is the gradient output calculated along y-direction
void gradient(cv::Mat image, cv::Mat xGradient, cv::Mat yGradient)
{
int rows = image.rows;
int cols = image.cols;

float xGrad = 0.0;
float yGrad = 0.0;

for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
if (j == 0)
{
xGrad = image.at<float>(i, j + 1) - image.at<float>(i, j);
}

else if (j == cols - 1)
{
xGrad = image.at<float>(i, j) - image.at<float>(i, j - 1);
}
else
{
xGrad = 0.5 * (image.at<float>(i, j + 1) - image.at<float>(i, j - 1));
}

if (i == 0)
{
yGrad = image.at<float>(i + 1, j) - image.at<float>(i, j);
}
else if (i == rows - 1)
{
yGrad = image.at<float>(i, j) - image.at<float>(i - 1, j);
}
else
{
yGrad = 0.5 * (image.at<float>(i + 1, j) - image.at<float>(i - 1, j));
}

xGradient.at<float>(i, j) = xGrad;
yGradient.at<float>(i, j) = yGrad;
} // end of j- loop
} // end of i-loop
} // end of gradient function definition

这给你的结果与 Matlab 的梯度函数完全相同。请记住,Matlab 会对结果进行四舍五入。例如,如果您在 OpenCV 中获得“0.00008562”,则在 Matlab 中将显示为“0.0001”。现在对于您的情况,您可以像这样使用它:

int sze = 6 * round(gradientsigma);

if (sze % 2 == 0)
{
sze += 1;
}

//Generate Gaussian filter
cv::Mat gaussKernelX = cv::getGaussianKernel(sze, gradientsigma, CV_32FC1);
cv::Mat gaussKernelY = cv::getGaussianKernel(sze, gradientsigma, CV_32FC1);
cv::Mat gaussKernel = gaussKernelX * gaussKernelY.t();

cv::Mat fx, fy;
cv::Mat kernelx = (cv::Mat_<float>(1, 3) << -0.5, 0, 0.5);
cv::Mat kernely = (cv::Mat_<float>(3, 1) << -0.5, 0, 0.5);
cv::filter2D(gaussKernel, fx, -1, kernelx);
cv::filter2D(gaussKernel, fy, -1, kernely);

gradient(gaussKernel, fx, fy); // Gradient of Gaussian

cv::Mat grad_x = cv::Mat::zeros(im.size(), CV_32FC1);
cv::Mat grad_y = cv::Mat::zeros(im.size(), CV_32FC1);

//Gradient of the image in x direction
cv::filter2D(im, grad_x, -1, fx, cv::Point(-1, -1), 0, cv::BORDER_DEFAULT);

//Gradient of the image in y direction
cv::filter2D(im, grad_y, -1, fy, cv::Point(-1, -1), 0, cv::BORDER_DEFAULT);

关于image - Matlab梯度和OpenCV梯度给出不同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28449024/

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