The histogram of a grayscale image with floating point intensity values consists
ID: 3764321 • Letter: T
Question
The histogram of a grayscale image with floating point intensity values consists of a count of how may pixels there are in a given intensity range. For example, we could divide the range of intensities between 0.0 and 1.0 into ten equal ranges (bins for values: 0.0-0.1, 0.1-0.2, 0.2-0.3, etc), and count the number of pixels whose intensity is in each range. The histogram shows the distribution of graylevel values within an image, which can sometimes tell us something about the objects or scene pictured in the image, particularly if different objects or scenes of interest have quite different grayscale distributions. In C++ we can store a grayscale image in a 2-dimensional array of type float double (use type double throughout this question instead of floats -- we have discovered problems with using float in this question; still use integers where it says to use integers). Here's an example of the data for image that is 5 pixels wide and 5 pixels high as a C++ array: 0.00 0.25 0.50 0.25 0.00 0.20 0.40 0.60 0.80 1.00 0.25 0.50 1.00 0.50 0.25 0.20 0.40 0.60 0.80 1.00 0.00 0.25 0.50 0.25 0.00 To compute the histogram of this image Count the number of pixels whose intensity is greater or equal to 0.0 and less than 0.1; there are four such pixels (the corners). Count the number of pixels with intensity greater or equal to 0.1 and less than 0.2. There are no such pixels, so the second number in the histogram is 0. Count the number of pixels with intensity greater or equal to 0.2 and less than 0.3. There are 8 such pixels (the ones with intensity 0.2 and 0.25), so the third number in the histogram would be 8. This proceeds in the same way for the remainder of the ten equal ranges between 0.0 and 1.0. Note: the last interval includes 1.0, so the last number in the histogram is the number of pixels greater or equal to 0.9 and less than or equal to 1.0. Convince yourself that the histogram for the above image is the sequence of ten numbers: 4, 0, 8, 0, 2, 4, 2, 0, 2, 3. Note that the ten numbers in the histogram should add up to the number of pixels in the image since each pixel in the image contributes a count of 1 to exactly one bin. Note how 4+0+8+0+2+4+2+0+2+3 = 25, which is the number of pixels in the original 5x5 image.
QUIZ:
Write a function called fillHistogram that takes three parameters: I: a 2D array of type double with a fixed width 5 (but can be of any height); height: an integer specifying the height of I; and H: a one-dimensional integer array of length 10, i.e., the histogram array. The function should fill H with the values for the histogram of the image I. In your main() function:
Create a 2D array for the 5x5 image shown in the above example. Use your histogram function to construct its histogram and print the histogram to the console to verify the correctness of your function.
Make up an second image with width 5 and height 10, declare and initialize an array to store it, and use your function from step 1 to compute its histogram, and print it to the console.
Explanation / Answer
#include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include #include using namespace std; using namespace cv; /** * @function main */ int main( int argc, char** argv ) { Mat src, dst; /// Load image src = imread( argv[1], 1 ); if( !src.data ) { return -1; } /// Separate the image in 3 places ( B, G and R ) vector bgr_planes; split( src, bgr_planes ); /// Establish the number of bins int histSize = 256; /// Set the ranges ( for B,G,R) ) float range[] = { 0, 256 } ; const float* histRange = { range }; bool uniform = true; bool accumulate = false; Mat b_hist, g_hist, r_hist; /// Compute the histograms: calcHist( &bgr_planes[0], 1, 0, Mat(), b_hist, 1, &histSize, &histRange, uniform, accumulate ); calcHist( &bgr_planes[1], 1, 0, Mat(), g_hist, 1, &histSize, &histRange, uniform, accumulate ); calcHist( &bgr_planes[2], 1, 0, Mat(), r_hist, 1, &histSize, &histRange, uniform, accumulate ); // Draw the histograms for B, G and R int hist_w = 512; int hist_h = 400; int bin_w = cvRound( (double) hist_w/histSize ); Mat histImage( hist_h, hist_w, CV_8UC3, Scalar( 0,0,0) ); /// Normalize the result to [ 0, histImage.rows ] normalize(b_hist, b_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() ); normalize(g_hist, g_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() ); normalize(r_hist, r_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() ); /// Draw for each channel for( int i = 1; iRelated Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.