使用 Matlab 在具有多个自交点的多边形内查找点
Find points within polygon with multiple self intersections with Matlab
我有一个与自身相交多次的多边形。我尝试从这个多边形创建一个掩码,即找到多边形内的所有 points/pixels 位置。我为此使用了 Matlab 函数 poly2mask。但是,由于多次自交,这是我获得的结果:
Resulting mask from poly2mask for multi-self-intersecting polygon
因此,由于交叉点,某些区域仍未被屏蔽。我认为 Matlab 将其视为某种内含物。 poly2mask 的 Matlab 帮助没有提及任何相关内容。有谁知道如何将这些区域也包含在蒙版中?
您应该首先计算多边形的边界并使用它来创建掩码。
k = boundary(x, y, 0.99); % 1 == tightest single-region boundary
BW = poly2mask(x(k), y(k), m, n)
使用收缩系数 0.99 而不是 1 可以避免底切,但尖锐的非凸角仍然无法正确拟合。
你可以使用 inpolygon
:
bw1 = poly2mask(x,y,1000,1000);
subplot(131)
imshow(bw1)
hold on
plot(x([1:end 1]),y([1:end 1]),'g','LineWidth',2)
title('using poly2mask')
[xq,yq] = meshgrid(1:1000);
[IN,ON] = inpolygon(xq,yq,x,y);
bw2 = IN | ON;
subplot(132)
imshow(bw2)
hold on
plot(x([1:end 1]),y([1:end 1]),'g','LineWidth',2)
title('using inpolygon')
% boundary - seggested by another answer
k = boundary(x, y, 1); % 1 == tightest single-region boundary
bw3 = poly2mask(x(k), y(k), 1000, 1000);
subplot(133)
imshow(bw3)
hold on
plot(x([1:end 1]),y([1:end 1]),'g','LineWidth',2)
title('using boundary')
更新 - 我更新了我的答案以包含 boundary
- 在我的情况下似乎效果不佳。
我结合小 erosion/dilation 步和 imfill
获得了很好的结果,如下所示:
data = load('polygon_edge.mat');
x = data.polygon_edge(:, 1);
y = data.polygon_edge(:, 2);
bw1 = poly2mask(x,y,ceil(max(y)),ceil(max(x)));
se = strel('sphere',1);
bw2 = imerode(imdilate(bw1,se), se);
bw3 = imfill(bw2, 'holes');
figure
imshow(bw3)
hold on
plot(x(:, 1),y(:, 1),'g','LineWidth',2)
需要小的腐蚀和膨胀步骤来确保即使在多边形仅通过一个点连接的地方也连接所有区域,否则 imfill
可能会看到一些不存在的孔。
我有一个与自身相交多次的多边形。我尝试从这个多边形创建一个掩码,即找到多边形内的所有 points/pixels 位置。我为此使用了 Matlab 函数 poly2mask。但是,由于多次自交,这是我获得的结果:
Resulting mask from poly2mask for multi-self-intersecting polygon
因此,由于交叉点,某些区域仍未被屏蔽。我认为 Matlab 将其视为某种内含物。 poly2mask 的 Matlab 帮助没有提及任何相关内容。有谁知道如何将这些区域也包含在蒙版中?
您应该首先计算多边形的边界并使用它来创建掩码。
k = boundary(x, y, 0.99); % 1 == tightest single-region boundary
BW = poly2mask(x(k), y(k), m, n)
使用收缩系数 0.99 而不是 1 可以避免底切,但尖锐的非凸角仍然无法正确拟合。
你可以使用 inpolygon
:
bw1 = poly2mask(x,y,1000,1000);
subplot(131)
imshow(bw1)
hold on
plot(x([1:end 1]),y([1:end 1]),'g','LineWidth',2)
title('using poly2mask')
[xq,yq] = meshgrid(1:1000);
[IN,ON] = inpolygon(xq,yq,x,y);
bw2 = IN | ON;
subplot(132)
imshow(bw2)
hold on
plot(x([1:end 1]),y([1:end 1]),'g','LineWidth',2)
title('using inpolygon')
% boundary - seggested by another answer
k = boundary(x, y, 1); % 1 == tightest single-region boundary
bw3 = poly2mask(x(k), y(k), 1000, 1000);
subplot(133)
imshow(bw3)
hold on
plot(x([1:end 1]),y([1:end 1]),'g','LineWidth',2)
title('using boundary')
更新 - 我更新了我的答案以包含 boundary
- 在我的情况下似乎效果不佳。
我结合小 erosion/dilation 步和 imfill
获得了很好的结果,如下所示:
data = load('polygon_edge.mat');
x = data.polygon_edge(:, 1);
y = data.polygon_edge(:, 2);
bw1 = poly2mask(x,y,ceil(max(y)),ceil(max(x)));
se = strel('sphere',1);
bw2 = imerode(imdilate(bw1,se), se);
bw3 = imfill(bw2, 'holes');
figure
imshow(bw3)
hold on
plot(x(:, 1),y(:, 1),'g','LineWidth',2)
需要小的腐蚀和膨胀步骤来确保即使在多边形仅通过一个点连接的地方也连接所有区域,否则 imfill
可能会看到一些不存在的孔。