如前所述,这是一道作业题,不过我已经做完了,就是慢了点。这与报告无关。但无论如何我都在努力加快速度。
所以我想对图像应用高斯模糊
const unsigned char KERNAL_SIZE = 5;
const unsigned char KERNAL_MEAN = KERNAL_SIZE / 2;
const unsigned char GaussianBlurKernal[KERNAL_SIZE][KERNAL_SIZE] =
{ { 1, 4, 7, 4, 1 },
{ 4, 16, 26, 16, 4 },
{ 7, 26, 41, 26, 7 },
{ 4, 16, 26, 16, 4 },
{ 1, 4, 7, 4, 1 }
};
const int GAUSSIAN_KERNAL_SIZE = 273;
并执行以下代码:
Mat CustomGuassianBlur(const Mat & inputImage)
{
Size maxSize = inputImage.size();
Mat outputImage(maxSize, CV_8UC1, Scalar(0, 0, 0));
for (int i = 0; i < maxSize.width; i++)
{
for (int j = 0; j < maxSize.height; j++)
{
unsigned int sum = 0;
for (int k = -KERNAL_MEAN; k <= KERNAL_MEAN; k++)
{
for (int l = -KERNAL_MEAN; l <= KERNAL_MEAN; l++)
{
Point imagePoint = { (i + l + maxSize.width) % maxSize.width, (j + k + maxSize.height) % maxSize.height };
sum = sum + inputImage.at<uchar>(imagePoint) * GaussianBlurKernal[k + KERNAL_MEAN][l + KERNAL_MEAN];
}
}
sum = sum / GAUSSIAN_KERNAL_SIZE;
outputImage.at<uchar>(j, i) = uchar(sum);
}
}
return outputImage;
}
过滤器大约需要 8 秒。我试图近似的 OpenCV 代码:
GaussianBlur(src_gray, detected_edges, Size(5, 5), 0, 0);
在同一张图片上用时不到四分之一秒。
我可以做些什么来加快这个过程?我读过一些关于应用两个一维滤波器的内容,但老实说我不太理解。我也读过一些关于对图像和滤波器进行 FFT、将它们相乘、然后进行 IFFT 的内容,但我认为这不是我想在这里做的事情:我发现的资源只是提到了当涉及到更大的过滤器时效率更高。
最佳答案
我的几分钱:
- 请将您的索引变量命名为
r
和c
以便您知道什么是行什么是列。从长远来看,它将对您有所帮助。 - 内核?这不应该是KERNEL吗?或者这是另一种语言?
- 记住您的缓存:您的矩阵以行优先顺序存储,因此每一行都要经过每一列。
- 如果您的内核大小是固定的,请展开内部双循环。
- 如果您的内核大小必须更改,请使用
cv::Mat::ptr()
获取当前行的地址。在一个内部循环中至少在列索引中节省一些计算。 - 模数宽度和高度听起来不对。您正在使用环形图像表示。不寻常。
关于c++ - 图像卷积与高斯模糊,加速可能吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46897509/