我有一个2D整数数组,它表示2D表面上的分组(晶粒)。像这样的东西:

(根据图像所属的组为该图像的每个像素分配一个整数,因此,每个红色像素都分配为1,例如每个蓝色为2)

给定两个这样的分组之间的边界上的X,Y坐标(用户单击那里),我如何跟踪这两个分组之间的边界,以保存沿边界的每个像素坐标并获得两个端点坐标(I' m与没有端点但有循环的机柜的情况无关)

无论我想出什么算法,实现起来似乎都很繁琐,而且我简直无法想象以前没有人做过。有什么帮助吗?最好是C#中的解决方案,但是对算法的任何暗示都将不胜感激。

编辑:

我应该说过,我将要实现一种算法来矢量化该行,如下所示:

两个端点之间的

  • 定义了一行
  • 获取距当前线最远的边界点,如果距离d远,请在此点分割线,因此有两个线段
  • 重复,直到没有边界点比线条
  • 距离d远

    我认为实现起来很容易,所以我没有说明。为了到达那里,我只需要解决当前问题...

    有关问题:

    原始数据如何格式化? -这是一个简单的short[,] labeling;,大小约为250x150,如下所示:
    11111112222
    11111222222
    11112222222
    11112222222 <- user clicks on leftmost 2 or rightmost 1 -> I want to trace that border
    11111122222                                                down to the first
    11111133322                                                encountered 3 and up to the
    11333333333                                                frame-border
    

    什么是端点? -正如我一直在考虑全局解决方案时,我可以将端点描述为:2x2区域,其中4个像素由color1,color2和至少三分之一的不同颜色组成。

    什么是连续连接的? -其余的算法并不重要,请参阅下文

    y形区域呢? -我不关心它们,您可以假设边框后的color1区域至少为2像素宽,这就是为什么我们谈论4或8邻域也无关紧要的原因。

    我目前有什么? -最初,我尝试了一种“步行”算法,类似于发布的mvds,但是发现我在所有4个方向上都非常乏味且看上去很糟糕,却要进行步进,邻居计算和检查。对于“这是最后一步来自的方向,请不要检查该像素的邻域”,我找不到很好的表示。

    然后,我放弃了行走算法,并尝试了一种全局方法(如过滤器):对于每个像素,检查其是否为color1并在其4邻域中具有color2。有了这个,我得到了color1和color2之间的所有边界。我打算删除所有未通过某种泛洪填充连接到用户单击的坐标的边界,但是随后出现了一个问题:端点在哪里?

    我仍然感谢您的投入。现在,我将了解mvds的算法可以走多远。

    最佳答案

    我假设您已经确定了上述2种颜色,例如如“mvds”所述,作为预处理步骤。

    我想您会发现使用一个坐标系很有帮助,其中每个(x,y)都不代表一个像素,而是代表4个像素接触的点。然后,您可以编写一个函数来确定North是否是边界像素边界,同样适用于South,East,West(或者您更喜欢使用上/下/左/右术语)。

    从边界上的某个点开始,例如在4x4邻域中扫描以N/S/E/W之一为边界的点。沿着该边框移动到下一个点,然后扫描除您进入的方向以外的所有4个方向,寻找下一个像素边框。重复直到像素边界用完。然后,您知道自己处在一个端点。

    回到起点,沿与最初拍摄方向不同的方向跟踪边框,直到到达另一个端点。

    这为您提供了所有像素边界。每个像素边界在一侧具有颜色1,在另一侧具有颜色2。

    (我本以为矢量化比确定边界要困难得多,但这不是您的主要问题,对吗?为此,我将从一个端点开始并遵循像素边界的顺序逐个边界,在每个点上检查从端点到当前点的直线是否与像素边界匹配。一旦不匹配,即为一行的结尾,然后开始新的一行。)

    关于二维数组中跟踪边界的算法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8874873/

    10-16 21:24