When applying Gaussian filters close to the borders of an image, algorithms usually zero-pad or replicate/mirror/wrap the borders. This is not good enough for my case, so I wonder if there is something better out there.
As the idea of smoothing is to absorb the information of surrounding points, I wonder if it would make sense to use a different kernel in the border cases. This kernel would only take values from available surrounding points, e.g. if my kernel is something like:
\begin{bmatrix} 0.0113 & 0.0838 & 0.0113 \\ 0.0838 & 0.6193 & 0.0838 \\ 0.0113 & 0.0838 & 0.0113 \end{bmatrix}
To calculate a pixel on the top margin (but not close to the corner), I would use
\begin{bmatrix} 0.0938 & 0.6933 & 0.0938 \\ 0.0126 & 0.0938 & 0.0126 \end{bmatrix}
The latter matrix was calculated by cropping out the part of the kernel that would be out of the image (the top row) and renormalizing. Is there something wrong with this approach, or an alternative?
Here's some code to explain my idea better:
kernel = [0.0113 0.0838 0.0113; 0.0838 0.6193 0.0838; 0.0113 0.0838 0.0113]
kernel2 = [0.0938 0.6933 0.0938; 0.0126 0.0938 0.0126];
M = [1 2 3; 4 5 6]; % my image
% application of kernel to point 2 in M would provide the value:
res1 = sum(sum( kernel(2:3,:).*M )); % 0 padding, equals 2.1058
res2 = sum(sum( kernel.*[1 2 3; M] )); % row replication, equals 2.3186
% application of kernel2 to the same point:
res3 = sum(sum( kernel2 .* M )); % equals 2.3568
Note that in using kernel2
I don't extrapolate a row of [0 0 0]
or [1 2 3]
, which would underestimate the point.