足迹发现算法

时间:2016-03-28 23:49:11

标签: algorithm image-processing 2d polygon

我试图想出一种算法来优化多边形(或多个多边形)的形状,以最大化该形状中包含的值。

我有3列数据:

  • X:x轴上的位置
  • Y:y轴上的位置
  • 值:可以具有正值和负值的块的值。

此数据来自常规网格,因此每个x和y值之间的间距是一致的。

我想创建一个边界多边形,使用添加的条件最大化包含的值。

  • 需要在多边形的所有点处保持最小半径。这意味着我们将丢失一些正值块或获得一些负值块。

我使用的当前算法执行以下操作

  1. 查找最大块值作为起点(或用户定义)
  2. 查找最小半径范围内的所有块,并通过检查整体值是否为正确来确定它是否可行
  3. 从进一步的值计算中移除最小搜索半径中的所有块,并将它们标记为最终形状的一部分
  4. 移动到原点周围螺旋线确定的下一个点。 (中心始终是网格点,因此按deltaX或deltaY移动)
  5. 这似乎正在捡起一些不需要的细胞。我确定那里有形状算法,但我不知道该怎么查找才能找到帮助。

    下面是一张希望有助于概述问题的图片。阳性细胞以红色显示(阴性细胞未显示)。黑色轮廓显示我当前正在返回的形状。我相信左侧应该更多。最小半径为100米,左下方的黑色圆圈大约是这个。

    enter image description here

    现在代码在R中运行但如果我能使算法正确,我可能会转向其他东西。

    为了回应不明确的投票,我试图在没有背景或尝试解决方案的情况下解决的问题是:

    "围绕一系列点创建边界多边形(或多边形)以最大化包含的值,同时沿多边形保持最小曲率半径

    编辑:

    数据

    我应该包含一些可以找到的数据here

    该文件是csv。 4列(X,Y,Z [未使用],值),长度约为25k,大小为800kb。

1 个答案:

答案 0 :(得分:5)

图形方法

我会以图形方式处理此问题。我的直觉告诉我,内部点完全位于铸造圆圈内,距离附近所有足迹点的最小半径为r。这意味着如果您从半径为r的每个足迹点投射圆圈,则所有相邻圆圈中至少一半内的所有点都在您的多边形内。如果你深入到多边形内部,那么你可以在任何像素上得到Pi*r^2个重叠的圆圈。如果你处于边缘,你就有一半了。这很容易计算。

首先我需要数据集。正如你提供的只是jpg文件我没有vales只是情节。所以我像二进制图像一样处理这个问题。首先,我需要重新着色图像以消除 jpg 颜色失真。在那之后,这是我的意见:

input

我选择黑色背景可以轻松地在图像上应用叠加数学,而且我更喜欢白色并留下足迹红色(最大饱和度)。现在算法:

  1. 创建临时图片

    它应该是相同的大小并清除为黑色(color=0)。处理其像素,如重叠圆的整数计数器。

  2. 演员圈

    source image中的每个红色像素添加+1到圆圈内的每个像素,同一像素周围的最小半径r但{{1} }}。结果是这样的(蓝色是我的temp image的低位):

    circle count

    作为pixelformat,我使用r,因为这是示例+/-像素中左下角的半径。

  3. 仅选择内部像素

    如此重新着色的临时图像。所有r=24的像素重新着色为黑色,其余像素为红色。结果是这样的:

    inside

  4. 仅选择多边形圆周点

    只需将黑色像素附近的所有红色像素重新着色为中性色蓝色,其余为黑色。结果:

    polygon

    现在只需将结果多边形化。要与输入图像进行比较,您可以将它们组合在一起(I color < 0.5*pi*r^2它们一起):

    combine

  5. <强> [注释]

    您可以使用最小半径或区域阈值属性来实现不同的行为。但我认为这与你的问题非常接近。

    这里有一些C ++源代码:

    OR

    我将自己的//picture pic0,pic1; // pic0 - source // pic1 - output/temp int x,y,xx,yy; const int r=24; // min radius const int s=float(1.570796*float(r*r)); // half of min radius area const DWORD c_foot=0x00FF0000; // red const DWORD c_poly=0x000000FF; // blue // resize and clear temp image pic1=pic0; pic1.clear(0); // add min radius circle to temp around any footprint pixel found in input image for (y=r;y<pic1.ys-r;y++) for (x=r;x<pic1.xs-r;x++) if (pic0.p[y][x].dd==c_foot) for (yy=-r;yy<=r;yy++) for (xx=-r;xx<=r;xx++) if ((xx*xx)+(yy*yy)<=r*r) pic1.p[y+yy][x+xx].dd++; pic1.save("out0.png"); // select only pixels which are inside footprint with min radius (half of area circles are around) for (y=0;y<pic1.ys;y++) for (x=0;x<pic1.xs;x++) if (pic1.p[y][x].dd>=s) pic1.p[y][x].dd=c_foot; else pic1.p[y][x].dd=0; pic1.save("out1.png"); // slect only outside pixels pic1.growfill(c_foot,0,c_poly); for (y=0;y<pic1.ys;y++) for (x=0;x<pic1.xs;x++) if (pic1.p[y][x].dd==c_foot) pic1.p[y][x].dd=0; pic1.save("out2.png"); pic1|=pic0; // combine in and out images to compare pic1.save("out3.png"); 类用于图像,因此有些成员是:

    • picture图片大小(以像素为单位)
    • xs,ysp[y][x].dd位置的像素,为(x,y)位整数类型
    • 32 - 清除整个图片
    • clear(color) - 将图片大小调整为新分辨率

    [编辑1]我在源代码中遇到了一个小错误

    我注意到有些边缘太尖锐所以我检查了代码,我忘记在填充时添加圆形条件,所以它填充了正方形。我修复了上面的源代码。我真的只是添加了行resize(xs,ys)。结果略有变化,因此我还使用新结果更新了图像

    我玩内部面积系数比率和这个:

    if ((xx*xx)+(yy*yy)<=r*r)

    为您提供更好的匹配。它越小,多边形可以在外部覆盖范围内重叠。结果:

    final result