带有内核的二维卷积,该内核不是中心发起的 [英] 2D convolution with a with a kernel which is not center originated
问题描述
我想用高斯内核对图像进行二维卷积,而高斯内核不是由公式给出的中心起源:
I want to do 2D convolution of an image with a Gaussian kernel which is not centre originated given by equation:
h(x-x',y-y ')= exp( - ((x-x')^ 2+(y-y'))/ 2 * sigma)
h(x-x', y-y') = exp(-((x-x')^2+(y-y'))/2*sigma)
让我们说内核的中心是(1,1)代替(0,0)。我应该如何更改以下代码以生成内核和卷积?
Lets say the centre of kernel is (1,1) instead of (0,0). How should I change my following code for generation of kernel and for the convolution?
int krowhalf=krow/2, kcolhalf=kcol/2;
int sigma=1
// 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-1)*(x-1) + (y-1)*(y-1));
gKernel[x + krowhalf][y + kcolhalf] = exp(-(r*r)/(2*sigma));
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]);
}
}
}
}
}
推荐答案
由于您使用的是卷积运算符,因此您有两种选择:
Since you're using the convolution operator you have 2 choices:
- 使用它是空间不变属性。
为此,只需使用常规卷积滤波器计算图像(使用conv2
或更好地完成imfilter
)然后移动结果。
您应该注意您要使用的边界条件(参见imfilter
属性)。 - 具体计算移位结果。
您可以按照建议循环执行此操作,或者更轻松地创建非对称内核并仍然使用imfilter
或conv2
。
- Using it Spatial Invariant property.
To so so, just calculate the image using regular convolution filter (Better done using eitherconv2
orimfilter
) and then shift the result.
You should mind the boundary condition you'd to employ (Seeimfilter
properties). - Calculate the shifted result specifically.
You can do this by loops as you suggested or more easily create non symmetric kernel and still useimfilter
orconv2
.
示例代码(MATLAB)
Sample Code (MATLAB)
clear();
mInputImage = imread('3.png');
mInputImage = double(mInputImage) / 255;
mConvolutionKernel = zeros(3, 3);
mConvolutionKernel(2, 2) = 1;
mOutputImage01 = conv2(mConvolutionKernel, mInputImage);
mConvolutionKernelShifted = [mConvolutionKernel, zeros(3, 150)];
mOutputImage02 = conv2(mConvolutionKernelShifted, mInputImage);
figure();
imshow(mOutputImage01);
figure();
imshow(mOutputImage02);
棘手的部分是知道裁剪与第一张图像在同一轴上的第二张图像。
然后你会有一个移位的图像。
你可以使用任何内核和任何应用卷积的函数。
The tricky part is to know to "Crop" the second image in the same axis as the first.
Then you'll have a shifted image.
You can use any Kernel and any function which applies convolution.
享受。
这篇关于带有内核的二维卷积,该内核不是中心发起的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!