use*_*386 25 python opencv image-processing
我们假设我们正在寻找这个模板:
停止http://oi48.tinypic.com/2u7q1l4.jpg
我们模板的角是透明的,因此背景会有所不同,如下所示:
停在月球上http://i49.tinypic.com/ziw3mc.png
停在珠穆朗玛峰上http://i45.tinypic.com/2unwxhu.png
离开树叶http://i48.tinypic.com/t06v7k.png
假设我们可以在模板中使用以下掩码:
停止http://oi48.tinypic.com/2u7q1l4.jpg 停止面具http://i49.tinypic.com/ogclfd.png
找到它会很容易.
我尝试过的:
我已经尝试matchTemplate但它不支持蒙版(据我所知),并且在模板中使用alpha通道(透明度)无法实现这一点,因为它比较alpha通道而不是忽略这些像素.
我也研究了"感兴趣的区域",我认为这将是解决方案,但有了它,你只能指定一个矩形区域.我甚至不确定它是否适用于模板.
我确信通过编写自己的算法可以做到这一点,但我希望这可以通过.标准OpenCV,以避免重新发明轮子.更不用说,它很可能比我自己更优化.
那么,我怎么能用OpenCV + Python做这样的事情呢?
这可以仅使用matchTemplate功能来实现,但是需要一些解决方法。
让我们分析默认指标(CV_TM_SQDIFF_NORMED)。根据matchTemplate文档
,默认指标如下所示
R(x, y) = sum (I(x+x', y+y') - T(x', y'))^2
哪里I是图像矩阵,T是模板,R是结果矩阵。总和超过模板坐标做x'和y',
因此,让我们通过插入权重矩阵来更改此指标,权重矩阵W的尺寸与相同
T。
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)}
Run Code Online (Sandbox Code Playgroud)
因此,我们将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)
Run Code Online (Sandbox Code Playgroud)
最后一个元素是一个常量,因此,对于最小化它没有任何作用。另一方面,查看我们的模板是否具有完美匹配(如果Q接近零)可能仍然有用。但是,对于最后一个元素,我们实际上不需要matchTemplate功能,因为可以直接计算它。
最终的伪代码如下所示:
result = matchTemplate(I^2, W, method=2) - matchTemplate(I, 2*W*T, method=2) + as.scalar(sum(W*T^2))
Run Code Online (Sandbox Code Playgroud)
它真的按照定义执行吗?数学上是。实际上,由于matchTemplate函数可以在32位浮点上工作,因此舍入误差很小,但是我认为这不是一个大问题。
请注意,您可以进行范围分析,并拥有所提供的任何指标的加权等效项matchTemplate。
这实际上为我工作。对不起,我没有提供实际的代码。我正在R中工作,所以我没有Python中的代码。但是想法很简单。
我希望这将有所帮助。
| 归档时间: |
|
| 查看次数: |
7235 次 |
| 最近记录: |