【OpenCV基础】第二十四课:直方图反向投影

直方图反向投影,cv::mixChannels,cv::calcBackProject

Posted by x-jeff on September 24, 2021

本文为原创文章,未经本人允许,禁止转载。转载请注明出处。

1.直方图的反向投影

先计算某一特征的直方图模型,然后在目标图像中寻找是否有相似的对象。因此,我们可以利用直方图的反向投影来实现图像分割,目标检测等任务。

通常用HSV色彩空间的H和S两个通道的直方图模型。

常用步骤:

  1. 读入原始图像(也可以是某一图像的目标区域,即我们想要提取的特征所在的区域)。
  2. 使用cv::cvtColor将原始图像转换到HSV色彩空间。
  3. 使用cv::mixChannels(用法见本文第2部分)将h通道从HSV格式的图像中提取出来。
  4. 使用cv::calcHist计算h通道的直方图。并使用cv::normalize进行归一化处理。
  5. 使用cv::calcBackProject(用法见本文第3部分)进行直方图反向投影,对另一图像(或原始图像)进行相似特征的检测。

👉直方图的反向投影原理详解:

假设有灰度图像:

\[Image = \begin{bmatrix} 1 & 2 & 3 & 4 \\ 5 & 6 & 7 & 7 \\ 9 & 8 & 0 & 1 \\ 5 & 6 & 7 & 6 \\ \end{bmatrix}\]

这个图像的直方图为:

[0,2] [3,5] [6,7] [8,10]
4 4 6 2

接下来计算反向投影矩阵(反向投影矩阵的大小和原灰度图像矩阵的大小相同)。原图像中坐标为$(0,0)$的灰度值为1,1位于区间[0,2]中,区间[0,2] 对应的直方图值为4,所以反向投影矩阵中坐标为$(0,0)$的值记为4,剩余位置以此类推:

\[Proj\_Image=\begin{bmatrix} 4 & 4 & 4 & 4 \\ 4 & 6 & 6 & 6 \\ 2 & 2 & 4 & 4 \\ 4 & 6 & 6 & 6 \\ \end{bmatrix}\]

2.cv::mixChannels

cv::mixChannels主要就是把输入的矩阵(或矩阵数组)的某些通道拆分复制给对应的输出矩阵(或矩阵数组)的某些通道中。

1
2
3
4
5
6
7
8
void mixChannels(
	const Mat* src, 
	size_t nsrcs, 
	Mat* dst, 
	size_t ndsts,
	const int* fromTo, 
	size_t npairs
);

参数解释见下:

  1. const Mat* src:输入图像(可多个,但必须是一样的大小和位图深度)。
  2. size_t nsrcs:输入图像的个数。
  3. Mat* dst:输出图像(同样可多个,和输入图像的大小以及位图深度保持一致)。
  4. size_t ndsts:输出图像的个数。
  5. const int* fromTo:偶数下标的用来标识输入矩阵,奇数下标的用来标识输出矩阵。如果偶数下标为负数,那么相应的输出矩阵为零矩阵。例如{0,1,1,3},表示将输入图像的第0个通道复制到输出图像的第1个通道;将输入图像的第1个通道复制到输出图像的第3个通道。如果输出图像有多个,则通道数索引可标记为:0,1,...,src[0].channels()-1,src[0].channels(),...,src[1].channels()-1,...。输出图像是多个的情况一样,不再赘述。
  6. size_t npairsfromTo中的序号对数(两个算1对)。

3.cv::calcBackProject

1
2
3
4
5
6
7
8
9
10
void calcBackProject( 
	const Mat* images, 
	int nimages,
	const int* channels, 
	InputArray hist,
	OutputArray backProject, 
	const float** ranges,
	double scale = 1, 
	bool uniform = true 
);

参数解释:

  1. const Mat* images:输入图像(即待检测图像)。可多个,但是图像大小和位图深度(只能是CV_8UCV_16UCV_32F中的一个)必须一样。
  2. int nimages:输入图像的数量。
  3. const int* channels:用于计算反向投影的通道列表(通道的索引标识类似于cv::mixChannels的第5个参数)。
  4. InputArray hist:目标特征的直方图。
  5. OutputArray backProject:输出的检测结果图像。为单通道,并且和输入图像的大小以及位图深度一致。
  6. const float** ranges:直方图中每个维度bin的取值范围。
  7. double scale = 1:输出反向投影的比例因子。
  8. bool uniform = true:直方图是否均匀分布,即每一个竖条的宽度是否相等。

4.代码地址

  1. 直方图反向投影

5.参考资料

  1. OpenCV之mixChannels()函数使用说明
  2. [OpenCV基础] OpenCV中对mixChannels函数的理解
  3. opencv学习(三十九)之反向投影calcBackProject()
  4. 直方图的反向投影的原理