将图像拆分为较小图像的算法,减少空白量并指定最大矩形数量

标签 algorithm image rectangles

我正在寻找一种算法,它可以将图像分割成较小的图像,但有一些限制。 一个约束是使用最少量的“空白”,即空像素。另一种是指定最大数量的图像将其分割成。

例如让我们看下图。其中有很多“空白”。我想将这张图片分成几张其他图片,这样我就可以减少这张图片占用的内存量,也可以减少这张图片“绘制”的数量。

.=transparent pixel
x=colored pixel

....................
.xxxxxxxxxxx........
...xxxx...xxxxxx....
.............xxxxx..
...............xxx..
...............xxx..
....................
..xxxxxx............
.....xxxxxxxxxxx....
.........xxxxxxxxxx.
....................

假设我希望将图像拆分为最多 4 张图像,可能的解决方案如下图所示。

....................
.111111111111111....
.111111111111111....
.............22222..
.............22222.
.............22222..
....................
..3333333...........
..33333334444444444.
.........4444444444.
....................

有没有人有这方面的算法,或者知道执行此操作的算法的名称? 我一直在寻找一段时间并找到了一些相关的算法,但是我发现的算法没有考虑到空格,例如他们将图像分割成只覆盖非透明像素的矩形,从而产生了大量的矩形。 我正在处理的现实生活数据是 1024*1024 像素的图像,我希望将它们减少到最多 16 个部分。诀窍是使用最少的空白提取 16 张图像。

最佳答案

我会使用与 ravloony 相同的算法,但进行了细微而重要的修改,使用“裁剪”操作查找不完全为空的最小/最大列和行,并丢弃其余部分。

在实践中,裁剪操作将获取一个 X*Y 区域作为输入,并输出 4 个整数 - 包含该区域所有已用像素的最小矩形的坐标。这也可用于检测和丢弃空白区域。

例子

....................
.xxxxxxxxxxx........     xxxxxxxxxxx.......
...xxxx...xxxxxx....     ..xxxx...xxxxxx...
.............xxxxx..     ............xxxxx.
...............xxx.. =>  ..............xxx. (first crop)
...............xxx..     ..............xxx.
....................     ..................
..xxxxxx............     .xxxxxx...........
.....xxxxxxxxxxx....     ....xxxxxxxxxxx...
.........xxxxxxxxxx.     ........xxxxxxxxxx
....................

现在将图像分成 NxN 部分(这里使用 N=4)并对每个部分使用裁剪操作:

xxxxx|xxxxx|x....|
..xxx|x...x|xxxxx|
---------------------
     |     |  xxx|xx
     |     |  ..x|xx
---------------------
     |     |    x|xx
     |     |     |
---------------------
 xxxx|xx...|     |
 ...x|xxxxx|xxxxx|
     |...xx|xxxxx|xxx

对于这个例子,我们得到 10+10+10+6+4+1+2+8+15+10+3=79 个像素,而不是 21*11=231,后者只有 34.2%。请注意,这恰好与您手工制作的 4 部分分割的数量相同 (30+15+14+20=79)!

结论

当然会有一些额外的数据来跟踪每个 16 个部分的位置和大小,它不会总是给出最好的结果,但我认为这是速度和节省之间的一个很好的折衷,算法是易于编写和维护。

关于附加数据:大小为 1024x1024 并拆分为 4x4 部分的图像将使您可以使用 4 字节值来存储每个矩形,因此附加数据大小仅为 16*4 = 64 字节 - 关于这一点,您或许应该考虑增加 16 部分的最大值,除非它会严重减慢其他部分的速度,例如绘图。

最坏情况

此算法的最坏情况是某些像素位于或靠近边缘集的部分,如下所示:

x......x    xxxxxxxx    xx......
........    ........    x.......
........    ........    ........
x......x    ...x....    .......x

我想到了几种解决方案:

  • 再次拆分区域(结束 使用四叉树实现)
  • 使用一些额外的步骤来检测 中完全空的矩形 里面。
  • 稍微翻译一下定义部分的网格

关于将图像拆分为较小图像的算法,减少空白量并指定最大矩形数量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5991302/

相关文章:

ruby-on-rails - 如何从外部网站重新创建图像预览?

c++ - 矩形交点。为空路口打印消息

java - 给定开始和结束矩形时如何创建矩形路径

c++ - 数组中的最大 X 值

Android:在用户触摸的 Canvas 上绘制图像

image - 带有图像文件内容的 Apache 基准测试 POST

java - 如何在 Java 中创建 'cooldown rectangle' 效果?

java - 使用 hashmap 改进词频计数

algorithm - 反向查找已排序的合并列表

c++ - 带内部while循环的while循环:O(n)或O(n ^ 2)?