Question: In this homework assignment, you will develop a computer vision application in C++ to automatically count coins and determine the amount of money. For simplicity,
In this homework assignment, you will develop a computer vision application in C++ to automatically count coins and determine the amount of money. For simplicity, assume that there are only nickels, dimes, quarters, and half dollars in the input image. An example input image is shown in Fig. 1a. In this case, there are three nickels, two dimes and two quarters (totaling 105 cents).
The first step will be to threshold the pixel intensity to obtain a thresholded image, indicated in Fig. 1b. You may assume that the threshold value should be COIN (a predefined symbolic constant) in this miniassignment. The pixels corresponding to each coin can be identified by a set of connected white pixels in the thresholded image, which inturn corresponds to pixels with intensities greater than the threshold value.
The coins can be classified based on their size, or equivalently the number of connected white pixels. In this assignment, you may assume the minimum number of pixels for each coin to be denoted by the predefined symbolic constants NICKEL, DIME, QUARTER, HALFDOLLAR for nickels, dimes, quarters, and half dollars, respectively. Note from the code that DIME < NICKEL < QUARTER < HALFDOLLAR). NICKEL, DIME, QUARTER, and HALFDOLLAR are all.
Your program should
Compute the number of each coin type in an input image, and report the total amount of money.
Save (write to a file) the black and white intermediate output image containing all coins (resulting from thresholding the original image) as shown in Fig. Fig. 1b.
Save (write to a file) a colored output image in which each coin type is a different (randomly assigned) color as shown in Fig. Fig. 1. c.
You will use the C++ Image class and the Stack class from the standard template library to develop the program. You may assume that there will be no more than 100 connected components in your input image. The high-level pseudocode of the program is provided below.
High-level pseudocode
Overall program:
Obtain input/output file names from command line.
Instantiate an Image object and read the input image (by just calling the readFromBMPFile member function of the image).
Threshold the input image so that the coins become white and the background becomes black (see Fig. 1b). Assume the desired threshold value is COIN. Thresholding an image requires iterating over every pixel in the image (e.g., using nested for loops). In particular, for every pixel, first obtain the current intensity value. Then, if the intensity value is greater than or equal to the threshold value, set this pixels new intensity value to 255 (white). Otherwise, set this pixels new intensity value to 0 (black).
Write the resulting thresholded image to a file (by just calling the writeToBMPFile member function of the image).
Identify all the connected components in the thresholded file and classify them to the appropriate coins based on the size. This can be performed by repeating the following steps until there are no other connected component (or if 100 connected components have already been found). You need to define and initialized the following counters before the loop: connected component label counter to 0, a nickel counter to 0, a dime counter to 0, a quarter counter to 0, a halfdollar counter to 0:
(a) Determine whether another connected component can be found in the image (i.e., if a pixel with the designated unlabeled value of 255 still exists in the image). If you can find such a pixel, use it as the seed. See finding a seed pixel within an image for more details about the function you may consider writing/calling to complete this step. If such a pixel has been found:
Increment the connected component label counter.
Mark all pixels in the connected component with this label and save the number of pixels that were marked. See mark all pixels in a connected component for more details about the function you may consider writing/calling to complete this step. At the end of this step, all of the pixel values in the connected component will have been changed from 255 (white) to the value of the label counter. Furthermore, the number of pixels in this connected component will be known.
If the number of pixels determined in the prior step is greater than or equal to DIME, but less than NICKEL, the connected component is a dime. Otherwise, if the number of pixels in the prior step is greater than or equal to NICKEL, but less than QUARTER, the connected component is a nickel. Otherwise, if the number of pixels in the prior step is greater than or equal to QUARTER, but less than HALFDOLLAR, the connected component is a QUARTER. Otherwise, if the number of pixels in the prior step is greater than or equal to HALFDOLLAR, the connected component is a half dollar. Based on the type of coin, increment the appropriate coin counter accordingly. Also, set all pixels in the image with the current label counter to the appropriate coin label (LABELNICKEL, LABELDIME, LABELQUARTER, or LABELHALF) by calling the setAllPixelsWithOldValToNewVal member function of the image.
Write the resulting labeled-coin image to a file, assigning each label a random color by first calling the switchToRandomColorMapping member function and then the writeToBMPFile member function of the image.
Output the numbers of nickels, dimes, quarters, and half dollars in the image, respectively, as well as the total amount of money (in cents).
Finding a seed pixel within an image (input: image, desired intensity value of seed pixel, placeholder for found seed row/column passed by reference; output: whether a seed pixel has been found and the row/column of the found seed pixel):
Iterate through pixels in image, looking for the first pixel in the image with a value equal to the desired intensity value (e.g., 255).
As soon as such a pixel is found, set the found row and column and return true.
However, if no such pixel is found, return false.
Mark all pixels in a connected component within an image (input: image passed by reference so that it can be modified, seed row/column, desired label for connected component pixels, output: number of pixels in connected component and modified image):
Initialize a pixel counter to zero.
Save the original intensity value of the seed pixel location (should be 255 in this homework assignment).
Push the seed pixel location on a stack (note: you can store row/column locations together by using variables of type struct pixelLocation [aka PixelLocation]).
While the stack is not empty:
Pop the top pixel location from the stack.
If the intensity value of this pixel location is equal to the original intensity value of the seed (e.g., if it equals 255)
Increment the pixel counter.
Set this pixels intensity value to the desired connected-component-label value.
Push all of this pixels neighbors onto the stack (assume the neighbors of a pixel are the pixel below, the pixel above, the pixel to the right, and the pixel to the left of the given pixel). Be careful not to push any pixels onto the stack that are outside the image boundary. You can use the member function isInBounds to confirm that a row and column position is inside the image boundary.
Return the value of the pixel counter.
Step by Step Solution
There are 3 Steps involved in it
Get step-by-step solutions from verified subject matter experts
