Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将大图像分割为两个不重叠的图像,其并集就是大图像_C++_Image Processing - Fatal编程技术网

C++ 将大图像分割为两个不重叠的图像,其并集就是大图像

C++ 将大图像分割为两个不重叠的图像,其并集就是大图像,c++,image-processing,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.从第一行开始考虑。 2.使用二进制搜索查找边界的起点。在上面的例子中,它将是 1 1 | 2

给定一个大图像,由存储为矩阵的较小图像组成。我需要找到一个边界,将大图像分为两部分(不一定相等,但最好接近相等),而不经过较小的图像。

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

1 1 2 2 2 1 1 2 2 2 3 3 3 4 4 3 3 3 4 4 是由4个小图像组成的大图像矩阵。 我需要找到一个这样的边界,将其分割成两个较小的图像,这样它们的大小就不会相差很大

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

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 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 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 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 1 1 1 1 1 1 1 1 1 1 -- 3 3 3 2 2 3 3 3 2 2 然后继续。
如何改进此解决方案? 有更好的解决方案吗?我的算法会随时失败吗?
我将用C++编码。启发式/贪婪的解决方案也不错。

如果图像大到有意义,那么您可以利用局部差异来指导边界选择。
为了简单起见,这里有一个在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,如下图所示:
理想情况下,您希望获得代表值1到4的这些“托盘”之间的边界。一种方法是将图像左/右移动一个像素,上/下移动一个像素,然后与原始图像相减。这将生成另一个仅在边界位置具有值的图像。
请参见MATLAB中的示例:

mask=((img-shift(img,1) + img-shift(img',1)')~=0);
这将创建一个遮罩,方法是将右移图像和原始图像的差值与下移图像和原始图像的差值相加,最后将结果与零进行比较(零值将是除边界外的所有像素值)。函数移位只是将矩阵的值向右或向左移位。无需将代码放在这里,因为我只想展示概念。
因此,您将得到以下蒙版图像:
由于前面的减法生成了不需要的边框,因此此遮罩在右侧和底部被裁剪了一个像素。

在此图像中,真值(白色像素)位于前一图像的最后一个像素上,即图像1在第一个边界结束,图像2从下一个像素开始,因此图像1的边界为x=20和y=30,对于其他子图像,依此类推。

我能想到的两件事是,因为您希望两半尽可能接近相等,从中间开始,走到边上,在水平和垂直之间交替,而不是在垂直开始之前排出水平。两者都使索引更复杂一些,但通常情况下,更快的代码比简单的直接方法要复杂一些。另外,我认为你的第四步是没有必要的——至少如果你只想要直线解决方案的话。如果多段解决方案可以,那就好了。。。
img = [ ones(20,20), 2*ones(20,30); ones(10,20), 2*ones(10,30); 3*ones(20,30), 4*ones(20,20)]
mask=((img-shift(img,1) + img-shift(img',1)')~=0);