本文为原创文章,未经本人允许,禁止转载。转载请注明出处。
1.直方图的反向投影
先计算某一特征的直方图模型,然后在目标图像中寻找是否有相似的对象。因此,我们可以利用直方图的反向投影来实现图像分割,目标检测等任务。
通常用HSV色彩空间的H和S两个通道的直方图模型。
常用步骤:
- 读入原始图像(也可以是某一图像的目标区域,即我们想要提取的特征所在的区域)。
- 使用
cv::cvtColor
将原始图像转换到HSV色彩空间。 - 使用
cv::mixChannels
(用法见本文第2部分)将h通道从HSV格式的图像中提取出来。 - 使用
cv::calcHist
计算h通道的直方图。并使用cv::normalize
进行归一化处理。 - 使用
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
);
参数解释见下:
const Mat* src
:输入图像(可多个,但必须是一样的大小和位图深度)。size_t nsrcs
:输入图像的个数。Mat* dst
:输出图像(同样可多个,和输入图像的大小以及位图深度保持一致)。size_t ndsts
:输出图像的个数。const int* fromTo
:偶数下标的用来标识输入矩阵,奇数下标的用来标识输出矩阵。如果偶数下标为负数,那么相应的输出矩阵为零矩阵。例如{0,1,1,3}
,表示将输入图像的第0个通道复制到输出图像的第1个通道;将输入图像的第1个通道复制到输出图像的第3个通道。如果输出图像有多个,则通道数索引可标记为:0,1,...,src[0].channels()-1,src[0].channels(),...,src[1].channels()-1,...
。输出图像是多个的情况一样,不再赘述。size_t npairs
:fromTo
中的序号对数(两个算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
);
参数解释:
const Mat* images
:输入图像(即待检测图像)。可多个,但是图像大小和位图深度(只能是CV_8U
、CV_16U
、CV_32F
中的一个)必须一样。int nimages
:输入图像的数量。const int* channels
:用于计算反向投影的通道列表(通道的索引标识类似于cv::mixChannels
的第5个参数)。InputArray hist
:目标特征的直方图。OutputArray backProject
:输出的检测结果图像。为单通道,并且和输入图像的大小以及位图深度一致。const float** ranges
:直方图中每个维度bin的取值范围。double scale = 1
:输出反向投影的比例因子。bool uniform = true
:直方图是否均匀分布,即每一个竖条的宽度是否相等。