Assignment 1: Image Processing
Due: Thurs 27
September 2001 at 11:59PM.
class results
Overview
In this assignment you will create a simple image processing program. The
operations that you implement will be mostly filters which take an input
image, process the image, and produce an output image.
Getting Started
You should use the following skeleton code (1.zip or 1.tar.gz ) as a starting point for your assignment.
We provide you with several files, but you should mainly change image.cpp.
-
main.cpp: Parses the command line arguments, and
calls the appropriate image functions.
-
image.[cpp/h]: Image processing.
-
pixel.[cpp/h]: Pixel processing.
-
vector.[cpp/h]: Simple 2D vector class you may find
useful.
-
bmp.[cpp/h]: Function to read and write Windows BMP
files.
-
Makefile: A Makefile suitable for UNIX platforms.
-
visual.dsp: Project file suitable for Visual C++ on Windows 2000 platform.
You can find test images at /u/cs426/images
(on the CIT accounts -- eg arizona).
After you copy the provided files to your directory, the first thing
to do is compile the program. If you are developing on a Windows NT machine,
double click on visual.dsp and select build from the build menu.
If you are developing on a UNIX machine, type make.
In either case an executable called image will be created.
How the Program Works
The user interface for this assignment was kept to the simplest possible,
so you can concentrate on the image processing issues. The program runs
on the command line. It reads an image from the standard input, processes
the image using the filters specified by the command line arguments, and
writes the resulting image to the standard output. For example, to increase
the brightness of the image in.bmp by 10%, and save the result in the image
out.bmp, you would type:
% image -brightness 1.1 < in.bmp > out.bmp
For each available image filter there is a corresponding optional argument.
To see the complete list of options, type:
% image -help
If you specify more than one option, the options are processed in the order
that they are found. For example,
% image -contrast 0.8 -scale 0.5 0.5 < in.bmp > out.bmp
would first decrease the contrast of the input image by 20%, and then scale
down the result by 50% in both x and y directions. Another way of doing
the same thing would be
% image -contrast 0.8 | image -scale 0.5 0.5 < in.bmp > out.bmp
which uses pipes instead of multiple options per command line. The ability
to use pipes can be used to avoid creating temporary files. For example,
% image -contrast 0.8 | image -scale 0.5 0.5 < in.bmp | xv -
does the same thing as the previous command, but it redirects the final
output to be the input of xv, which simply shows you the result
on the screen, without creating any temporary files in your directory.
Another advantage of this kind of interface is that you can combine
different filters in shell scripts, and automate image processing steps,
which can save you time.
What You Have to Do
The assignment is worth 20 points. The following is a list of features
that you may implement (listed roughly from easiest to hardest). The number
in front of the feature corresponds to how many points the feature is worth.
The features in bold face are required. The other ones are optional.
Refer to this web page for more details on
the implementation of each filter and example output images.
-
(1/2) Random noise: Add noise to an image.
-
(1/2) Brighten: Individually scale the RGB channels of an
image.
-
(1/2) Contrast: Change the contrast of an image. See Graphica
Obscura.
-
(1/2) Saturation: Change the saturation of an image. See Graphica
Obscura.
-
(1/2) Crop: Extract a subimage specified by two
corners.
-
(1/2) Extract Channel: Leave specified channel intact
and set all others to zero.
-
(1) Quantize: Change the number of bits per channel of an
image, using simple rounding.
-
(1) Random dither: Convert an image to a given number
of bits per channel, using a random threshold.
-
(1) Composite: Composite
one image with a second image, using a third image as a matte.
-
(1) Create a composite image of yourself and a famous
person.
-
(2) Blur: Blur an image
by convolving it with a Gaussian low-pass filter.
-
(2) Edge detect: Detect edges in an image by
convolving it with an edge detection kernel.
-
(2) Ordered dither: Convert an image to a given
number of bits per channel, using a 4x4 ordered dithering matrix.
-
(2) Floyd-Steinberg dither: Convert an image to a given number of bits per channel, using
dithering with error diffusion.
-
(2) Scale: Scale an image
up or down by a real valued factor.
-
(2) Rotate: Rotate an image by a given angle.
-
(2) Fun: Warp an image
using a non-linear mapping of your choice (examples are fisheye, sine, bulge,
swirl).
-
(3) Morph: Morph two images using the method in Beier & Neeley's ``Feature-based
Image Metamorphosis.''
-
(up to 3) Nonphotorealism: Implement any non-trivial painterly filter.
For inspiration, take a look at the effects available in programs like
xv, PhotoShop, and Image Composer (e.g., impressionist, charcoal, stained
glass, etc.). The points awarded for this feature will depend on
the creativity and difficulty of the filter. At most one such filter
will receive points.
For any feature that involves resampling (i.e., scale, rotate, "fun," and
morph), you have to provide three sampling methods: point sampling, bilinear
sampling, and Gaussian sampling.
By implementing all the required features, you get 12 points. There
are many ways to get more points:
-
(as listed above) implementing optional features ,
-
(1) submitting one or more images for the art
contest,
-
(1) submitting a .mpeg movie animating the results of
one or more filters with continuously varying parameters (e.g., use the
makemovie command on the SGIs),
-
(2) winning the art contest.
For images or movies that you submit, you also have to submit the sequence
of commands used to created them, otherwise they will not be considered
valid.
It is possible to get more than 20 points. However, after 20 points,
each point is divided by two, and after 22 points, each point is divided
by four.
What to Submit
You should submit one
archive (zip or tar file) containing:
- the complete source code with a Visual C project file
-
the .bmp images (sources, masks, and final) for the
composite feature,
-
the .mpeg movie for the movie feature (optional),
-
the images for the art contest (optional), and
-
a writeup.
The writeup should be a HTML document called assignment1.html
which may include other documents or pictures. It should be brief, describing
what you have implemented, what works and what doesn't, how you created
the composite image, how you created the art contest images, and instructions
on how to run the fun filters you have implemented.
Make sure the source code compiles in the MECA
workstations. If it doesn't, you will have to attend to a grading session
with a TA, and your grade will suffer.
Always remember the late policy
and the collaboration
policy.
Hints
-
Do the simpler filters first!
-
Look at the example pages here and here.
-
There are functions to manipulate pixel components and pixels in
image.[ch]. You may
find them helpful while writing your filters.
-
There are functions to manipulate 2D vectors in
vector.[ch]. You may find them helpful
while writing the morphing functions.
-
Post questions to the pu.cs.426 newsgroup.
-
Stay tuned for more hints.
FAQ
-
The compose image parameters don't make sense.
-
We are using PixelOver operator for composing images. Unfortunately,
the bmp format doesn't store alpha values, so we need a way of getting
alpha values for both the top and bottom image. The way we are doing
this is by loading another image and treating its blue channel as the alpha
value (see the function SetImageMask in main.cpp). So... we need
4 images: top, top_mask, bottom, bottom_mask. top is the current
image that's already loaded, so the ComposeImage option takes the remaining
3 filenames as input. In the parameter section of main.cpp these
4 images are put together to create two images (main.cpp, lines 148-170)
with the alpha values filled in, which is then passed to the ComposeImage
function that you write in image.cpp. The three parameters of ComposeImage
are stylistic, you could get away with two, or return an image pointer,
or something equivalent.
-
For the quantization function, can we safely assume
that the image channels for input are always 8 bit and not any greater?
-
For the quantization function, should we assume that
the number of bits to which we're quantizing is always a multiple of 3?
-
No. The parameter is the number of bits per channel, not per pixel.
-
I get error messages and a core dump when the program
tries to read in my bmp files. What should I do?
-
Make sure your files are 24-bit, uncompressed bitmaps. The provided code
does not read any other kind of files. If you are using xv: right-click
to open the xv controls window, then click on the 24/8 Bit
menu-button, then select the 24-bit mode option. Alt-8 toggles between
8-bit and 24-bit mode
-
Under windows, the error msg:
Assertion failed: bmih.biSizeImage == (DWORD) lineLength * (DWORD) bmih.biHeight, file c:\temp\one\1\bmp.cpp, line 252
means the image is not correctly formatted. One solution is to open the image, save it a .jpg then save as back to .bmp.
-
Stay tuned for more questions.
Announcements
-
Stay tuned for more announcements.
Last update: 09/13/01
03:54
PM