仅使用重叠方块重新创建图像

时间:2014-05-25 10:51:45

标签: algorithm math graphics

我尝试拍摄源图像,然后仅使用重叠的单色方块在透明画布上重新创建它。目标是使用尽可能少的方块。

换句话说,我采用空白的透明图像,并绘制各种颜色的正方形,直到我重新创建源图像,目标是尽可能少地使用正方形。

例如:
Sample image 1
这是源图像。它有两种颜色:红色和绿色。我想使用可能重叠的 only squares 来重新创建源图像。

理想的解决方案是一个大的红色方块,然后在顶部绘制两个绿色方块 - 这就是我希望我的算法找到的任何源图像 - 每个方块的位置,大小,颜色和顺序。 / p>


我打算处理的目标图像是这样的:
Target image

(8倍放大)

enter image description here

它有1411个非透明像素(最坏情况),并且使用不使用重叠方块的强力解决方案,我使用1246个方块重新创建了图像。


我目前的解决方案是一种蛮力方法:

  1. 创建源图像中使用的所有颜色的列表。每个项目都是"层"。图层具有颜色,2D阵列表示像素。订单很重要,但我不知道图层需要订购的顺序,所以最初是随意的。
  2. 对于列表中的每个图层,初始化2D数组。每个元素对应于源图像中的像素。与图层所选颜色颜色相同的像素标记为' 1'。位于当前图层上方的图层中的像素标记为"不关心"。所有其他像素都标记为' 0'。
  3. 使用一些算法处理每一层,使用最小数量的方块到达标记为' 1'的每个像素,而不触及标记为' 0'
  4. 的任何像素。
  5. 重新排列图层的顺序并返回步骤2.对每个可能的图层组合执行此操作,然后检查哪个排序使用的总方格数最少。
  6. 有人可能在答复中有更好的解释;但蛮力测试每个排列是不可行的,因为我的目标图像有31种颜色(导致31种排列)。

    至于我为什么要这样做?我试图在游戏中创建一个图像(Starbound),我只能使用正方形。懒惰的解决方案是为每个像素使用一个正方形,但这只是太多的正方形。

3 个答案:

答案 0 :(得分:1)

只是建议可能的解决方案。我还没试过。

这是一种贪婪的做法。

对于每个像素,计算包含它的最大均匀方块。

然后选择所有正方形中最大的正方形并将其覆盖的所有像素标记为"覆盖"。

然后在所有未标记的像素中,选择最大的覆盖方块,依此类推,直到没有未标记的像素为止。

关系无所谓,只需取任何最大的方块并标记其像素。

更新:重叠提供减少方格数的机会。

考虑形状填充顺序的所有可能排列。首先在底层绘制的形状可以(部分地)被其他一些隐藏。从顶层开始处理形状。处理形状以将每个像素与包含它的最大均匀方块相关联时,请将所有覆盖的像素视为不关心。

在给定的示例中,首先填充绿色方块;然后在填充红色方块时,绿色像素可以被视为红色或不是红色,具体取决于方便性。

如果您无法尝试所有排列,请随意尝试。遗传算法或模拟退火等启发式方法可能会有所帮助。这里没什么直白的。

答案 1 :(得分:0)

很难保证最佳解决方案。蛮力搜索将是巨大的。这需要启发式。

从边缘开始。走在外面的边缘,找到最常见的颜色。画方块 填补背景。

迭代,向内工作绘制覆盖最多的较小和较小的正方形 像素是错误的颜色。以单像素方块结束。

向内工作意味着减少外部边界框的大小 其中所有像素都是正确的颜色。在每个步骤中,正方形大小的上限将适合于边界框。选择得分最高的方块。

分数是基于旧颜色和新颜色错误或正确,因此每个像素有4个可能的值。每像素得分的一个示例函数是:

  • 错误 - >错误:0
  • 错误 - >右:1
  • 右 - >右:1
  • 右 - >错误:-2

我认为如果你总是减少边界框边缘上的错误方块的数量并且永远不会增加方形的大小,那么算法必须停止使用解决方案而不需要回溯。回溯解决方案可能会做得更好。

答案 2 :(得分:0)

“基于侵蚀的”启发式。


  • 考虑所有轮廓像素,即在形状外至少有一个邻居。

  • 在这些像素中,选择一种颜色(最常见的颜色?)。

  • 对于此颜色的所有轮廓像素,请计算不超过形状的最大方块。

  • 填充这些正方形,从大到小,直到覆盖整个轮廓。

  • 删除正确填充的像素,然后在侵蚀的形状上重新开始此过程。


在红色方块的情况下,所有轮廓像素都将被红色方块本身覆盖,第一个填充将“消耗”整个区域。

然后,移除红色覆盖的像素,两个绿色方块将保留。

所有绿色轮廓像素现在将被两个绿色方块覆盖,并且两个第一个填充将“消耗”所有绿色区域。