我有一个2D整数数组,它表示2D表面上的分组(晶粒)。像这样的东西:
(根据图像所属的组为该图像的每个像素分配一个整数,因此,每个红色像素都分配为1,例如每个蓝色为2)
给定两个这样的分组之间的边界上的X,Y坐标(用户单击那里),我如何跟踪这两个分组之间的边界,以保存沿边界的每个像素坐标并获得两个端点坐标(I' m与没有端点但有循环的机柜的情况无关)
无论我想出什么算法,实现起来似乎都很繁琐,而且我简直无法想象以前没有人做过。有什么帮助吗?最好是C#中的解决方案,但是对算法的任何暗示都将不胜感激。
编辑:
我应该说过,我将要实现一种算法来矢量化该行,如下所示:
两个端点之间的
我认为实现起来很容易,所以我没有说明。为了到达那里,我只需要解决当前问题...
有关问题:
原始数据如何格式化? -这是一个简单的
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/