在浮动[] []中搜索3D模式

时间:2011-12-30 19:41:29

标签: java search design-patterns matching

我有一个浮点值数组,可以解释为灰度图像或3D表面(高度图)。 例如,它可能是一个像这样的10x10数组:

0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 0 0
0 0 4 0 9 0 0 0 0 0
0 0 0 0 0 0 0 0 3 0
0 8 0 0 0 0 0 0 0 0
0 0 0 6 0 2 8 7 0 0
0 0 0 0 0 3 5 5 0 0
0 0 0 0 0 6 2 1 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0

我正在寻找一个Java库(或高效算法)来检测类似于参考模式的一个(或多个)模式的存在和位置,例如我想获取位置(5,5)作为结果无论我在寻找:

2 8 7
3 5 5
6 2 1

或:

3 8 6
3 6 5
5 2 3

有什么想法吗?

3 个答案:

答案 0 :(得分:1)

我不知道任何Java库,但我认为编程不会太难。这个问题可以看作是子串问题的衍生物,除了你没有线性字符串。这里有一些Java-ish伪代码可能非常接近。

for(int x = 0; x < heightmap.width(); ++x)
    for(int y = 0; y < heightmap.height(); ++y)
        if(find_pattern(x, y))
            // YAY! pattern starts at (x, y)

// start at (x, y) and find an exact match
boolean find_pattern(int x, int y)
{
      for(int xx = 0; xx < pattern.width(); ++x)
          for(int yy = 0; yy < pattern.width(); ++x)
              if(heightmap[x + xx][y + yy] != pattern[xx][yy])
                  return false;
      return true; 
}

这将找到完全匹配。如果你想要一些东西,比如加或减2,那么你需要在find_pattern()中使用一些额外的逻辑而不是!=比较。

可能还有一些其他算法运行得更好。这可能是编程最简单的。复杂性在O(n ^ 2 * m ^ 2)中运行:给定n是高度图的宽度和高度,m是图案的宽度和高度。

注意:这不做边界检查!

如果实施边界检查,它将减少所需的比较次数,因为很明显上述模式无法在高度图的最右边两列中开始。有趣的是,当你进行边界检查时,复杂性变为O(n ^ 2),因为比率n:m变为1:1或0:1

答案 1 :(得分:0)

如果您可以将数据表示为一维数据 数组你基本上有一个字符串(只包含数值) 可以使用正则表达式搜索模式。如果 这是不可能的Java(即创建一串浮动代替 字符)它不应该太难滚动(简单) 用于匹配正则表达式的实现[1]。

[1] http://matt.might.net/articles/implementation-of-nfas-and-regular-expressions-in-java/

答案 2 :(得分:0)

这是图像过滤的问题。最基本的方法可以用这种方式表达:

for i in 0..image.height
  for j in 0..image.width
    result = 0
    for k in 0..pattern.height
      for l in 0..pattern.width
        if  i + k < image.height && j + l < image.width
          result += image[i + k][j + l] * pattern[k][l]
    if result > threshold
      /* Found a solution */

对于给定问题,您必须通过反复试验来找到数字threshold。也许将数字标准化为[0,1]区间是个好主意。然后,例如result / (pattern.width * pattern.height) > 0.75意味着“75%喜欢模式”。

根据图像的大小和图案,这可能会很慢 - 在这种情况下,您可以查看Image Filtering in the Frequency Domain