找出包含一条线的周围矩形区域

3
我的问题仅涉及OpenCV/Matplotlib。然而,为了理解问题,请耐心听我讲一下机器学习/计算机视觉方面的内容:
我正在处理地图数据集上的图像分割问题。我将使用完全卷积网络(FCN)来解决这个问题。
现在,FCN需要一个对应的分割图像作为输入图像。例如:

image and its groundtruth

左侧图像是实际图像,右侧图像是图像的适当“注释”。基本上,每个对象(类)都被其自己的颜色完全填充 - 汽车、道路、建筑等。
现在,在我的情况下,我正在处理平面图数据。示例平面图像如下:

Example floorplan image

这些图像中相关的实体包括墙壁、门等。
问题是,我已经获取了大量这种图像的注释数据,但它们并不是以上述形式进行注释的。墙壁被注释为简单的线条——这意味着它们只有1像素的厚度,并且实际上并没有填充实际图像中墙壁的区域/厚度。请参见以下示例:

Annotated Data I have

在上面的图片中,可以看到左上角有两条代表墙壁的线。虽然墙很厚,但我作为注释数据只有那些粉色的1像素宽的线。
然而,我需要的实际上是完整的填充区域墙壁。例如:

Ground truth I want

现在我想做的是,以编程方式将这些线转换为填充区域,即基于每堵墙的线条数据,我希望创建一个包含这些线条的墙的填充版本。
因此,问题本质上是: 如果我有一个矩形区域内的细线,是否可以以某种方式获得它所代表的整个矩形区域?如果可以,我可以用它的颜色填充它,并按需要注释。 我们可以做出一些假设: - 线条始终代表它们所在的墙 - 墙通常是较粗的线条,只有与图像其余部分相比较暗的颜色
重新进行数据标注将非常困难和昂贵,因此我希望知道是否可以通过编程实现此目标。
我对opencv和matplotlib的了解非常有限,因此可能会问一些初学者问题。如果是这种情况,请告诉我需要阅读的算法或函数。
谢谢。

很抱歉,我没有理解为什么要对这个问题进行投票。如果你们能告诉我原因,那就太好了。即使有人能简单地指点我一下,我也会很高兴的。 - Bhavul
2个回答

2

我会编辑我的答案来涵盖@Prune的条件。 我可能会尝试一些逻辑,比如:

  1. 寻找粉色线条。 为了做到这一点,您可以查看:如何在opencv中检测线条。这部分的结果是一个包含检测到线段端点的数组。
  2. 查找每条线的方向。 考虑一条线的端点:[x1;y1][x2;y2]。如果(x2-x1)>(y2-y1),则该线是水平的。否则,该线是垂直的。
  3. 查找新的端点。如果线是水平的,从最左边(较小的x)的端点向左移动,直到找到深灰色像素。一旦找到它,它将成为您的新左端点(x1')。对于“最右边”(较大的x)的端点,执行相同的操作,这次向右移动,以便找到x2'如果线是垂直的,从下面(较小的y)的端点向下移动,直到找到深灰色像素。一旦找到它,它将成为您的新下端点(y1')。对于上面(较大的y)的端点,执行相同的操作,这次向上移动,以便找到y2'
  4. 绘制矩形,以便涂上新墙。 如果墙的宽度是恒定的,并且粉色线条是居中的,则可以从这里简单地绘制矩形。 如果线是水平的,矩形的左上角坐标为[x1';y1+墙宽一半],右下角坐标为[x2'; y2-墙宽一半]如果线是垂直的,矩形的左上角坐标为[x1-墙宽一半;y1'],右下角坐标为[x2; y2'-墙宽一半]

如果第四个条件没有满足,请告诉我。在这种情况下,例如水平线,我们需要沿着水平线向上/向下迭代,寻找暗像素之间更小的距离,然后获取这些y坐标来帮助绘制矩形。


2
谢谢。我最初也是这么想的,但对我来说,这似乎不是一个很优化的方法。无论如何,即使我继续使用这种方法,是否有一种好的方式可以利用一些现有的matplotlib或opencv2函数来帮助我完成这个任务?比如说,是否有方法可以直接获取粉色像素点及其相邻的像素点?是否有任何方法可以持续填充相邻点,直到达到某个特定条件为止? - Bhavul
为了获取粉色像素,您可以使用一种称为InRange的函数。https://docs.opencv.org/3.4/da/d97/tutorial_threshold_inRange.html。现在,要找到满足特定条件的像素,我相信迭代直到找到图像边界将是最好的方法,尤其是对于我在编辑答案中提供的解决方案。 - Mariana Mascarenhas de Carvalh
1
嘿,谢谢你提供更新和更清晰的答案。我刚好采用了一种方法,在处理垂直线时,我检查左侧一个像素的端点是否具有相同的背景颜色...如果是的话,我会在这里画一条线。然后再向左移动1个像素。以此类推...同样地,对于右侧也是如此。然后对于水平线,我同样迭代并继续绘制上下相邻的线条。这种方法也有效。你的方法也可以。我接受你的答案。 对于将来参考此问题的任何人,请记住你的粉色线条必须清晰地位于墙壁区域内。 - Bhavul

2
通常情况下,您可以使用简单的“填充”算法,就像Mariana的答案中建议的那样。但是,您只需要扩展到给定行的范围内--不能继续沿着该办公区域的西墙延伸。我假设每个最终结果都将是与绘图轴对齐的矩形。
相反,您需要一种“波前”填充方法:在南北方向(超过一个像素的线条尺寸)上扩展整个线条,只要所有相邻的像素都是灰色的。然后在东西方向上执行相同的操作。您可以通过将线条复制到相邻的像素行/列来执行扩展。
我不知道有哪个软件包直接支持此功能,但大多数软件都会执行矢量化的复制粘贴或等效更改。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接