Try to encapsulate the api of calcHist because it is too complicated for me. I've read the documentation for calcHist() many times, but I think my inexperience precluding me from understanding all of the parameters of this api.
void calcHist(const Mat* images, int nimages, const int* channels, InputArray mask, OutputArray hist, int dims, const int* histSize, const float** ranges, bool uniform=true, bool accumulate=false )
(1)nimages : Number of source images-->is it always same as the number of images point to? ex :
cv::Mat a, b, c;
cv::Mat images[] = {a, b, c};
int nimages = sizeof(images) / sizeof(cv::Mat);
(2)channels : List of the dims channels used to compute the histogram-->is it always same as the number of dims? ex : int channels[] = {0, 1}; int dims = sizeof(channels)/ sizeof(int);
(3)histSizes && ranges: Are they always have the same elements numbers as channels?
(4)channels, histSize and ranges always have same number of elements? ex :
int channels[] = {0, 1}; //two elements
int histSize[] = {180, 256}; //two elements
float hue[] = {0, 180};
float sat[] = {0, 255};
float const *ranges[] = {hue, sat}; //two elements
(5)if (1)~(4) are correct, that means we could deduce nimages from images;deduce dims from channels, histSize or ranges?
encapsulation base on the assumption from (1)~(4)
void calc_histogram(std::initializer_list<cv::Mat> images, cv::OutputArray &output, std::initializer_list<int> channels,
std::initializer_list<int> hist_sizes, std::initializer_list<std::initializer_list<float>> ranges,
cv::InputArray const &mask = cv::Mat(), bool uniform = true, bool accumulate = false)
{
size_t const sizes = ranges.size();
std::vector<float const*> d_ranges(sizes);
for(size_t i = 0; i != sizes; ++i){
d_ranges[i] = std::begin( *(std::begin(ranges) + i) );
}
cv::calcHist(std::begin(images), images.size(), std::begin(channels), mask, output,
channels.size(), std::begin(hist_sizes), &d_ranges[0], uniform ,accumulate);
}