一、 函数原型
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 );
函数作用:计算一个或多个数组的直方图
参数 | 解释 |
---|---|
images | 输入图像 |
nimages | 输入图像个数 |
channels | 用来计算直方图的dims通道的列表 |
mask | 可选的掩码 |
hist | 输出直方图 |
dims | 直方图的维数(不大于CV_MAX_DIMS) |
histSize | 每个维度的直方图尺寸的数组(256) |
ranges | 每个维度的直方图范围的数组[dims]的阵列(0-255) |
uniform | 表示直方图是否是统一的标志 |
accumulate | 累积标志 |
uniform:是否对灰度值范围进行均匀划分的标志
ccumulate:累积标志。如果它被设置,直方图在开始分配时不会被清除。
分配时不会被清除。这个特性使你可以从几组数组中计算出一个单一的直方图,或者更新直方图。
数组,或者及时更新柱状图。
二、参数具体解释
1. channels
用来计算直方图的dims通道的列表。
第一个通道索引值:0到images[0].channels()-1的数字
(如果是三通道,就是0 ~(3-1) 即 0 ~ 2)
第二个通道索引值:images[0].channels() 到 images[0].channels() + images[1].channels()-1
例:三张三通道图像,
则第一张图像三个通道索引值:0、1、2
第一张图像三个通道索引值:3、4、5
第一张图像三个通道索引值:6、7、8
计算二维直方图(第一张图像第二通道,第二张图象第三通道)
const int channels[1] = { 0,5 };
2. mask
可选的操作掩码矩阵,
如果是空矩阵则表示图像中所有位置的像素都计入直方图中,
如果矩阵不为空,则该操作掩码矩阵必须与输入图像尺寸相同且数据类型为CV_8U。当矩阵不为空的时候,那些掩码值不为0的掩码对应的像素被纳入统计范围,而那些掩码值为0的掩码对应的像素则不被纳入统计。
空矩阵:Mat();
3. dims
需要计算的直方图的维度(不大于CV_MAX_DIMS)
一般为数组channels大小(三通道为3),当写为1的时候计算的是通道索引数组中的第1个通道的直方图,当写为2的时候计算的是通道索引数组中的第1个通道和第2个通道的二维直方图。
4. histSize
每个维度的直方图尺寸,直方图中每个dims维度需要分成多少个区间(如果把直方图看作一个一个竖条的话,就是竖条的个数);
例如:
计算二维直方图(第一张图像第二通道,第二张图象第一通道)两个图象分别为RGB和HSV
const int histSize[2] = { 256 ,181 };
可以分为256个区间(也就是一个像素值一个区间)
const int histSize[2] = { 3 ,3 };
(也可以分为3个区间,也就是256/3个像素值一个区间,画出来的直方图就是三个点两个折线)
5. ranges
例如:
计算二维直方图(第一张图像第二通道,第二张图象第一通道)两个图象分别为RGB和HSV(也就是一维根据第一个图象决定,二维根据第二个图像决定)
float hranges1[2] = { 0,255 };
float hranges2[2] = { 0,180 };
const float* ranges[2] = { hranges1, hranges2};
三、 代码
1. 一维直方图
// 图像直方图
void QuickDemo::showHistogram(Mat& image)
{
// 三通道分离
std::vector<Mat> bgr_plane; // Mat有三个通道
split(image, bgr_plane);
// 定义参数变量
const int channels[1] = {
0 };
const int bins[1] = {
256 }; // 每个维度分成256个区间
float hranges[2] = {