If something is useful for computer vision, you'll almost definitely find it in OpenCV. Histograms are no exception. And OpenCV comes with a rich set of functions to work with and manipulate histograms.
Histograms are stored in the CvHistogram data structure:
typedef struct CvHistogram { int type; CvArr* bins; float thresh[CV_MAX_DIM][2]; // for uniform histograms float** thresh2; // for nonuniform histograms CvMatND mat; // embedded matrix header for array histograms } CvHistogram;
To create a new histogram, use the cvCreateHist function:
CvHistogram* cvCreateHist(int dims, int* sizes, int type, float** ranges = NULL, int uniform = 1 );
Very simple to understand. Here's what the parameters mean:
Uniform: If uniform is set to zero, the histogram is made non-uniform. For any non-zero value, the histogram is uniform. In the cvCreateHist function, you can actually set ranges to NULL. But then you'll have to set the ranges later on. You must do this with:
:::c++ void cvSetHistBinRanges(CvHistogram hist, float* ranges, int uniform = 1 );
The function just sets the ranges for the histogram hist. The parameters work just as explained above.
Once you're done with a histogram, it's a good idea to release it from memory. Other programs could really use some extra free RAM. You do this with:
void cvReleaseHist(CvHistogram** hist);
This is similar to most other cvRelease type commands.
If you've already made a histogram and want to reuse it, you need to set each of the bins to zero. This is done by "clearing" the histogram:
void cvClearHist(CvHistogram* hist);
If you already have an array and you want to convert it into a histogram, there's another utility function.
CvHistogram* cvMakeHistHeaderForArray(int dims, int* sizes, CvHistogram* hist, float* data, float** ranges = NULL, int uniform = 1 );
This is similar to the cvCreateHist function, so it should be easy to understand. Dims is the number of dimensions, sizes is the number of bins in each dimension. Hist is the histogram and data is the actual array. This array must have sizes[0]sizes[1]sizes[2]…*sizes[dims-1] number of values. Ranges and uniform have the same meaning as above.
There are two things to remember when using cvMakeHistHeaderForArray():
With the cvCreateHist and cvMakeHistHeaderForArray, we're technically capable of creating histograms in OpenCV now!