ES 314 Advanced Programming, Modeling and Simulation Fall 2008
Project
# 1
Due:
September 29, 2008
Problem Statement: Write a C++ program to perform the following operations
on an image: (a) add a text label at the North-East corner as foreground and
(b) perform an image filtering operation. The filtering operation we are
interested in called the median-filtering operation and its removes random
noise in the image.
The following figure
illustrates the input and the output files for operation (a):
The next pair of
images show the input and output of the median-filter.
Goals of the project:
EasyBMP
library:
EasyBMP is a library
written in C++ that provides support for opening an image (in the BMP format),
and manipulate the individual pixels of the image. You don’t have to know the
details of how a BMP image is stored in a file. It is enough to know how to
make calls to EasyBMP functions. The following are
some useful classes and functions from the EasyBMP
library:
If you are unclear about any of these
functions, the manual EasyBMP_UserManual.pdf may be
useful and can be found in http://easybmp.sourceforge.net/documentation.html.
The manual also contains some examples with source code.
In the following, a simple example is presented
to illustrate how to use EasyBMP.
Suppose we want to convert a color image or a
gray scale image into black and white. This is a tricky process, but a very
important one – for example when we want to print a color photo on a black and
white printer, we need such an algorithm. We will use a very simple-minded
algorithm called thresholding. Recall that
each color pixel is defined by three color components (R, G, B), each taking a
value between 0 and 255. R = G = B = 255 is white, R = G = B = 0 is
black. In thresholding, the average the color
components of a pixel (i.e., compute (R + G + B)/3) is computed and if this
average exceeds 127, this pixel to mapped to white, otherwise it is mapped to
black. In the code below, we take a weighted average by weighting the colors by
0.3, 0.6 and 0.1 (since green is the most sensitive and blue is the least
sensitive.) We present the code to implement this algorithm below.
An example of input/output is shown below.
The code is as follows:
#include "EasyBMP.h"
using
namespace std;
int main( int
argc, char* argv[] )
{
BMP Background;
Background.ReadFromFile(argv[1]);
BMP Output;
int
picWidth = Background.TellWidth();
int
picHeight = Background.TellHeight();
Output.SetSize(picWidth, picHeight);
Output.SetBitDepth(1);
for (int i = 1; i
< picWidth-1; ++i)
for (int j = 1; j < picHeight-1; ++j) {
Output(i,j)->Red = 0;
Output(i,j)->Blue = 0;
Output(i,j)->Green = 0;
}
for (int i = 1; i
< picWidth-1; ++i)
for (int j = 1; j < picHeight-1; ++j) {
int col = 0.1* Background(i, j)->Blue +
0.6*Background(i,j)->Green +0.3* Background(i,j)->Red;
if
(col > 127) {
Output(i,j)->Red = 255;
Output(i,j)->Blue = 255;
Output(i,j)->Green = 255;
}
}
Output.WriteToFile(argv[2]);
return 0;
}
The
resulting b/w image is smaller in size. It also looks like hand-drawn.
Solution
to the two problems:
Problem
(1)
To
label the given image with a given text, you need access to a bit-map image of
each letter. For the purpose of this lab, you can assume that the font size of
the letters in the label is fixed. (i.e., you will not be required to rescale
the font files.) We will assume that the label consists of an alphabetical
symbol or a blank space. Also assume that the font images are black in color
with black background. The font images will be provided to you. The basic idea
is to first copy the background image onto a buffer. Then, your program should
overwrite the pixels on the upper-right corner by copying the bit-map images
corresponding to the label. For example, if the label is the word “text”, your
program will calculate the position in which each of the letters t, e, x and t
should be written. It should then copy the image t.bmp, e.bmp etc. in the appropriate position. Note that
when your write a letter, only the letter (not the background) should be
copied. You can assume that the heights of all the font images are the same.
However, they have varying widths so your program should use the width
information to ensure a uniform spacing between letters. If the space needed to
typeset the label exceeds the width of the image, your program should display
an error message and terminate without adding any text to the image.
Problem
(2)
The idea behind median-filter is simple.
Assume that only a small number of pixels have been affected by the random
noise. Consider a pixel p that has been changed by the noise. A reasonable
choice for the correct value of this pixel is the median of 9 pixels – itself
and the 8 neighboring pixels. This guess will be incorrect only under the
following situations: (a) the pixel was actually not affected by noise, and its
color value is significantly different from that of its neighbors, (b) more
than half of the pixels surrounding the current pixel have been corrupted by
noise. Since both these events are low probability events, the algorithm is
likely to replace most of the noisy pixel values by a value that is close to
the correct one.
The algorithm is described below:
I = input image; O = output image;
w = width of the image;
h = height of the image;
for
j from 0 to w-1 do
O(0,j)->Blue
= I(0,j)->Blue; // etc. for all colors
end
for;
for
k from 0 to h-1 do
O(k,0)->Blue
= I(k,0)->Blue; // etc. for all colors
end
for;
for
j from 1 to w-2 do
for
k from 1 to h-2 do
O(j,k)->Blue =
(I(j,k)->Blue + I(j-1,k)->Blue + I(j+1,k)->Blue
+ I(j,k-1)->Blue
+ I(j-1,k-1)->Blue+ I(j+1,k-1)->Blue
+I(j,k+1)->Blue
+ I(j-1,k+1)->Blue+ I(j+k+1)->Blue)/9;
. . . . //
similarly for other colors
end
for;
end
for;
What
should be submitted?
When
your program is run (after compiling it through the makefile
you submit), it should take as input several image files, and produce as output
three image files. The names of the main image files are in1.bmp
and in2.bmp; in addition, your program will use a.bmp, b.bmp,
… , z.bmp and space.bmp – all stored in the current directory.
After
compiling, suppose the object code is named proj1. If proj1 is run with 5
inputs (in1.bmp, in2.bmp, str,
out1.bmp, out2.bmp), it should read the files in1.bmp and in2.bmp and a string str, and produce images out1.bmp (by adding the label str to image in1.bmp) and out2.bmp (by applying median
filtering on in2.bmp). The two image files should be created in the same
directory.
Grading:
Both
problems will be weighted equally. Your program will be tested with at least
one input pair and its correctness will be determined by visual inspection.
Full credit will be given for correct output. Partial credit will be given
based on part of the work completed. You should demonstrate working
functions/procedures with appropriate test cases to get partial credit.