首页 > 代码库 > OpenCV Tutorials —— Histogram Calculation

OpenCV Tutorials —— Histogram Calculation

Let’s identify some parts of the histogram:

  1. 1,dims: The number of parameters you want to collect data of.
  2. 2,bins: It is the number of subdivisions in each dim.
  3. 3,range: The limits for the values to be measured.

 

void calcHist(const Mat* images, int nimages, const int* channels, InputArray mask, OutputArray hist, intdims, const int* histSize, const float** ranges, bool uniform=true, bool accumulate=false )

Parameters:

  • images – Source arrays. They all should have the same depth, CV_8U or CV_32F , and the same size. Each of them can have an arbitrary number of channels.
  • nimages – Number of source images.
  • channels – List of the dims channels used to compute the histogram. The first array channels are numerated from 0 to images[0].channels()-1 , the second array channels are counted fromimages[0].channels() to images[0].channels() + images[1].channels()-1, and so on.
  • mask – Optional mask. If the matrix is not empty, it must be an 8-bit array of the same size asimages[i] . The non-zero mask elements mark the array elements counted in the histogram.
  • hist – Output histogram, which is a dense or sparse dims -dimensional array.
  • dims – Histogram dimensionality that must be positive and not greater than CV_MAX_DIMS (equal to 32 in the current OpenCV version).
  • histSize – Array of histogram sizes in each dimension.
  • ranges – Array of the dims arrays of the histogram bin boundaries in each dimension. When the histogram is uniform ( uniform =true), then for each dimension i it is enough to specify the lower (inclusive) boundary L_0 of the 0-th histogram bin and the upper (exclusive) boundary U_{\texttt{histSize}[i]-1}for the last histogram bin histSize[i]-1 . That is, in case of a uniform histogram each ofranges[i] is an array of 2 elements. When the histogram is not uniform ( uniform=false ), then each of ranges[i] contains histSize[i]+1 elements:L_0, U_0=L_1, U_1=L_2, ..., U_{\texttt{histSize[i]}-2}=L_{\texttt{histSize[i]}-1}, U_{\texttt{histSize[i]}-1} . The array elements, that are not between L_0 and U_{\texttt{histSize[i]}-1} , are not counted in the histogram.
  • uniform – Flag indicating whether the histogram is uniform or not (see above).    是否归一化
  • accumulate – Accumulation flag. If it is set, the histogram is not cleared in the beginning when it is allocated. This feature enables you to compute a single histogram from several sets of arrays, or to update the histogram in time.  是否累加

 

 

calcHist( &bgr_planes[2], 1, 0, Mat(), r_hist, 1, &histSize, &histRange, uniform, accumulate );

where the arguments are:

  • &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
  • 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
  • uniform and accumulate: The bin sizes are the same and the histogram is cleared at the beginning.

 

 

 

normalize(b_hist, b_hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() );
 
 
Code
 
#include "stdafx.h"#include "opencv2/highgui/highgui.hpp"#include "opencv2/imgproc/imgproc.hpp"#include <iostream>#include <stdio.h>using namespace std;using namespace cv;/** * @function main */int main( int argc, char** argv ){  Mat src, dst;  /// Load image  src = http://www.mamicode.com/imread("img2.jpg", 1 );  if( !src.data )    { return -1; }  /// Separate the image in 3 places ( B, G and R )  vector<Mat> 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; i < histSize; i++ )  {      line( histImage, Point( bin_w*(i-1), hist_h - cvRound(b_hist.at<float>(i-1)) ) ,                       Point( bin_w*(i), hist_h - cvRound(b_hist.at<float>(i)) ),                       Scalar( 255, 0, 0), 2, 8, 0  );      line( histImage, Point( bin_w*(i-1), hist_h - cvRound(g_hist.at<float>(i-1)) ) ,                       Point( bin_w*(i), hist_h - cvRound(g_hist.at<float>(i)) ),                       Scalar( 0, 255, 0), 2, 8, 0  );      line( histImage, Point( bin_w*(i-1), hist_h - cvRound(r_hist.at<float>(i-1)) ) ,                       Point( bin_w*(i), hist_h - cvRound(r_hist.at<float>(i)) ),                       Scalar( 0, 0, 255), 2, 8, 0  );  }  /// Display  namedWindow("calcHist Demo", CV_WINDOW_AUTOSIZE );  imshow("calcHist Demo", histImage );  waitKey(0);  return 0;}

OpenCV Tutorials —— Histogram Calculation