OpenCV模板匹配和透明度

时间:2011-01-21 17:37:07

标签: image-processing opencv computer-vision template-matching

OpenCV在模板匹配过程中处理图像透明度的方式是什么?

问题是模板图像需要有透明部分,因为在原始图像中,这些地方可能有任何东西。

我尝试了所有方法,但都没有产生正面结果(例如原始图像中的模板位置未被正确检测到)。

8 个答案:

答案 0 :(得分:17)

OpenCV似乎并不像你想要的那样处理alpha。

您有两种选择:

  1. 编写您自己的使用Alpha通道的互相关方法
  2. 转换图片,使您的Alpha通道变得无关紧要
  3. 由于第一个选项很简单,我将在这里探讨第二个选项。我将重新使用我之前提供给a similar question的示例代码。如果直接对图像应用互相关,则背景会干扰模板匹配(特别是浅色背景部分)。如果您使用颜色通道,您会发现蓝色通道中的匹配可以得到正确的结果。这取决于图像内容,并不是解决问题的一致方法。

    另一种选择是在图像和模板上执行边缘检测(例如Sobel),然后执行互相关。这是边缘检测图像(我使用GIMP中Luma通道上的Sobel边缘检测器,然后进行一些强度拉伸)。

    map

    building

    正如您所看到的,此处的Alpha通道已变得无关紧要,因为大多数地形已变为零强度,并且不会对互相关计算做出贡献。所以现在可以直接应用互相关,得到理想的结果:

    misha@misha-desktop:~/Desktop/stackoverflow$ python cross-correlation.py map-blue.png building-maskz-blue.png 
    (163, 244)
    

    最后,这是another related question

    PS。这是什么游戏?

答案 1 :(得分:9)

对于这个问题,我有一个稍微有点脑死亡的解决方案,实际上似乎运行得相当好:用噪声替换模板图像的alpha通道,这或多或少使得透明区域在匹配过程中在统计上无关紧要。

例如,我的用例涉及在iOS屏幕截图中搜索表情符号字符。 iOS键盘背景会根据上下文更改颜色,如果您在模板图像中提交特定背景颜色,则会使匹配过程出现问题。

这是alpha上的原始模板图像:
raw template image on alpha

这是处理过的模板,其中填充了alpha通道的噪音:
enter image description here

我通过OpenCV文档中提供的Template Matching sample code发送了已处理的模板图片。在黑暗或浅色背景下,匹配是合理放心的。

在深色背景上搜索:

matched on dark

在浅色背景上搜索:

matched on light

相比之下,让模板的Alpha通道保持透明 - 或者提交给深色或浅色背景 - 并没有返回可接受的匹配。

答案 2 :(得分:9)

OpenCV 3.0为与模板匹配的模板匹配提供原生支持。请参阅new documentation

  

参数:

     

图片......

     

templ ...

     

结果......

     

方法......

     

掩码搜索模板的掩码。它必须与templ具有相同的数据类型和大小。默认情况下不设置。

[轻微的题外话]

请注意,模板与屏蔽参考图像(较大图像)匹配是不可能的。这是有道理的,因为OpenCV使用基于FFT的模板匹配。

因此,如果您只需要在参考图像的特定区域执行模板匹配,则需要为此实现自己的方法或屏蔽cv :: matchTemplate的输出。

从头开始实施它应该可以弥补您只想在非常特定的区域搜索模板的情况(即:哈里斯角附近)。

答案 3 :(得分:1)

如果您尝试使用黑色RGB颜色替换Alpha通道,则SQDIFF/SQDIFF_N选项将是一种解决方案。 至少这是我解决同样问题的方法。从我的结果来看很明显,这种方法对更亮的像素值很敏感,我抓住了机会。

答案 4 :(得分:0)

OpenCV 将透明度作为图像的一部分处理而不是忽略它,这可能会导致意外结果。我处理它的方式是使用具有透明度的模板作为 templatemask 中的 matchTemplate() 参数。我已经回答了一个类似的问题 here,但更详细一些,也许会有所帮助。

答案 5 :(得分:-1)

我认为你试图在OpenCV中做什么被称为模板匹配掩码。我想你可以尝试在模板上设置ROI(感兴趣的区域)。 This SO question shows how to do it。 (请注意,在该问题中,ROI是在目标图像上设置的,而不是模板,但程序是相同的。)

答案 6 :(得分:-1)

我不确定,但透明度频道的处理方式与其他频道一样。如果模板中的像素是“透明的”,那么它在主图像上也应该是“透明的”。我只是在这里猜测。

答案 7 :(得分:-2)

我遇到了同样的问题,我想到了一个解决方案。假设referenceImageMask和templateMask在好像素中有1,在坏像素中有0。并且referenceImage和templateImage已经被屏蔽,并且在坏像素中也有0。

然后,模板匹配的第一个结果将给出图像之间的非标准化互相关。但是,一堆像素为零。

第二个模板匹配将为每个可能的偏移量提供两个图像中同时不同于零(未屏蔽)的像素数。

然后,通过该数字标准化相关性应该给出你(和我)想要的值。两个图像中未遮盖的像素的平均乘积。

Image<Gray, float> imCorr = referenceImage.MatchTemplate(templateImage,      Emgu.CV.CvEnum.TM_TYPE.CV_TM_CCORR);
Image<Gray, float> imCorrMask = referenceImageMask.MatchTemplate(templateMask, Emgu.CV.CvEnum.TM_TYPE.CV_TM_CCORR);
_imCorr = _imCorr.Mul(_imCorrMask.Pow(-1));

更新:实际上,此解决方案不起作用。因为opencv中交叉相关的实现使用DFT会出现数字问题,你不能使用第二个交叉相关来纠正第一个交叉相关。