如何在图像中使用掩膜(或透明度)找到模板,使用OpenCV和Python?

30 投票
6 回答
12166 浏览
提问于 2025-04-17 19:23

假设我们想找一个这样的模板:

停止

这个模板的角落是透明的,所以背景会有所不同,比如:

在月球上停止

在珠穆朗玛峰上停止

在树叶上停止

假设我们可以用下面的遮罩来处理我们的模板:

停止 停止遮罩

这样就很容易找到它了。

我尝试过的:

我试过用 matchTemplate,但我知道它不支持遮罩,而且在模板中使用透明通道并不能解决这个问题,因为它会比较透明通道,而不是忽略那些像素。

我还研究过“感兴趣区域”,我以为这会是解决方案,但用这个只能指定一个矩形区域。我甚至不确定它是否适用于模板。

我相信通过自己写算法是可以做到的,但我希望能通过标准的 OpenCV 来实现,这样就不用重新发明轮子了。更何况,标准的方法可能会比我自己的实现更优化。

那么,我该如何用 OpenCV 和 Python 来做这样的事情呢?

6 个回答

2

你问的问题有一个答案是卷积。你可以把模板当作一个工具,用来处理图像。

处理后的结果会在你模板可能出现的地方显示出明亮的区域。接下来,你需要把这些结果进行聚类(比如说用均值漂移算法)。

这样一来,你就能简单地实现一种叫做广义霍夫变换的技术,或者说是基于模板的卷积匹配

3

我之前遇到过类似的问题,解决的方法是把“遮罩”区域填充上白噪声。这样在寻找匹配的时候,这些区域就会被有效地“冲淡”,不会影响结果。否则,我想你也遇到过,我在遮罩区域得到了错误的匹配结果。

10

这个可以通过使用 matchTemplate 函数来实现,不过需要一些小技巧。

我们先来分析一下默认的度量标准(CV_TM_SQDIFF_NORMED)。根据 matchTemplate 的文档,默认的度量标准是这样的:

R(x, y) = sum (I(x+x', y+y') - T(x', y'))^2

这里 I 是图像矩阵,T 是模板,R 是结果矩阵。求和是针对模板的坐标 x'y' 进行的。

所以,我们可以通过插入一个与 T 大小相同的权重矩阵 W 来改变这个度量标准。

Q(x, y) = sum W(x', y')*(I(x+x', y+y') - T(x', y'))^2

在这种情况下,通过设置 W(x', y') = 0,你可以让某些像素被忽略。那么,如何构造这样的度量标准呢?用简单的数学方法:

Q(x, y) = sum W(x', y')*(I(x+x', y+y') - T(x', y'))^2
        = sum W(x', y')*(I(x+x', y+y')^2 - 2*I(x+x', y+y')*T(x', y') + T(x', y')^2)
        = sum {W(x', y')*I(x+x', y+y')^2} - sum{W(x', y')*2*I(x+x', y+y')*T(x', y')} + sum{W(x', y')*T(x', y')^2)}

所以,我们把 Q 的度量标准分成了三个独立的求和。所有这些求和都可以通过 matchTemplate 函数计算(使用 CV_TM_CCORR 方法)。具体来说:

sum {W(x', y')*I(x+x', y+y')^2} = matchTemplate(I^2, W, method=2)
sum{W(x', y')*2*I(x+x', y+y')*T(x', y')} = matchTemplate(I, 2*W*T, method=2)
sum{W(x', y')*T(x', y')^2)} = matchTemplate(T^2, W, method=2) = sum(W*T^2)

最后一个元素是一个常数,所以在最小化时它没有任何影响。不过,看到我们的模板是否完美匹配(如果 Q 接近于零)还是有用的。尽管如此,对于最后一个元素,我们实际上不需要 matchTemplate 函数,因为它可以直接计算。

最终的伪代码看起来是这样的:

result = matchTemplate(I^2, W, method=2) - matchTemplate(I, 2*W*T, method=2) + as.scalar(sum(W*T^2))

它真的完全按照定义来做吗?从数学上来说是的。 实际上,会有一些小的舍入误差,因为 matchTemplate 函数是基于 32 位浮点数工作的,但我认为这不是大问题。

请注意,你可以扩展分析,并为 matchTemplate 提供的任何度量标准创建加权等价物。

这对我来说确实有效。抱歉我没有提供实际的代码。我是在 R 语言中工作,所以没有 Python 的代码。但这个想法非常简单明了。

希望这能帮到你。

撰写回答