我试图想出一种算法来优化多边形(或多个多边形)的形状,以最大化该形状中包含的值。
我有3列数据:
此数据来自常规网格,因此每个x和y值之间的间距是一致的。
我想创建一个边界多边形,使用添加的条件最大化包含的值。
我使用的当前算法执行以下操作
这似乎正在捡起一些不需要的细胞。我确定那里有形状算法,但我不知道该怎么查找才能找到帮助。
下面是一张希望有助于概述问题的图片。阳性细胞以红色显示(阴性细胞未显示)。黑色轮廓显示我当前正在返回的形状。我相信左侧应该更多。最小半径为100米,左下方的黑色圆圈大约是这个。
现在代码在R中运行但如果我能使算法正确,我可能会转向其他东西。
为了回应不明确的投票,我试图在没有背景或尝试解决方案的情况下解决的问题是:
"围绕一系列点创建边界多边形(或多边形)以最大化包含的值,同时沿多边形保持最小曲率半径34>
编辑:
数据
我应该包含一些可以找到的数据here。
该文件是csv。 4列(X,Y,Z [未使用],值),长度约为25k,大小为800kb。
答案 0 :(得分:5)
图形方法
我会以图形方式处理此问题。我的直觉告诉我,内部点完全位于铸造圆圈内,距离附近所有足迹点的最小半径为r
。这意味着如果您从半径为r
的每个足迹点投射圆圈,则所有相邻圆圈中至少一半内的所有点都在您的多边形内。如果你深入到多边形内部,那么你可以在任何像素上得到Pi*r^2
个重叠的圆圈。如果你处于边缘,你就有一半了。这很容易计算。
首先我需要数据集。正如你提供的只是jpg文件我没有vales
只是情节。所以我像二进制图像一样处理这个问题。首先,我需要重新着色图像以消除 jpg 颜色失真。在那之后,这是我的意见:
我选择黑色背景可以轻松地在图像上应用叠加数学,而且我更喜欢白色并留下足迹红色(最大饱和度)。现在算法:
创建临时图片
它应该是相同的大小并清除为黑色(color=0)
。处理其像素,如重叠圆的整数计数器。
演员圈
为source image
中的每个红色像素添加+1
到圆圈内的每个像素,同一像素周围的最小半径r
但{{1} }}。结果是这样的(蓝色是我的temp image
的低位):
作为pixelformat
,我使用r
,因为这是示例+/-像素中左下角的半径。
仅选择内部像素
如此重新着色的临时图像。所有r=24
的像素重新着色为黑色,其余像素为红色。结果是这样的:
仅选择多边形圆周点
只需将黑色像素附近的所有红色像素重新着色为中性色蓝色,其余为黑色。结果:
现在只需将结果多边形化。要与输入图像进行比较,您可以将它们组合在一起(I color < 0.5*pi*r^2
它们一起):
<强> [注释] 强>
您可以使用最小半径或区域阈值属性来实现不同的行为。但我认为这与你的问题非常接近。
这里有一些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,ys
是p[y][x].dd
位置的像素,为(x,y)
位整数类型32
- 清除整个图片clear(color)
- 将图片大小调整为新分辨率[编辑1]我在源代码中遇到了一个小错误
我注意到有些边缘太尖锐所以我检查了代码,我忘记在填充时添加圆形条件,所以它填充了正方形。我修复了上面的源代码。我真的只是添加了行resize(xs,ys)
。结果略有变化,因此我还使用新结果更新了图像
我玩内部面积系数比率和这个:
if ((xx*xx)+(yy*yy)<=r*r)
为您提供更好的匹配。它越小,多边形可以在外部覆盖范围内重叠。结果: