2011-01-21 275 views
24

OpenCV在模板匹配期间处理图像透明度的方式是什么?OpenCV模板匹配和透明度

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

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

编辑:好吧,我明白这是必要提供的例子。

Original image

Template image

正如你所看到的,这几乎是不可能这样的模板匹配那样的图像。 “背景” 周围的物体可以有任何颜色(像这样,还是白色,棕色...)

Sobel on grayscaled image & template + cvConvertScaleAbs

Additional original image

编辑2: Misha的解决方案有一点甚至工作(“透明”作品)。例如:

Template match sucessful

编辑3 - 多次出现:

我做了找到一个模板的多次出现的快速和肮脏的解决方案,但是当模板没有找到,我收到了“很多“的误报。这主要是因为我的实现的:

  • 迭代过的图像数据
  • 如果(的imageData [Y,X,0]> =包括maxValue * 0.95f),那么它计数[X,Y]为匹配 (包括maxValue从cvMinMaxLoc)

works图片,当有至少一个正赛,但是结果是可怕的局面图像,其上有isn't such template

+0

对最大值设置阈值。如果它低于阈值,图像不包含模板。您将不得不凭经验确定阈值的度量。 – misha 2011-01-26 01:00:35

+4

找不到图片。 =( – 2015-12-10 04:32:05

+0

@anatolytechtonik对不起,我没有他们了(已经5年了) – mnn 2016-02-18 18:30:19

回答

15

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

你有两个选择:

  1. 写,将使用Alpha通道
  2. 将您的图像,所以您的alpha通道变得无关紧要

因为第一选择自己的互相关法很简单,我会在这里探索第二个选项。我将重新使用前面提供给a similar question的示例代码。如果将互相关直接应用于图像,背景会干扰模板匹配(特别是浅色背景部分)。如果您使用颜色通道,您会发现蓝色通道中的匹配会给出正确的结果。这取决于图像内容,并不是解决问题的一致方法。

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

map

building

正如你可以看到,α通道这里已经变得无关紧要,因为大多数的地形成为零强度,并且不会向交叉相关计算。所以,现在的互相关可以直接应用,获得所需结果:

[email protected]:~/Desktop/stackoverflow$ python cross-correlation.py map-blue.png building-maskz-blue.png 
(163, 244) 

最后,这里的another related question

PS。这是什么游戏?

0

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

+0

有趣,但并没有真正的帮助,因为我不能缩小搜索范围到这样的区域(模板图像可能位于 – mnn 2011-01-24 19:51:53

+0

但是,在模板本身中,像素是透明的(即不应该在模板ROI中),像素不透明(即应该在模板ROI中)。可能发生的最糟糕的事情(就像@Utkarsh Shinha所说的那样,你必须编写自己的模板匹配函数来忽略不在ROI中的像素) – carlosdc 2011-01-25 00:38:20

+0

查看示例图像透明区域不是以任何方式呈现矩形,并且ROI是一个矩形 – mnn 2011-01-25 10:05:33

0

我不确定,但透明度通道就像其他任何通道一样处理。如果模板中的某个像素是“透明的”,则它在主图像上也应该是“透明的”。我只是在这里猜测。

1

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

-1

我遇到了同样的问题,我想到了一个解决方案。假设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,因此会出现数字问题,您不能使用第二个互相关来纠正第一个。

9

我对这个问题有一个稍微更多的脑死亡的解决方案,实际上它似乎工作得很好:用噪声代替模板图像的alpha通道,这或多或少会使得透明区域在匹配过程中变得无足轻重。

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

下面是关于阿尔法原始模板图像:
raw template image on alpha

这里的处理的模板与噪声alpha通道填充:
enter image description here

我通过在所提供的Template Matching sample code发送经处理的模板图像OpenCV文档。无论是黑暗或浅色背景下,都可以找到合适的信心。

在搜索深色背景:

matched on dark

在搜索上的光的背景:

matched on light

相比较而言,在离开模板的alpha通道透明 - 或承诺深色或浅色背景 - 没有返回可接受的比赛。

6

OpenCV 3.0提供了本机支持模板匹配与屏蔽模板。请参阅new documentation

参数:

图像...

TEMPL ...

结果...

方法...

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

该模板与掩蔽参考图像(较大的图像)的匹配[轻微题外话]

注意是不可能的,但。这是有道理的,因为OpenCV使用基于FFT的模板匹配。因此,如果您只需要在参考图像的特定区域执行模板匹配,则需要实现自己的方法或掩盖cv :: matchTemplate的输出。

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