programming assignment 2 cs308 fall 2001. goals improve your skills with using templates. learn how...
Post on 19-Dec-2015
216 views
TRANSCRIPT
Programming Assignment 2
CS308
Fall 2001
Goals
• Improve your skills with using templates.
• Learn how to compile your code when using templates.
• Learn more about image processing.
• Learn to document and describe your programs.
Template the Image class• Make the implementation general enough so it can handle both gray-
level (PGM) and color (PPM) images.• Download the code for reading/writing PPM image from the course’s
webpage. template<class PixelType> class Image { public: member functions … private: int N; // no of rows int M; // no of columns int Q; // no gray-levels PixelType **pixelVal; };
PixelType can be int or RGB
New class for color pixels
• Each color pixel is represented by three values: (r,g,b)
struct RGB {
int r; // red component
int g; // green component
int b; // blue component
} ;
Important things to remember when using templates
• Your implementation should be as general as possible.• Your code should not depend on gray-level/color
images.• If you have to use the Image class with a new type of
images in the future, then you shouldn’t have to make any changes to the implementation of the class !
• If you need to make changes, then your are not hiding the implementation details from the application !
• This is bad programming strategy.
An example (without using templates)
int Image::meanGray()
{
int i, j;
int avg;
avg = 0;
for(I=0; I<N; I++)
for(j=0; j<M; j++)
avg = avg + pixelVal[I][j];
avg = avg / (N*M);
return avg;
}
An example (using templates)
template<class PixelType>
PixelType Image::meanValue()
{
int i, j;
PixelType avg;
avg = 0;
for(I=0; I<N; I++)
for(j=0; j<M; j++)
avg = avg + pixelVal[I][j];
avg = avg / (N*M);
return avg;
}
An example (cont’d)
• How does the function know how to initialize a variable of type PixelType to 0?
• Hoes does the function know how to add together two variables of type PixelType?
• How does it know how to implement assignment for PixelType variables?
• How does it know how to divide a variable of type PixelType by an integer?
An example (cont’d)
• Actually, it doesn’t until the user of the class has defined PixelType (i.e., by passing a parameter to the template)
Image<int> myGrayLevelImage;
Image<RGB> yourColorImage;
• Where does the function look for the definition of these operations?
“You need to define these operations within the class RGB”
Specification and Implementation
• Separating the specification from implementation makes it easier to modify programs.
• Changes in the class’s implementation should not affect the client (as long as the class’s interface has not been changed).
• Follow the following two principles:– Place the class declaration in a header file to be included by any
client that wants to use the class (e.g., StackType.h).
– Place the definition of the class member functions in a source file (e.g., StackType.cpp)
Multiple definitions
• When splitting a program into multiple files, the header file needs to be included in each file in which the class is used.
• To avoid multiple definitions of a class (or even functions), the class specification need to be enclosed in the following preprocessor code: #ifndef NAME
#define NAME
<class specification>
#endif
Multiple definitions (cont’d)
#ifndef STACKTYPE_H
#define STACKTYPE_H
template <class ItemType>
class StackType {
public:
……..
void Push(ItemType);
void Pop(ItemType&);
private:
int top;
ItemType *items;
};
#endif
Rules when using templates
• When working with templates, we change the ground rules regarding which file(s) we put the source code into.
• Previously (no templates) StackType.cpp could be compiled into object code independently of any client code.
• Using templates, the compiler cannot instantiate a function template unless it knows the argument to the template
• This information is found in the client code !!
Rules using templates (cont’d)
• Two possible solutions– Place the class definition and member function definitions
into the same file (e.g., StatckType.h)
– Or, give the include directive for the implementation file at the end of the header file
Rules when using templates (cont’d)
template <class ItemType> class StackType { public: …….. void Push(ItemType); void Pop(ItemType&); private: int top; ItemType *items; }; #include StatckType.cpp
Thresholding
• It computes a binary (black/white) image of the input.
threshold(image, thresh)
• Implement this as a client function (needs to be overloaded for int and RGB).
• Each pixel in the input image is compared against a threshold.
• Values greater than the threshold are set to 255, while values less than the threshold are set to 0.
• The same idea applies to color images (using up to three thresholds now)
255 ( , )
0 ( , )( , ) if I i j T
if I i j TO i j
Coin segmentation
• Separate the regions corresponding to the coins from the background.
• Useful for coin recognition:– collect all the pixels belonging to the same region
– extract “features” useful for coin recognition
Character segmentation
original
thresholoded
Object counting
• Use up to three thresholds in this case:– a threshold for red
– a threshold for green
– a threshold for blue
Face segmentationoriginal
thresholded
candidate face regions
Important Issues Regarding Thresholding
• How to choose the threshold?
• How to improve the results of thresholding?
• How to segment specific objects only?
How to choose the threshold?original good
threshold
low threshold
high threshold
displayHistogram(image)
• Implement this as a client function (needs to be overloaded for int and RGB).
• The histogram is a bar graph of the pixel value frequencies (i.e., the number of times each value occurs in the image)
displayHistogram(image) -- cont’d• Use an array of counters to store the pixel frequencies.
• Display the histogram as another image.
• Draw a bar for every counter.
• Normalize counter values:
0 255
500max_
cc
c
500
0
Face segmentation
• Find regions containing skin-color.
• In practice, we would have to estimate the skin-color distribution using statistical models and lots of images containing regions of skin-color.
• You will try a simpler approach here:– convert RGB values to HSV values (Hue-Saturation-Value)
– threshold the HSV values
RGBtoHSV(RGB)
• Converts a pixel from RGB to HSV
max( , , )
255
R G BV
max( , , ) min( , , )
max( , , )
R G B R G BS
R G B
1 1/ 2[( ) ( )]cos ( )
( )( ) ( )( )
R G R BH
R G R G R B G B
faceThreshold(image)
• You should implement this as a separate client function since it is specific to face detection.
• This function should call RGBtoHSV first.
• Then, it will apply the thresholding shown below to compute a binary image (we do not use V):
255 0.23 0.67,0 50
0( , ) if S H
if otherwiseO i j
How to improve the results of thresholding?
• In most cases, further processing is required to improve the results of thresholding.
• For example, some of the regions in the thresholded image might contain holes.
dilate(image) -- client
255
0( , ) if
d ifO i j If at least one neighbor is 255
if all 8 neighbors are 0
dilate(cont’d)
• Dilation “expands” the regions (i.e.,adds a layer of boundary pixels)
original thresholded dilated
erode(image) -- client
255
0( , ) if
e ifO i j If all 8 neighbors are 255
if at least one neighbor is 0
erode(image)
• Erosion “shrinks” the regions (i.e., removes a layer of boundary pixels)
original thresholded eroded
Filling in the holes of regions
• Apply dilation to fill in the holes.
• Apply erosion to restore the size of the regions.
original thresholded
dilatederoded
How to segment specific objects only?
• There are cases where we are interested in detecting some of the objects in the scene (e.g., just the key and the coin).
• Can you do this using the simple threshold function?