In this exercise, you will explore some transformations on images
and get some practice working with 2D arrays. Essentially, you will
read in an input image and construct a "result" image from the
input image. To construct the (i,j)-th pixel in the
result image, you will take a weighted average of the intensity
values of the (i,j-th pixel in the original image and
the corresponding intensities of the pixels around the
(i,j)-th pixel of the original image.
Since each pixel, except for those at the borders, has
8 neighboring pixels and itself, we need a total of 9 weights.
These weights are themselves specified
in a 3 x 3 array. This smaller array is called a kernel
in the image processing jargon. For example, consider the kernel
double[][] someKernel = {
{0.1, 0.2, 0.3},
{0.1, 0.5, 0.2},
{0.1, -1, -0.5}
};
Now, suppose we are computing the Red pixel intensity for pixel
(25,53), i.e., the pixel in row 25, column 53 of the result.
This is what we do:
- We find the corresponding pixel in row 25, column 53 of
the original.
- We identify the neighboring pixels (there are eight of them).
- We look at their Red intensities: there are eight of them,
and the Red intensity of the pixel itself.
=>
A total of 9 Red intensities.
- We take a weighted average of these 9 intensities
=>
This gives us the Red intensity for the pixel in location
(25,53) of the result.
- This picture shows an example:
- Repeat the computation to get the Green intensity for the
result pixel, then the Blue intensity. Of course, for the
Green intensity, use the weighted average (same weights)
of the Green intensities of the original-image pixels.
Likewise for the Blue intensity.
Thus, the goal of the exercise is to do this computation for an
entire image and return the result image.
To get started:
- Download ImageTransformations.java
and ImageTool.java.
You will also need this JPEG image.
- Write all your code in ImageTransformations.java.
- In main(), you will see that test code has already
been written. You will need to write the method
applyKernel() in which all the computation is done.
Things to note:
- Don't worry about why we've used variable names like "lowPass"
or "highPass". This is image-processing terminology that's not
needed for the exercise.
- You should be able to deduce the signature of the method
applyKernel() from the way the method is invoked.
- Don't forget that pixel values must be in the range 0-255.
Thus, if the weighted average returns something else, you'll
have to force it in that range.
- Do not change the alpha value of each pixel, simply copy that
over to the right place in the corresponding result pixel.
Submission:
- Submit your file ImageTransformations.java using these
submission instructions.
Do NOT email your program.
- Answer the following questions (in English, in a file called
"Answers.txt" as part of your submission):
- What kind of image effect does the low-pass kernel achieve?
- What kind of image effect does the high-pass kernel achieve?
- Try both on a geometric image like that of a chessboard.
- Who is the person in the image?
- Aside from the kernels above, implement an image transformation of your own design,
to create some kind of image effect. This doesn't have to be
a kernel-based transformation. It can be anything you do
to a 2D array of pixels. Put this code in the same file and
write tests with "before" and "after" images to show your
transformation. Describe in comments what it does.
What else is due: