OpenCV3学习(8)——直方图
什么是直方图?
直方图是对数据的集合 统计 ,并将统计结果分布于一系列预定义的 bins 中。
这里的 数据 不仅仅指的是灰度值 (如上一篇您所看到的), 统计数据可能是任何能有效描述图像的特征。
先看一个例子吧。 假设有一个矩阵包含一张图像的信息 (灰度值 )
如果我们按照某种方式去 统计 这些数字,会发生什么情况呢? 既然已知数字的 范围 包含 256 个值, 我们可以将这个范围分割成子区域(称作 bins), 如:
然后再统计掉入每一个 的像素数目。采用这一方法来统计上面的数字矩阵,我们可以得到下图( x轴表示 bin, y轴表示各个bin中的像素个数)。
以上只是一个说明直方图如何工作以及它的用处的简单示例。直方图可以统计的不仅仅是颜色灰度, 它可以统计任何图像特征 (如 梯度, 方向等等)。
让我们再来搞清楚直方图的一些具体细节:
dims: 需要统计的特征的数目, 在上例中, dims = 1 因为我们仅仅统计了灰度值(灰度图像)。
bins: 每个特征空间 子区段 的数目,在上例中, bins = 16
range: 每个特征空间的取值范围,在上例中, range = [0,255]
怎样去统计两个特征呢? 在这种情况下, 直方图就是3维的了,x轴和y轴分别代表一个特征, z轴是掉入 组合中的样本数目。 同样的方法适用于更高维的情形 (当然会变得很复杂)。
OpenCV提供了一个简单的计算数组集(通常是图像或分割后的通道)的直方图函数 calcHist 。 支持高达 32 维的直方图。函数原型为:
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 );
//! computes the joint sparse histogram for a set of images.
void calcHist( const Mat* images, int nimages,
const int* channels, InputArray mask,
SparseMat& hist, int dims,
const int* histSize, const float** ranges,
bool uniform=true, bool accumulate=false );
参数1:const Mat*类型的images,输入的数组(或数组集),它们需为相同的深度(CV_8U或CV_32F)和相同的尺寸。
参数2:int类型的nimages,输入数组的个数,也就是第一个参数中存放了多少张图像,有几个源数组
参数3:const int*类型的channels,需要统计的通道索引。通道是按顺序进行序列编号,image[0]的前n个通道被编号0~(n-1),接下来的images[1]的m个通道被编号为n+m-1,以此类推。
参数4:InputArray类型的mask,可选的操作掩码。如果此掩码不为空,那么它必须为8位,并且与images[i]有同样大小的尺寸。这里的非零掩码元素用于标记出统计直方图的数组元素数据。
参数5:OutputArray类型的hist,输出的目标直方图,一个二维数组 。
参数6:int类型的dims,需要计算的直方图维度。该值恰好是channels中元素的个数。
参数7:const int*类型的histSize,存放多个维度的直方图尺寸的数组。
参数8:const float**类型的ranges,表示每一个维度数组(第六个参数dims)的每一维边界阵列,可以理解为每一维数值的取值范围。
参数9:bool类型的uniform,指示直方图是否均匀的标识符
参数10:bool类型的accumulate,累计标识符,有默认值false.