带有内核的二维卷积,该内核不是中心发起的

我想用高斯核进行图像的2D卷积,高斯核不是由等式给出的中心起源:

h(x-x’,y-y’)= exp( – ((x-x’)^ 2 +(y-y’))/ 2 * sigma)

可以说内核的中心是(1,1)而不是(0,0)。 我应该如何更改以下代码以生成内核和卷积?

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 = 0 && ii = 0 && jj < v ) //out[i][j] += in[ii][jj] * (kernel[mm+nn*29]); out[i][j] += in[ii][jj] * (kernel[mm][nn]); } } } } } 

由于您使用的是卷积运算符,因此您有两种选择:

  1. 使用它的Spatial Invariant属性。
    为此,只需使用常规卷积滤波器(使用conv2imfilter更好地完成)计算图像,然后移动结果。
    你应该注意你要使用的边界条件(参见imfilter属性)。
  2. 具体计算移位结果。
    您可以按照建议循环执行此操作,或者更轻松地创建非对称内核并仍使用imfilterconv2

示例代码(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); 

棘手的部分是知道“裁剪”与第一个图像在同一轴上的第二个图像。
然后你会有一个转移的图像。
您可以使用任何内核和任何应用卷积的函数。

请享用。