Programming Assignment 2 CS308 Fall 2001. Goals Improve your skills with using templates. Learn how...

Preview:

Citation preview

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?

Recommended