[英]Generated gaussian kernel saturates the image to white color with opencv in C++
I'm trying to implement a function that gives me the Gaussian kernel given a certain standard deviation and dimensions.我正在尝试实现一个 function,在给定特定标准偏差和维度的情况下,它会给出高斯 kernel。 The output of the function seems correct, but when I apply it using the cv::filter2D function the result I obtain is quite strange.
function 的 output 似乎是正确的,但是当我使用 cv::filter2D function 应用它时,我得到的结果很奇怪。 The values saturate to maximum, giving a white color.
这些值饱和到最大值,呈现白色。
The implementation of the function that generates the kernel is the following:生成 kernel 的 function 的实现如下:
cv::Mat gaussKernel(int kernel_size, float stdDev)
{
// For now, only odd kernel_size values
std::default_random_engine generator;
std::normal_distribution<float> distribution(0, stdDev);
float sum_term {0};
cv::Mat kernel = cv::Mat::zeros(kernel_size, kernel_size, CV_32F);
// Create kernel
for (int i = -kernel_size/2; i <= kernel_size/2; i++)
{
for (int j = -kernel_size/2; j <= kernel_size/2; j++)
{
kernel.at<float>(i + kernel_size/2,j + kernel_size/2) = std::exp(-(pow(i,2) + pow(j,2))/(2*pow(stdDev,2)));
sum_term += kernel.at<float>(i + kernel_size/2,j + kernel_size/2);
}
}
kernel /= sum_term;
std::cout << "The kernel is: " << std::endl;
for (int i = 0; i < kernel.rows; i++)
{
std::cout << " ";
for (int j = 0; j < kernel.cols; j++)
{
std::cout << kernel.at<float>(i,j) << ", ";
}
std::cout << std::endl;
}
return kernel;
}
All is being done with greyscale pictures.所有这些都是用灰度图片完成的。 I expect the error to be related to the codification used in the kernel matrix, but I have tested some stuff and received no result.
我预计错误与 kernel 矩阵中使用的编码有关,但我已经测试了一些东西但没有收到任何结果。
--Edit: Value of stdDev = 1; --编辑:stdDev = 1 的值; Value of kernel_size = 3;
kernel_size = 3 的值;
Image: Link to image图片:图片链接
Part of the code related to reading or modifications of the image:与读取或修改图像相关的部分代码:
std::string dir {"../resources/ORings/ORing01.jpg"};
cv::Mat original, customKernel;
original = cv::imread(dir);
cv::Mat noisy = original.clone();
cv::Mat clean_1 = original.clone();
customKernel = gauss::gaussKernel(kernel_size, 1);
noisy = gauss::addGaussianNoise(noisy, SNR);
cv::filter2D(clean_1, clean_1, CV_32F, customKernel, cv::Point(-1,-1), 0, cv::BORDER_DEFAULT);
The cause of the problem is setting the ddepth
argument of cv::filter2D
to CV_32F
.问题的原因是将
cv::filter2D
的ddepth
参数设置为CV_32F
。
Setting the argument value to -1
solves the issue:将参数值设置为
-1
可解决问题:
cv::filter2D(clean_1, clean_1, -1, customKernel, cv::Point(-1,-1), 0, cv::BORDER_DEFAULT);
Setting ddepth
argument to CV_32F
causes the output type of cv::filter2D
to be CV_32F
(pixels of type float
).将
ddepth
参数设置为CV_32F
会导致 output 类型的cv::filter2D
为CV_32F
(类型为float
的像素)。
The values of the output are in range [0, 255] (same range as the input). output 的值在 [0, 255] 范围内(与输入范围相同)。
OpenCV convention for pixels of type CV_32F
(float) is that black is 0
and white is 1
. OpenCV
CV_32F
(浮点)类型像素的约定是黑色为0
白色为1
。 Values above 1.0 are also white.高于 1.0 的值也是白色的。
There are 3 relevant solutions I can think of:我能想到 3 个相关的解决方案:
CV_8U
(same as the input), by setting ddepth
to -1
.ddepth
设置为-1
来保持 output CV_8U
的类型(与输入相同)。customKernel /= 255.0f;
customKernel /= 255.0f;
. clean_1 /= 255.0f;
clean_1 /= 255.0f;
.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.