From 1494da339d8b1134cd479a69c3638c34be968720 Mon Sep 17 00:00:00 2001 From: Alexander Shishkov Date: Mon, 5 Mar 2012 11:08:59 +0000 Subject: [PATCH] fixed #1507 --- .../histogram_calculation.rst | 183 +++++++++--------- .../images/Histogram_Calculation_Result.jpg | Bin 10167 -> 31264 bytes .../Histograms_Matching/calcHist_Demo.cpp | 60 +++--- 3 files changed, 122 insertions(+), 121 deletions(-) diff --git a/doc/tutorials/imgproc/histograms/histogram_calculation/histogram_calculation.rst b/doc/tutorials/imgproc/histograms/histogram_calculation/histogram_calculation.rst index e8eb67f214..4b6e7c3930 100644 --- a/doc/tutorials/imgproc/histograms/histogram_calculation/histogram_calculation.rst +++ b/doc/tutorials/imgproc/histograms/histogram_calculation/histogram_calculation.rst @@ -88,79 +88,80 @@ Code .. code-block:: cpp - #include "opencv2/highgui/highgui.hpp" - #include "opencv2/imgproc/imgproc.hpp" - #include - #include + #include "opencv2/highgui/highgui.hpp" + #include "opencv2/imgproc/imgproc.hpp" + #include + #include - using namespace std; - using namespace cv; + using namespace std; + using namespace cv; - /** @function main */ - int main( int argc, char** argv ) - { - Mat src, dst; + /** + * @function main + */ + int main( int argc, char** argv ) + { + Mat src, dst; - /// Load image - src = imread( argv[1], 1 ); + /// Load image + src = imread( argv[1], 1 ); - if( !src.data ) - { return -1; } + if( !src.data ) + { return -1; } - /// Separate the image in 3 places ( R, G and B ) - vector rgb_planes; - split( src, rgb_planes ); + /// Separate the image in 3 places ( B, G and R ) + vector bgr_planes; + split( src, bgr_planes ); - /// Establish the number of bins - int histSize = 255; + /// Establish the number of bins + int histSize = 256; - /// Set the ranges ( for R,G,B) ) - float range[] = { 0, 255 } ; - const float* histRange = { range }; + /// Set the ranges ( for B,G,R) ) + float range[] = { 0, 256 } ; + const float* histRange = { range }; - bool uniform = true; bool accumulate = false; + bool uniform = true; bool accumulate = false; - Mat r_hist, g_hist, b_hist; + Mat b_hist, g_hist, r_hist; - /// Compute the histograms: - calcHist( &rgb_planes[0], 1, 0, Mat(), r_hist, 1, &histSize, &histRange, uniform, accumulate ); - calcHist( &rgb_planes[1], 1, 0, Mat(), g_hist, 1, &histSize, &histRange, uniform, accumulate ); - calcHist( &rgb_planes[2], 1, 0, Mat(), b_hist, 1, &histSize, &histRange, uniform, accumulate ); + /// 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 R, G and B - int hist_w = 400; int hist_h = 400; - int bin_w = cvRound( (double) hist_w/histSize ); + // 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_w, hist_h, CV_8UC3, Scalar( 0,0,0) ); + Mat histImage( hist_h, hist_w, CV_8UC3, Scalar( 0,0,0) ); - /// Normalize the result to [ 0, histImage.rows ] - normalize(r_hist, r_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() ); - normalize(g_hist, g_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() ); - normalize(b_hist, b_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() ); + /// 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; i < histSize; i++ ) - { - line( histImage, Point( bin_w*(i-1), hist_h - cvRound(r_hist.at(i-1)) ) , - Point( bin_w*(i), hist_h - cvRound(r_hist.at(i)) ), - Scalar( 0, 0, 255), 2, 8, 0 ); - line( histImage, Point( bin_w*(i-1), hist_h - cvRound(g_hist.at(i-1)) ) , - Point( bin_w*(i), hist_h - cvRound(g_hist.at(i)) ), - Scalar( 0, 255, 0), 2, 8, 0 ); - line( histImage, Point( bin_w*(i-1), hist_h - cvRound(b_hist.at(i-1)) ) , - Point( bin_w*(i), hist_h - cvRound(b_hist.at(i)) ), - Scalar( 255, 0, 0), 2, 8, 0 ); - } + /// Draw for each channel + for( int i = 1; i < histSize; i++ ) + { + line( histImage, Point( bin_w*(i-1), hist_h - cvRound(b_hist.at(i-1)) ) , + Point( bin_w*(i), hist_h - cvRound(b_hist.at(i)) ), + Scalar( 255, 0, 0), 2, 8, 0 ); + line( histImage, Point( bin_w*(i-1), hist_h - cvRound(g_hist.at(i-1)) ) , + Point( bin_w*(i), hist_h - cvRound(g_hist.at(i)) ), + Scalar( 0, 255, 0), 2, 8, 0 ); + line( histImage, Point( bin_w*(i-1), hist_h - cvRound(r_hist.at(i-1)) ) , + Point( bin_w*(i), hist_h - cvRound(r_hist.at(i)) ), + Scalar( 0, 0, 255), 2, 8, 0 ); + } - /// Display - namedWindow("calcHist Demo", CV_WINDOW_AUTOSIZE ); - imshow("calcHist Demo", histImage ); + /// Display + namedWindow("calcHist Demo", CV_WINDOW_AUTOSIZE ); + imshow("calcHist Demo", histImage ); - waitKey(0); + waitKey(0); - return 0; - - } + return 0; + } Explanation =========== @@ -184,25 +185,25 @@ Explanation .. code-block:: cpp - vector rgb_planes; - split( src, rgb_planes ); + vector bgr_planes; + split( src, bgr_planes ); our input is the image to be divided (this case with three channels) and the output is a vector of Mat ) -#. Now we are ready to start configuring the **histograms** for each plane. Since we are working with the R, G and B planes, we know that our values will range in the interval :math:`[0,255]` +#. Now we are ready to start configuring the **histograms** for each plane. Since we are working with the B, G and R planes, we know that our values will range in the interval :math:`[0,255]` a. Establish number of bins (5, 10...): .. code-block:: cpp - int histSize = 255; + int histSize = 256; //from 0 to 255 b. Set the range of values (as we said, between 0 and 255 ) .. code-block:: cpp - /// Set the ranges ( for R,G,B) ) - float range[] = { 0, 255 } ; + /// Set the ranges ( for B,G,R) ) + float range[] = { 0, 256 } ; //the upper boundary is exclusive const float* histRange = { range }; c. We want our bins to have the same size (uniform) and to clear the histograms in the beginning, so: @@ -215,26 +216,26 @@ Explanation .. code-block:: cpp - Mat r_hist, g_hist, b_hist; + Mat b_hist, g_hist, r_hist; e. We proceed to calculate the histograms by using the OpenCV function :calc_hist:`calcHist <>`: .. code-block:: cpp - /// Compute the histograms: - calcHist( &rgb_planes[0], 1, 0, Mat(), r_hist, 1, &histSize, &histRange, uniform, accumulate ); - calcHist( &rgb_planes[1], 1, 0, Mat(), g_hist, 1, &histSize, &histRange, uniform, accumulate ); - calcHist( &rgb_planes[2], 1, 0, Mat(), b_hist, 1, &histSize, &histRange, uniform, accumulate ); + /// 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 ); where the arguments are: .. container:: enumeratevisibleitemswithsquare - + **&rgb_planes[0]:** The source array(s) + + **&bgr_planes[0]:** The source array(s) + **1**: The number of source arrays (in this case we are using 1. We can enter here also a list of arrays ) + **0**: The channel (*dim*) to be measured. In this case it is just the intensity (each array is single-channel) so we just write 0. + **Mat()**: A mask to be used on the source array ( zeros indicating pixels to be ignored ). If not defined it is not used - + **r_hist**: The Mat object where the histogram will be stored + + **b_hist**: The Mat object where the histogram will be stored + **1**: The histogram dimensionality. + **histSize:** The number of bins per each used dimension + **histRange:** The range of values to be measured per each dimension @@ -246,26 +247,26 @@ Explanation .. code-block:: cpp // Draw the histograms for R, G and B - int hist_w = 400; int hist_h = 400; + int hist_w = 512; int hist_h = 400; int bin_w = cvRound( (double) hist_w/histSize ); - Mat histImage( hist_w, hist_h, CV_8UC3, Scalar( 0,0,0) ); + Mat histImage( hist_h, hist_w, CV_8UC3, Scalar( 0,0,0) ); #. Notice that before drawing, we first :normalize:`normalize <>` the histogram so its values fall in the range indicated by the parameters entered: .. code-block:: cpp /// Normalize the result to [ 0, histImage.rows ] - normalize(r_hist, r_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() ); - normalize(g_hist, g_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() ); 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() ); this function receives these arguments: .. container:: enumeratevisibleitemswithsquare - + **r_hist:** Input array - + **r_hist:** Output normalized array (can be the same) + + **b_hist:** Input array + + **b_hist:** Output normalized array (can be the same) + **0** and**histImage.rows**: For this example, they are the lower and upper limits to normalize the values of **r_hist** + **NORM_MINMAX:** Argument that indicates the type of normalization (as described above, it adjusts the values between the two limits set before) + **-1:** Implies that the output normalized array will be the same type as the input @@ -273,35 +274,35 @@ Explanation #. Finally, observe that to access the bin (in this case in this 1D-Histogram): - .. code-block:: cpp + .. code-block:: cpp - /// Draw for each channel + /// Draw for each channel for( int i = 1; i < histSize; i++ ) - { - line( histImage, Point( bin_w*(i-1), hist_h - cvRound(r_hist.at(i-1)) ) , - Point( bin_w*(i), hist_h - cvRound(r_hist.at(i)) ), - Scalar( 0, 0, 255), 2, 8, 0 ); - line( histImage, Point( bin_w*(i-1), hist_h - cvRound(g_hist.at(i-1)) ) , - Point( bin_w*(i), hist_h - cvRound(g_hist.at(i)) ), - Scalar( 0, 255, 0), 2, 8, 0 ); - line( histImage, Point( bin_w*(i-1), hist_h - cvRound(b_hist.at(i-1)) ) , - Point( bin_w*(i), hist_h - cvRound(b_hist.at(i)) ), - Scalar( 255, 0, 0), 2, 8, 0 ); - } + { + line( histImage, Point( bin_w*(i-1), hist_h - cvRound(b_hist.at(i-1)) ) , + Point( bin_w*(i), hist_h - cvRound(b_hist.at(i)) ), + Scalar( 255, 0, 0), 2, 8, 0 ); + line( histImage, Point( bin_w*(i-1), hist_h - cvRound(g_hist.at(i-1)) ) , + Point( bin_w*(i), hist_h - cvRound(g_hist.at(i)) ), + Scalar( 0, 255, 0), 2, 8, 0 ); + line( histImage, Point( bin_w*(i-1), hist_h - cvRound(r_hist.at(i-1)) ) , + Point( bin_w*(i), hist_h - cvRound(r_hist.at(i)) ), + Scalar( 0, 0, 255), 2, 8, 0 ); + } we use the expression: .. code-block:: cpp - r_hist.at(i) + b_hist.at(i) - where :math:`i` indicates the dimension. If it were a 2D-histogram we would use something like: + where :math:`i` indicates the dimension. If it were a 2D-histogram we would use something like: .. code-block:: cpp - r_hist.at( i, j ) + b_hist.at( i, j ) #. Finally we display our histograms and wait for the user to exit: diff --git a/doc/tutorials/imgproc/histograms/histogram_calculation/images/Histogram_Calculation_Result.jpg b/doc/tutorials/imgproc/histograms/histogram_calculation/images/Histogram_Calculation_Result.jpg index 07b7e320d1378e6de7648041874ee5383d4c7ccb..70eb1e80cd474e2a863dfe4a0693da7649b538d1 100644 GIT binary patch literal 31264 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 literal 10167 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 IbU*t)02Le7 rgb_planes; - split( src, rgb_planes ); + /// Separate the image in 3 places ( B, G and R ) + vector bgr_planes; + split( src, bgr_planes ); - /// Establish the number of bins - int histSize = 255; + /// Establish the number of bins + int histSize = 256; - /// Set the ranges ( for R,G,B) ) - float range[] = { 0, 255 } ; + /// Set the ranges ( for B,G,R) ) + float range[] = { 0, 256 } ; const float* histRange = { range }; bool uniform = true; bool accumulate = false; - Mat r_hist, g_hist, b_hist; + Mat b_hist, g_hist, r_hist; /// Compute the histograms: - calcHist( &rgb_planes[0], 1, 0, Mat(), r_hist, 1, &histSize, &histRange, uniform, accumulate ); - calcHist( &rgb_planes[1], 1, 0, Mat(), g_hist, 1, &histSize, &histRange, uniform, accumulate ); - calcHist( &rgb_planes[2], 1, 0, Mat(), b_hist, 1, &histSize, &histRange, uniform, accumulate ); + 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 R, G and B - int hist_w = 400; int hist_h = 400; + // 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_w, hist_h, CV_8UC3, Scalar( 0,0,0) ); + Mat histImage( hist_h, hist_w, CV_8UC3, Scalar( 0,0,0) ); /// Normalize the result to [ 0, histImage.rows ] - normalize(r_hist, r_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() ); - normalize(g_hist, g_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() ); 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 + /// Draw for each channel for( int i = 1; i < histSize; i++ ) - { - line( histImage, Point( bin_w*(i-1), hist_h - cvRound(r_hist.at(i-1)) ) , - Point( bin_w*(i), hist_h - cvRound(r_hist.at(i)) ), - Scalar( 0, 0, 255), 2, 8, 0 ); - line( histImage, Point( bin_w*(i-1), hist_h - cvRound(g_hist.at(i-1)) ) , - Point( bin_w*(i), hist_h - cvRound(g_hist.at(i)) ), - Scalar( 0, 255, 0), 2, 8, 0 ); - line( histImage, Point( bin_w*(i-1), hist_h - cvRound(b_hist.at(i-1)) ) , - Point( bin_w*(i), hist_h - cvRound(b_hist.at(i)) ), - Scalar( 255, 0, 0), 2, 8, 0 ); - } + { + line( histImage, Point( bin_w*(i-1), hist_h - cvRound(b_hist.at(i-1)) ) , + Point( bin_w*(i), hist_h - cvRound(b_hist.at(i)) ), + Scalar( 255, 0, 0), 2, 8, 0 ); + line( histImage, Point( bin_w*(i-1), hist_h - cvRound(g_hist.at(i-1)) ) , + Point( bin_w*(i), hist_h - cvRound(g_hist.at(i)) ), + Scalar( 0, 255, 0), 2, 8, 0 ); + line( histImage, Point( bin_w*(i-1), hist_h - cvRound(r_hist.at(i-1)) ) , + Point( bin_w*(i), hist_h - cvRound(r_hist.at(i)) ), + Scalar( 0, 0, 255), 2, 8, 0 ); + } - /// Display + /// Display namedWindow("calcHist Demo", CV_WINDOW_AUTOSIZE ); imshow("calcHist Demo", histImage ); waitKey(0); return 0; - + }