作为序言,这是一个家庭作业问题,但我已经完成了它,它只是很慢。这与报告无关。但无论如何我都想加快速度。
所以我试图将高斯模糊应用于图像
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);
在同一张图片上不到四分之一秒。
我可以做些什么来加快这个过程?我已经阅读了一些关于应用两个1-d滤波器的内容,但老实说我真的无法理解这一切。我还读过一些关于对图像和滤波器进行FFT,乘以它们然后进行IFFT的看法,但我不认为我想在这里做什么:我发现提到的资源只是'在更大的过滤器方面更有效率。
答案 0 :(得分:3)
我的几分钱:
r
和c
,以便了解行和列是什么。从长远来看,它会对你有所帮助。cv::Mat::ptr()
的当前行的地址,以至少在列索引中保存一些计算。答案 1 :(得分:3)
除了@CostantinoGrana的答案之外,我想指出2D高斯平滑是线性可分的。您可以使用2个1D内核,而不是使用2D内核 - 首先通过行,第二个通过列。
此外,如果您可以访问多个核心,则可以并行对行/列执行1D过滤。请参阅cv::parallel_for_
构造。