广义直方图
直方图的横坐标除了可以是图片中的强度值,也可以是任何其他我们想要观察的特征。例如,下面的图片矩阵中包含了0-255的强度值:
如果想观察每个宽度为16的强度值区间上的频数分布,我们就可以将横坐标分成下面的区间:
[ 0 , 255 ] = [ 0 , 15 ] ∪ [ 16 , 31 ] ∪ . . . . . ∪ [ 240 , 255 ] r a n g e = b i n 1 ∪ b i n 2 ∪ . . . . . ∪ b i n n = 15 [0, 255] = [0, 15] \cup [16, 31] \cup ..... \cup [240, 255] \\ range = bin_1 \cup bin_2 \cup ..... \cup bin_{n=15} [0,255]=[0,15]∪[16,31]∪.....∪[240,255]range=bin1∪bin2∪.....∪binn=15
这样就可以得到类似于下图的直方图:
直方图中的元素的定义如下:
- 维数(dims):即想要观察的参数的数量,比如上例中只观察灰度图中每个像素的强度值,因此
dims = 1
; - 组数(bins):每个维度中的数据被分组的数量,比如上例中分了16组区间,所以
bins = 16
; - 全距(range):被观察的数据的总区间,比如上例中
range = [0, 255]
;
如果你相观察的参数不止一个,比如说2个,即dims = 2
,那就需要画一个3维的图了。
示例
目标
- 导入图片
- 分离通道:用
split
函数将图片分离为R, G, B3个矩阵数据 - 计算直方图:用
calcHist
函数对分离出来的3个矩阵分别计算直方图 - 绘制计算结果
分离通道
split
函数,其原型如下:
void cv::split( const Mat& src,
Mat* mvbegin)
该函数将多通道的矩阵数组分成多个单通道的矩阵数组,其中:
src
为要进行通道分离的原矩阵mvbegin
为接收分离结果的数组的指针,该数组的长度要和原矩阵的通道数相同
该函数还有以下更便利的重载版本(第2个参数不再是指针,而是多维数组):
void cv::split( InputArray m,