如何从连续的单元格的外部单元格中创建多边形

时间:2017-02-01 20:19:06

标签: matlab geometry computational-geometry

我在Matlab中绘制了一个连续的细胞片段。 enter image description here

必须确定红色斑块的外部细胞,然后连接这些细胞中心的多边形将给出一个多边形。我如何计算连续补丁的外部细胞?

我有一个整数数组,其元素表示红色补丁中的单元格,例如

a=[1;64;23;456;345];

每个元素,比如64对应于图像中的一个单元格,它是属于红色区域的单元格。

解决问题的动机是处理具有最少边数的多边形而不是那么多单元。它减慢了计算速度。凸壳不够好。我不希望生成的多边形与棕色区域重叠。

我建议的是下图中左侧的情况,但看起来很难看。因此,更好的方法是跳过仅与外部棕色区域共享单个点的单元格。我希望我的外部细胞只是那些与外部棕色区域只有一个点的区域。

但是我们想要在结果多边形中避免大量的边缘!

enter image description here

3 个答案:

答案 0 :(得分:1)

使用图像处理工具箱您可以在图像上应用=VLOOKUP(A2, INDIRECT(A1&"!$B$13:$K$100"), 7, FALSE) ,而不是在扩张结果和原始图像之间应用dilation

enter image description here enter image description here

and operator

答案 1 :(得分:1)

尽管@ rahnema1的回答非常酷,但我认为OP正在询问更多如何根据所描述的规则提取边缘集。

这是我的方法,用于识别包含边缘的所有10个2x2像素模式。假设矩阵A的图像包含1 s和0 s(A = zeros(ny, nx); A(a) = 1):

% we identify patterns with edges over 2x2 patches, describing with
% the first 4 binary values what pixels are set, and with the next 2
% the edge with 2 indices over the 2x2 patch
patterns = [
 0,1,0,1,  3,4 % vertical edge at rhe right 
 1,0,1,0,  1,2 % vertical edge at the left
 0,0,1,1,  2,4 % horizontal edge at the bottom
 1,1,0,0,  1,3 % horizontal edge at the top
 1,0,0,1,  1,4 % diagonal edge
 0,1,1,0,  2,3 % diagonal edge
 1,0,1,1,  1,4 % diagonal edge, extra pixel set
 1,1,0,1,  1,4 % diagonal edge, extra pixel set
 1,1,1,0,  2,3 % diagonal edge, extra pixel set
 0,1,1,1,  2,3 % diagonal edge, extra pixel set
];

% 2x2 patches (matrix form)
P00 = A(1:end-1,1:end-1);
P10 = A(2:end,1:end-1);
P01 = A(1:end-1,2:end);
P11 = A(2:end,2:end);

% edge unique identifier using powers of 2
id = @(p00,p01,p10,p11) 1*p00 + 2*p10 + 4*p01 + 8*p11;
P = id(P00,P01,P10,P11); % vectorized pattern identification

% edges
e0 = []; % from (i,j)
e1 = []; % to (i,j)
for i = 1:size(patterns, 1) % small loop over the 10 patterns
  p = patterns(i, :);
  E = (P == id(p(1),p(2),p(3),p(4))); % pattern search, vectorized
  [c,r] = ind2sub(size(E), find(E));
  [c0,r0] = ind2sub([2,2], p(5));
  [c1,r1] = ind2sub([2,2], p(6));
  e0 = [e0; c+c0, r+r0];
  e1 = [e1; c+c1, r+r1];
end

此处将结果应用于您的图像(我使用GIMP进行捕获,调整大小和过滤,因此图像可能完全相同):

X = [e0(:,2) e1(:,2)];
Y = size(A,1) - [e0(:,1) e1(:,1)];
plot(X', Y', '.-')

YearWeek

我假设一旦你有上述的设置,获得一个描述多边形(或多边形)的有序序列边缘不是主要的问题。

答案 2 :(得分:1)

我首先处理您问题中的示例图像以创建逻辑蒙版(您已经有一个如何执行此操作的示例here)。

使用此掩码后,可以使用bwtraceboundary中的Image Processing Toolbox函数轻松生成所需的多边形。这将为您提供围绕遮罩区域周边的一组像素索引:

[r, c] = find(mask, 1);
coords = bwtraceboundary(mask, [r c], 'N');

我们可以像这样想象它:

imagesc(mask);
colormap([0.9 0.9 0.9; 0.6 0.6 0.6]);
axis equal
set(gca, 'XLim', [0.5 0.5+size(mask, 2)], 'YLim', [0.5 0.5+size(mask, 1)]);
hold on;
plot(coords(:, 2), coords(:, 1), 'r', 'LineWidth', 2);
plot(coords(1, 2), coords(1, 1), 'go', 'LineWidth', 2);

enter image description here

红线的坐标从绿色圆圈开始排序,顺时针绕着蒙面区域的周边像素移动。

如果您希望生成沿着区域的周边像素而不是周边像素 center 的边界轮廓,则可以使用{的解决方案{3}}到my answer。这将产生以下结果:

related question