将大图像分成两个不重叠的图像,其联合是大图像

时间:2014-01-16 18:29:42

标签: c++ image-processing

给定由作为矩阵存储的较小图像组成的大图像。我需要找出一个边界,将大图像分成两部分(不一定相等,但最好几乎相等),而不会切割出较小的图像。

每个小图像由较大图像矩阵中的单个整数表示。 例如:

1 1 2 2 2 
1 1 2 2 2
3 3 3 4 4
3 3 3 4 4

是由4个小图像组成的大图像矩阵。 我需要找到一个这样的边界,将它分成两个较小的图像,这样它们的大小差别不大。

这是我的解决方案: 1.从考虑第1行开始 2.使用二分搜索找到边界的起点。在上面的例子中,它将像

  1 1 | 2 2 2 
  1 1   2 2 2
  3 3   3 4 4
  3 3   3 4 4

3.向下移动直到分割线不与图像相交。如果达到大图像的结尾,则停止。

  1 1 | 2 2 2 
  1 1 | 2 2 2
  3 3   3 4 4
  3 3   3 4 4

4.考虑剩下的行,再做第1,2,3步,并从旧线到新的划分线做出水平线。

  1 1 | 2 2 2 
  1 1 | 2 2 2
       --
  3 3   3 4 4
  3 3   3 4 4
  1 1 |  2  2 2 
  1 1 |  2  2 2
      -----
  3 3   3 | 4 4
  3 3   3 | 4 4

大图像结束......停止。

当然,如果在步骤2中找不到垂直线,我们可以先找到一条水平线,类似于以下情况:

  1 1 1 1 1
  1 1 1 1 1
  --
  3 3 3 2 2
  3 3 3 2 2

然后继续。
如何改进此解决方案? 有更好的解决方案,我的算法会随时失败吗? 我将用C ++编写代码。启发式/贪婪的解决方案也会很好。

1 个答案:

答案 0 :(得分:0)

如果图像在某种程度上足够大,那么你可以获得局部差异来指导你的边界选择 以下是为简单起见在MATLAB中实现的示例,但您将获得图片:
假设我们创建的图像类似于您定义的图像:

img = [ ones(20,20), 2*ones(20,30); ones(10,20), 2*ones(10,30); 3*ones(20,30), 4*ones(20,20)]

此命令创建一个50x50的图像,具有20x30子图像1,30x30子图像2,30x20子图像3和20x20子图像4,如下图所示: color-coded image
理想情况下,您希望获得表示值1到4的这些“托盘”之间的边界。一种方法是将图像向左/向右移动一个像素,在顶部/底部移动一个像素,然后用原始图像将其减去。这将生成另一个仅在边界位置具有值的图像 例如,参见MATLAB:

mask=((img-shift(img,1) + img-shift(img',1)')~=0);

这将通过将右移图像和原始图像的差异与底部移位图像和原始图像的差异相加来创建遮罩,最后,通过将结果与零进行比较(零值将全部除边界外的像素值)。函数移位只是向右或向左移动矩阵的值。没有必要在这里放置代码,因为我只想展示这个概念 因此,您最终会得到以下蒙版图像: mask image
由于先前的减法产生了不需要的边框,因此该掩模在右侧和底部被裁剪了一个像素 在此图像中,真值(白色像素)位于前一图像的最后一个像素上,即图像1在第一个边界处结束,图像2从下一个像素开始,因此图像1以x = 20和y = 30为界。等等其他子图像。