Photographs are often a mess. Sometimes there's a a hair or a scratch on the negative when you print a photograph. Still photographs taken from television broadcasts or from worn video tapes are often filled with static. Even photos taken with digital cameras might show signs of scratches or smudges on the lens. There are many ways an image can accumulate pixels that show "noise" instead of the intended subject.
One way to eliminate some kinds of noise is a median filter. The idea behind a median filter is that most pixels are surrounded by pixels of the same or similar color. If one pixel has an unexpected color (white for a scratch on the lens or black for a hair on the negative, for example), the surrounding pixels are probably still okay. If we somehow let a pixel's neighbors vote on the pixel's proper color, we might be able to get rid of noisy pixels.
Here's one way to arrange such a vote. Start with a grayscale image. Cycle through all
the pixels in the image with the usual double loop over the rows and columns of the image.
For each pixel P
:
P
. The neighborhood could be
a square of a particular radius, for example, where the radius-1 neighborhood would consist of
P
itself plus the eight surrounding pixels.P
.The left image below is a gray version of our old standard photo from the London Underground, with some artificial scratching added to. Using the median filter described above, with radius-1 square neighborhoods, we get the image on the right. At the cost of a bit of blurring and flattening of the grays, we have nearly eliminated the severe damage of the diagonal scratches.
It's interesting to see that some images clean up better than others. In this scene from a spring break past, for example, the same median filter doesn't do nearly as good a job of fixing the problem (any ideas why?).
For this assignment, write a class called ImageProcessor3
. You may,
if you wish, copy your ImageMultiProcessor
class and just add to it.
In any case, your class should include:
public ImageProcessor3( String filename ) throws IOException
public void scratch()
public void filter( int radius )
public void gray()
gray
method from the last image processing
assignment.Pixel
to store the row, column, and gray value of a single pixel.
Then you could use an ArrayList<Pixel>
to store
and sort the neighborhood.ArrayList
class has a clear
method that allows you to start over with an empty list.