| Image
Processing Articles
Index |
 |
| Convolution
is a simple mathematical
operation which is
fundamental to many
common image processing
operators. Convolution
provides a way of
`multiplying together'
two arrays of numbers,
generally of different
sizes, but of the
same dimensionality,
to produce a third
array of numbers of
the same dimensionality.
This can be used in
image processing to
implement operators
whose output pixel
values are simple
linear combinations
of certain input pixel
values. |
 |
| In
an image processing
context, one of the
input arrays is normally
just a graylevel image.
The second array is
usually much smaller,
and is also two-dimensional
(although it may be
just a single pixel
thick), and is known
as the kernel. The
following image shows
an example image and
kernel that we will
use to illustrate
convolution. |
 |
 |
 |
| The
convolution is performed
by sliding the kernel
over the image, generally
starting at the top
left corner, so as
to move the kernel
through all the positions
where the kernel fits
entirely within the
boundaries of the
image. (Note that
implementations differ
in what they do at
the edges of images,
as explained below.)
Each kernel position
corresponds to a single
output pixel, the
value of which is
calculated by multiplying
together the kernel
value and the underlying
image pixel value
for each of the cells
in the kernel, and
then adding all these
numbers together. |
 |
| So,
in our example, the
value of the bottom
right pixel in the
output image will
be given by: |
 |
 |
 |
| If
the image has M rows
and N columns, and
the kernel has m rows
and n columns, then
the size of the output
image will have M
- m + 1 rows, and
N - n + 1 columns. |
 |
| Mathematically
we can write the convolution
as: |
 |
 |
 |
| where
i runs from 1 to M
- m + 1 and j runs
from 1 to N - n +
1. |
 |
| Note
that many implementations
of convolution produce
a larger output image
than this because
they relax the constraint
that the kernel can
only be moved to positions
where it fits entirely
within the image.
Instead, these implementations
typically slide the
kernel to all positions
where just the top
left corner of the
kernel is within the
image. Therefore the
kernel `overlaps'
the image on the bottom
and right edges. One
advantage of this
approach is that the
output image is the
same size as the input
image. Unfortunately,
in order to calculate
the output pixel values
for the bottom and
right edges of the
image, it is necessary
to invent input pixel
values for places
where the kernel extends
off the end of the
image. Typically pixel
values of zero are
chosen for regions
outside the true image,
but this can often
distort the output
image at these places.
Therefore in general
if you are using a
convolution implementation
that does this, it
is better to clip
the image to remove
these spurious regions.
Removing n - 1 pixels
from the right hand
side and m - 1 pixels
from the bottom will
fix things. |
 |
| How
It Works: |
 |
| The
effect of a simple
Mask: |
 |
 |
 |
| On
the Image: |
 |
 |
 |
| The
result after convolution
is as: |
 |
 |
 |
| Sample
Project: |
| For
understanding Convolution
and its concepts,
lets make a Class
of CSharpMask First
as: |
 |
public
class CSharpMask
{ public
int TopLeft=0,TopMid=0,TopRight=0;
public
int MidLeft=0,Pixel=1,MidRight=0;
public
int BottomLeft=0,BottomMid=0,BottomRight=0;
public
int Factor=1;
public
int Offset=0;
public
void setAll(int
nVal)
{
TopLeft=TopMid=TopRight=MidLeft=Pixel=MidRight=BottomLeft=BottomMid=BottomRight=nVal;
} public
CSharpMask()
{ //
// TODO: Add constructor
logic here
//
}
} |
 |
This
class would be used
in all of the articles
we will be writing
after this simple
one in order to illustrate
the basics of every
operator.
See Line #: 55 in
the class ConvOperation
nPixel=(((pOutPut[2]*m.TopLeft)+(pOutPut[5]*m.TopMiddle)+(pOutPut[8]*m.TopRight)+
(pOutPut[stride+2]*m.MiddleLeft)+(pOutPut[stride+5]*m.Pixel)+(pOutPut[stride+8]*m.MiddleRight)
+(pOutPut[stride2+2]*m.BottomLeft)+(pOutPut[stride2+5]*m.BottomMiddle)+(pOutPut[stride2+8]*m.BottomRight))/m.Factor)+m.Offset; |
 |
| This
is the most important
thing to understand
here. We are now applying
the mask on the pixel.
This is the Red Pixel.
Actully at the end
of the RGB series
as it is stored BGR.
It is shown as : |
 |
| pOutPut[2] |
pOutPut[5] |
pOutPut[8] |
| pOutPut[stride+2] |
pOutPut[stride+5] |
pOutPut[stride+8] |
| pOutPut[stride2+2] |
pOutPut[stride2+5] |
pOutPut[stride2+8] |
|
 |
| The
Mask being Applied
is also given as: |
 |
| TopLeft
|
TopMiddle
|
TopRight
|
|
MiddleLeft
|
Pixel
|
MiddleRight
|
|
BottomLeft
|
BottomMiddle
|
BottomRight
|
|
 |
| The
GUI of the whole Project
is as: |
 |
 |
 |
Download
Project Files
 |
 |
| Image
Processing Articles
Index |