Reputation: 1763
I need to apply mean removal filter to an image with convolution.
The kernel is:
-1 -1 -1 k11 k12 k13
-1 9 -1 (coord) k21 k22 k23
-1 -1 -1 k31 k32 k33
Factor = 1, Offset = 0
If my matrix coordinates are
m11 m12 m13
m21 m22 m23
m31 m32 m33
1. In order to calculate the resulting pixel (from the center of matrix), shouldn't the formula look like this?
pixel = m11 * k11 + m12 * k12 + m13 * k13
+ m21 * k21 + m22 * k22 + m23 * k23
+ m31 * k31 + n32 * k32 + m33 * k33
pixel /= factor
pixel += offset
The image looks ok, but there are slight changes if I compare my filtered image to one filtered by other program by using diff
.
2. The new pixel value should be put back to the input matrix, so that it is used in the calculation of the next pixels?
3. Also, bonus question: If the number of pixels is the same, how is it possible that the filtered image has a different size?
Upvotes: 1
Views: 761
Reputation: 60444
The convolution is defined as
f is your image, and g is your kernel (or the other way around, really doesn't matter). The 2D case is similar, with t and τ being 2-vectors, and using a double integral. Note the different sign of τ in the evaluation of f and g. This implies that one of the two is being mirrored with respect to the other.
So your equation is strictly wrong. You are using a symmetric kernel, so there's no difference in mirroring, but the equation should read
pixel = m11 * k33 + m12 * k32 + m13 * k31
+ m21 * k23 + m22 * k22 + m23 * k21
+ m31 * k13 + n32 * k12 + m33 * k11
The offset
value plays no role in the convolution, and the factor
can be mixed in with the kernel values kxx
:
pixel = ( m11*k33 + m12*k32 + m13*k31 ) * factor
is the same as
pixel = m11*k33*factor + m12*k32*factor + m13*k31*factor
So you can just pre-multiply all kxx
with factor before you compute the convolution.
No, the new pixel value should be written to a new image. If you write it back to the input image, you'll be using that value when computing the result for the next pixel, so you'll get a wrong result.
The result of the convolution operation for a pixel at the edge of the image reads "out of bounds". It needs to read the value of the pixel outside the image. You can choose to read 0 there, or to fill the values in some other way. Some software instead chooses to not compute those pixels instead, yielding a smaller output image. Some software actually computes more pixels, if you extend the image with zeros, the result of the convolution at a pixel just outside the image will read some of the image's pixels at the edge.
MATLAB's conv2
function takes an optional argument that is one of 'full'
, 'same'
or 'valid'
. 'full'
, which is the default, does this last thing, where it computes the convolution at all locations where the image pixels have some influence. The output will be size(f)+size(g)-1
. 'valid'
produces a smaller image, where it doesn't need to read outside the image domain. 'same'
produces an image of the same size as the input image.
Upvotes: 2