您好我必须使用以下内核对我的32位原始图像进行2D卷积
h(x,y)= a(b* exp^(-squareroot(x^2+y^2))
我不知道如何执行它,因为我不熟悉。我的图片尺寸是1024 * 768。我应该保持相同大小的内核并执行卷积,还是应该保留一个小内核?他们俩会有所作为吗?如果我保留一个小内核,我该如何用整个图像卷积它?
请帮忙
请检查生成内核的代码是否正确
谢谢你们两位回答。请你在下面查看生成内核然后卷积的代码。我不确定我做得对吗
int krowhalf = krow / 2,kcolhalf = kcol / 2;
// sum is for normalization
float sum = 0.0;
// generate kernel
for (int x = -krowhalf; x <= krowhalf; x++)
{
for(int y = -kcolhalf; y <= kcolhalf; y++)
{
r = sqrtl(x*x + y*y);
gKernel[x + krowhalf][y + kcolhalf] = a*(b*exp(-(r));
sum += gKernel[x + krowhalf][y + kcolhalf];
}
}
//normalize the Kernel
for(int i = 0; i < krow; ++i)
for(int j = 0; j < kcol; ++j)
gKernel[i][j] /= sum;
float **convolve2D(float** in, float** out, int h, int v, float **kernel, int kCols, int kRows)
{
int kCenterX = kCols / 2;
int kCenterY = kRows / 2;
int i,j,m,mm,n,nn,ii,jj;
for(i=0; i < h; ++i)
// rows
{
for(j=0; j < v; ++j)
// columns
{
for(m=0; m < kRows; ++m) // kernel rows
{
mm = kRows - 1 - m; // row index of flipped kernel
for(n=0; n < kCols; ++n) // kernel columns
{
nn = kCols - 1 - n; // column index of flipped kernel
//index of input signal, used for checking boundary
ii = i + (m - kCenterY);
jj = j + (n - kCenterX);
// ignore input samples which are out of bound
if( ii >= 0 && ii < h && jj >= 0 && jj < v )
//out[i][j] += in[ii][jj] * (kernel[mm+nn*29]);
out[i][j] += in[ii][jj] * (kernel[mm][nn]);
}
}
}
}
退出; }
答案 0 :(得分:0)
您知道如何进行一维信号卷积吗?你的过滤器总是有限长度。你无法使用数字计算机进行无限卷积。二维滤波器也总是有限长度。例如,最简单的2-D滤波器拉普拉斯算子之一只有3X3大小。过滤器越长,处理就越复杂。
答案 1 :(得分:0)
使用非常大的内核(这将是理论上的确切结果)需要永远,所以通常你需要3x3或5x5,除非你真的需要精确的东西。如果您使用有限精度的常规浮点数,则不太可能产生影响。
卷积可以通过两个简单的for循环遍历每个点。对于边缘,一种简单的方法是扩展图像(例如,如果使用3x3,则每边添加一个像素)并从旧边缘开始循环。
代码发布后编辑:
在循环代码中使用ifs将阻止编译器使用更快的指令(除非编译器非常智能)同时计算更多的点。这一行:
out[i][j] += in[ii][jj] * (kernel[mm][nn]);
可能由编译器转换为使用SIMD指令同时计算4个值。正因为如此,通常更有效的是在边缘添加填充零并且不要将内核置于这些点上。
答案 2 :(得分:0)
有许多方法可以计算高斯滤波器(这是图像处理中的基本滤波器)。这取决于您对性能的要求以及您希望支持的内核大小范围。
OpenCV和Intel IPP支持此过滤器,您可以轻松地在Web上找到开源。您还可以查看Deriche(递归实现高斯及其衍生物)和van Vliet(高斯滤波器的递归实现)特殊算法:它们设法计算每个像素具有固定操作数的滤波器,无论大小如何
您的实施似乎是正确的。无论如何,我建议你使用滤镜的可分性属性:2D高斯是通过1D水平高斯,然后是1D垂直(e^-(X²+Y²)=e^-X².e^-Y²
)获得的。这样,您只需要krow x kcol
个像素,而不是krow + kcol
每个像素的操作,这是一个显着的节省。