我需要为拼图设计求解器,它被分成矩形瓷砖(几行和几列):
BufferedImage subImage =
image.getSubimage(y, x, dWidth, dHeight)
然后以小于 1.0 的比例调整大小:
BufferedImage resized = new BufferedImage(newWidth, newHeight, original.getType());
我的算法背后的想法是总结当前瓦片边的每个适当像素与所有其他相对瓦片边之间的差异 - 例如对于右边缘 - 我定义了这样的代码:
for(Side s:reverseSides) { ...
{for(int i=0;i<height;i++) //checking current tile's right side
int rgbValue1=image.getRGB(width-1,i); //right side rgb values of current tile
int rgbValue2=imageN.getRGB(0,i); //left side rgb values of other tiles
....
int diff=|rgbValue1-rgbValue2|;
sum+=diff;
}
}
根据某种算法,我从某个边开始,其 rgbvalues 的总和在所有边的总和的整个范围的中间(sortinglistBySum/2)。然后我找到所有对立面的最小总和,并遍历该 Tile 的所有其他 3 个面,然后选择 Tiles,它至少有一个已处理的面,存储在队列中,直到所有面都以连续的方式处理。
但是第一个出乎意料的大问题是,大约 80 个像素(宽度或高度)的最小总和约为 50-70 000 000 个单位(RGB),而最大值可能超过 1000 000 000。所以这个最小和,甚至一个差异,例如 first/second/Npixel getRGB(width-1,1) - getRGB(0,1) - 就足够大了。确实在分割之前 - 相邻边缘的像素位置之间的差异应该只有 1 个像素?
因此,在这种情况下,如果左图块“右边缘索引”宽度-1 = 80,则匹配右图块左侧的 0 索引应为 81。或者至少差异可能为 2-如果图像丢失一条垂直像素线被分割,并且图像宽度除以列数不会产生整数值(我认为它不是真实图像,因此在技术上不应该丢失像素,只是在数学上)。
但是当我计算差异之和时。一个图块中两条相邻的垂直(或水平)像素线 - getRGB(width-2,i) - getRGB(width-1,i) - 它产生的值要低得多 - 大约 5-7 000 000. getRGB(width -3,i) - getRGB(width-1,i) - 30-40 000 000。所以我不明白为什么原始图像的相邻像素集之间存在如此大的差异?
另一个问题是,当我发现差异最小的反面时,我会检查这个反面的最小差异总和,并且只有当差异总和相互匹配时。我将这些边定义为相邻的,如果这个共同的最小总和小于我自己根据经验定义的某个阈值,也受到限制 - 在我的情况下,我认为它大约为 150 000 000(RGB 差异。),但这只是近似值。
但是还有第三个,可能是最困难的问题 - 如何检查这个匹配的边是否不是整个图像的边缘边,即使存在和的相互匹配,并且小于阈值,但实际上这些边不应该匹配为它们在原始图片中不相邻?!
这种方法工作得比较好,除了要考虑很多方面,以及在 Java Swing 布局中移动和更改网格单元的困难。例如,在我的第三个测试图像中匹配“单边”问题,在一个在最后一次迭代中,但它也可能在开始时发生。阈值在上面的一些不常见的情况下,用于无数学运算的边(确实与最小和相互匹配),或者在真正匹配的边下。
那么对于简单有保证的算法有哪些建议和参考,还有哪些更可靠的边缘检查和模式可以使用?为什么相邻边的rgb值差异之和如此之大?我什至以前读过,它应该对平方 rgb 值的差求和,但它会改变什么?另请阅读有关使用一些基于统计的算法的建议,因此可能会检查所有组合 - 检查从每个当前边缘(不仅仅是一个)遍历的边缘组合,然后选择最佳组合。