OpenCV  4.10.0
开源计算机视觉库
加载中...
搜索中...
无匹配项
反向投影

上一篇教程: 直方图比较
下一篇教程: 模板匹配

原作者Ana Huamán
兼容性OpenCV >= 3.0

目标

在本教程中,您将学习

  • 什么是反向投影以及它为什么有用
  • 如何使用 OpenCV 函数 cv::calcBackProject 计算反向投影
  • 如何使用 OpenCV 函数 cv::mixChannels 混合图像的不同通道

理论

什么是反向投影?

  • 反向投影是一种记录给定图像中的像素与直方图模型中像素分布的匹配程度的方法。
  • 简而言之:对于反向投影,您计算特征的直方图模型,然后使用它在图像中查找该特征。
  • 应用示例:如果您有肤色直方图(例如,色调-饱和度直方图),那么您可以使用它在图像中找到肤色区域。

它是如何工作的?

  • 我们使用皮肤示例来解释这一点。
  • 假设您根据下图获取了皮肤直方图(色调-饱和度)。除了直方图之外,将是我们模型直方图(我们知道它代表皮肤色调的样本)。您应用了一些蒙版来仅捕获皮肤区域的直方图:
  • 现在,假设您获得另一张手部图像(测试图像),如下所示:(及其相应的直方图):
  • 我们要做的是使用我们模型直方图(我们知道它代表皮肤色调)来检测测试图像中的皮肤区域。以下是步骤
    1. 在测试图像的每个像素(即 \(p(i,j)\) )中,收集数据并找到该像素的相应 bin 位置(即 \(( h_{i,j}, s_{i,j} )\) )。
    2. 在相应 bin 中查找模型直方图 - \(( h_{i,j}, s_{i,j} )\) - 并读取 bin 值。
    3. 将该 bin 值存储在新图像(反向投影)中。此外,您可能需要先考虑归一化模型直方图,这样测试图像的输出对于您来说是可见的。
    4. 应用上述步骤,我们得到测试图像的反向投影图像如下
  1. 从统计学角度来看,存储在反向投影中的值代表测试图像中的像素属于皮肤区域的概率,这基于我们使用的模型直方图。例如,在我们的测试图像中,更亮的区域更有可能成为皮肤区域(就像它们实际上那样),而更暗的区域的概率较小(注意,这些“暗”区域属于表面,这些表面上有一些阴影,反过来会影响检测)。

代码

  • 该程序做什么?
    • 加载图像
    • 将原始图像转换为 HSV 格式,并仅分离用于直方图的色调通道(使用 OpenCV 函数 cv::mixChannels
    • 允许用户输入要用于计算直方图的 bin 数量。
    • 计算直方图(如果 bin 发生变化则更新它)以及相同图像的反向投影。
    • 在窗口中显示反向投影和直方图。

解释

  • 读取输入图像

  • 将其转换为 HSV 格式

  • 在本教程中,我们只使用色调值作为我们的 1-D 直方图(如果您想使用更标准的 H-S 直方图,它会产生更好的结果,请查看上面的链接中的更高级代码)

  • 如您所见,我们使用函数 cv::mixChannels 从 hsv 图像中仅获取通道 0(色调)。它获取以下参数
    • &hsv: 将从中复制通道的源数组
    • 1: 源数组的数量
    • &hue: 复制通道的目标数组
    • 1: 目标数组的数量
    • ch[] = {0,0}: 指示如何复制通道的索引对数组。在本例中,&hsv 的色调 (0) 通道正在被复制到 &hue 的 0 通道(1 通道)
    • 1: 索引对的数量
  • 创建允许用户输入箱值的轨迹栏。轨迹栏上的任何更改都意味着调用 Hist_and_Backproj 回调函数。

  • 显示图像并等待用户退出程序

  • Hist_and_Backproj 函数: 初始化 cv::calcHist 所需的参数。 轨迹条提供箱子数量。

  • 计算直方图并将其归一化到 [0,255] 范围

  • 通过调用 cv::calcBackProject 函数获取相同图像的反向投影

  • 所有参数都是已知的(与计算直方图时使用的一样),我们只添加了 backproj 矩阵,它将存储源图像 (&hue) 的反向投影
  • 显示 backproj

  • 绘制图像的一维色调直方图

结果

以下是使用示例图像(猜猜看? 另一只手)的输出。 你可以玩弄箱子值,你会观察到它如何影响结果: