Azzera filtri
Azzera filtri

Alphashape boundary detection not working as desired

21 visualizzazioni (ultimi 30 giorni)
Given a complex set of (x, y) data I would like to create a hull that is not convex but not fully conforming. I (think I) prefer alphashape over boundary as the former lets me select a specific number of pixels for the radius. My final goal is to create a mask from the outline of the resulting shape. However, my attempt has failed.
Any; suggestions on how to make this work as intended?
load XY.mat
shp = alphaShape(x, y, 100, 'HoleThreshold', 99999999999999);
[~, BXY] = boundaryFacets(shp);
figure
scatter(x, y, '.k')
axis ij equal off
axis([1, max(x) + 500, 1, max(y) + 500])
figure
plot(shp)
axis ij equal off
axis([1, max(x) + 500, 1, max(y) + 500])
% This looks good. I want everything green/black in the final mask.
figure
plot(BXY(:,1), BXY(:,2))
axis ij equal off
axis([1, max(x) + 500, 1, max(y) + 500])
% This seems to have the correct points, but there are lines both
% inside and outside of the desired shape and for it to work right it
% needs to be just the outside boarder of the above
figure
BW = poly2mask(BXY(:,1), BXY(:,2), max(x) + 500, max(y) + 500);
imshow(BW);
% Consequently, the mask looks all wrong.
% I want the mask to to be the entire area enclosed by the alphashape,
% with no holes, and just the area enclosed by the alphashape.
  1 Commento
James Akula
James Akula il 23 Giu 2023
Closer. But still need help...
load XY.mat
shp = alphaShape(x, y, 100, 'HoleThreshold', 99999999999999);
[~, BXY] = boundaryFacets(shp);
subplot(2, 2, 1)
scatter(x, y, '.k')
axis ij equal off
axis([1, max(x) + 500, 1, max(y) + 500])
subplot(2, 2, 2)
plot(shp)
axis ij equal off
axis([1, max(x) + 500, 1, max(y) + 500])
% This looks good
subplot(2, 2, 3)
plot(BXY(:,1), BXY(:,2))
axis ij equal off
axis([1, max(x) + 500, 1, max(y) + 500])
% This looks good, except there are crisscrossing lines and for it to work
% right it needs to be just the outside boarder
subplot(2, 2, 4)
[R, C] = find(ones([max(y) + 500, max(x)+500]));
tf = inShape(shp, C, R);
BW = false([max(y) + 500, max(x) + 500]);
BW(tf) = true;
imshow(BW)
% I was ablt to solve part of my problem--that is, the creation of a
% working mask. But I would still like the border plot (lower left) to
% work, too!

Accedi per commentare.

Risposta accettata

James Akula
James Akula il 27 Giu 2023
An answer that seems to work is to convert the alphashape into a triangulation and then use "boundaryshape."
load XY.mat
shp = alphaShape(x, y, 100, 'HoleThreshold', 99999999999999);
subplot(2, 2, 1)
scatter(x, y, '.k')
axis ij equal off
axis([1, max(x) + 500, 1, max(y) + 500])
subplot(2, 2, 2)
plot(shp)
axis ij equal off
axis([1, max(x) + 500, 1, max(y) + 500])
subplot(2, 2, 3)
[tri, P] = alphaTriangulation(shp);
TR = triangulation(tri, P);
polyshp = boundaryshape(TR);
plot(polyshp, 'EdgeColor', 'b', 'FaceColor', 'none')
axis ij equal off
axis([1, max(x) + 500, 1, max(y) + 500])
subplot(2, 2, 4)
ps_regions = regions(polyshp);
BW = false([max(y) + 500, max(x) + 500]);
for ii = 1:numel(ps_regions)
BW = BW | poly2mask(...
ps_regions(ii).Vertices(:,1), ps_regions(ii).Vertices(:,2), ...
max(y) + 500, max(x) + 500);
end
imshow(BW)

Più risposte (2)

Image Analyst
Image Analyst il 23 Giu 2023
Try imfill
BW = imfill(BW, 'holes');
  1 Commento
James Akula
James Akula il 23 Giu 2023
Thank you for this advice, but filling the holes isn't the solution, as that would do "too much." The "outline" of the blue plot does not match that of the alphashape, as lines crisscross both internally and externally.

Accedi per commentare.


Matt J
Matt J il 23 Giu 2023
Modificato: Matt J il 27 Giu 2023
Try bwlalphaclose() from this FEX submission,
load XY
s=5;
x=round(x/s)+10; y=round(y/s); %cut down to more manageable sizes
shp = alphaShape(x,y, 100/s, 'HoleThreshold', 99999999999999/s);
Warning: Duplicate data points have been detected and removed.
BW = accumarray([y,x], true, [max(y) + 500/s, max(x) + 500/s]);
BW=bwlalphaclose(BW,shp);
imshow(BW,[]); shg
hold on
scatter(x,y,'r.')
hold off
  3 Commenti
Matt J
Matt J il 27 Giu 2023
Did you run the example in Examples.mlx?
Matt J
Matt J il 27 Giu 2023
Modificato: Matt J il 27 Giu 2023
Here's what I get:
load XY
s=5;
x=round(x/s)+10; y=round(y/s); %cut down to more manageable sizes
shp = alphaShape(x,y, 100/s, 'HoleThreshold', 99999999999999/s);
Warning: Duplicate data points have been detected and removed.
BW = accumarray([y,x], true, [max(y) + 500/s, max(x) + 500/s]);
BW=bwlalphaclose(BW,shp);
imshow(BW,[]); shg
hold on
scatter(x,y,'r.')
hold off

Accedi per commentare.

Categorie

Scopri di più su Bounding Regions in Help Center e File Exchange

Prodotti


Release

R2022b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by