Java 浮动中的三维模式搜索[][]
我有一个浮点值数组,可以解释为灰度图像或3D曲面(高度贴图)。 例如,它可能是一个10x10阵列,如下所示:Java 浮动中的三维模式搜索[][],java,search,design-patterns,matching,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 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
或:
有什么想法吗?如果您可以将数据表示为一维 数组实际上有一个字符串(仅包含数值) 可以用正则表达式搜索模式。万一 这在Java中是不可能的(例如,创建一个浮点字符串) (角色)你自己的角色应该不会太难(简单) 匹配正则表达式的实现[1]
[1] 这是一个图像过滤问题。最基本的方法可以这样表达:
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 */
0..image.height中的i的
对于0..image.width中的j
结果=0
对于0..pattern.height中的k
对于0..pattern.width中的l
如果i+k阈值
/*找到了解决办法*/
对于给定的问题,您必须通过反复试验才能找到阈值。也许首先将数字标准化为[0,1]区间是个好主意。例如,result/(pattern.width*pattern.height)>0.75
表示“75%喜欢这个图案”
根据图像和模式的大小,这可能会很慢-在这种情况下,您可以查看我不知道有任何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;
}
for(int x=0;x
这将找到一个精确的匹配。若您想要一些东西,比如说正负2,那个么您需要在find_pattern()中使用一点额外的逻辑,而不是!=比较
可能还有其他一些算法运行得更好。这可能是最简单的编程。从复杂性的角度来看,这以O(n^2*m^2)表示:给定n是heightmap的宽度和高度,m是模式的宽度和高度
注意:这不进行边界检查
如果实现边界检查,将减少所需的比较次数,因为显然上述模式无法从高度贴图最右边的两列开始。有趣的是,当你进行边界检查时,复杂度变为O(n^2),因为n:m的比率变为1:1或0:1这个算法的效率应该有多高?显然,你可以在nnm*m时间内完成。为了更好的估计,你需要一些先进的技术。是的,谢谢。我知道有可能编写这样的函数,但我想知道是否有更高效的算法,即使在CPU使用率较低的情况下,也能很好地处理大数据。例如,我听说了小波的东西,但我没有找到任何Java库来做这个。。。
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;
}