How to convert 2D triangulation to binary image?

3 visualizaciones (últimos 30 días)
Geert
Geert el 21 de Ag. de 2013
Comentada: T. Dunker el 6 de Jul. de 2022
Does anyone know of an easy way to convert a 2D triangulation to a binary image, which represents the inside?
Let my clarify my question with a picture: http://i41.tinypic.com/2gvvvnl.jpg The goal is to go from left to right...
My triangulation is given its Points and the ConnectivityList (i.e., it was created with the matlab function "triangulation").
It is important that no holes get filled and all features are preserved.
BEST ANSWER SO FAR:
% Make some data
pts = rand(50,2);
DT = delaunayTriangulation(pts);
% Find a central triangle to remove
[~,holeTrias] = min(sum(abs(DT.incenter - 0.5),2));
holeTrias = [holeTrias DT.neighbors(holeTrias)];
triasMask = ~ismember(1:DT.size(1), holeTrias);
T = triangulation(DT.ConnectivityList(triasMask,:), DT.Points);
% Define query points
X = 0:0.05:1;
Y = 0:0.05:1;
[xMat,yMat] = meshgrid(X,Y);
IN = false(size(xMat));
for t = 1:size(T,1)
vertsXY = T.Points(T.ConnectivityList(t,:),:);
IN = IN | inpolygon(xMat,yMat, vertsXY(:,1), vertsXY(:,2));
end
% Show the result
figure
patch('faces',T.ConnectivityList,'vertices',T.Points,'FaceColor','g')
hold on
plot(xMat(IN),yMat(IN),'b.',xMat(~IN),yMat(~IN),'r.')

Respuesta aceptada

Sven
Sven el 21 de Ag. de 2013
Editada: Sven el 21 de Ag. de 2013
Hi Geert,
Here's something that does what you want. It's not optimised for speed as it simply iterates naively through triangles, but it's at least correct.
% Make some data
pts = rand(50,2);
DT = delaunayTriangulation(pts);
% Find a central triangle to remove
[~,holeTrias] = min(sum(abs(DT.incenter - 0.5),2));
holeTrias = [holeTrias DT.neighbors(holeTrias)];
triasMask = ~ismember(1:DT.size(1), holeTrias);
T = triangulation(DT.ConnectivityList(triasMask,:), DT.Points);
% Define query points
X = 0:0.05:1;
Y = 0:0.05:1;
[xMat,yMat] = meshgrid(X,Y);
% Query each point
IN = false(size(xMat));
for i = 1:numel(IN)
for t = 1:size(T,1)
vertsXY = T.Points(T.ConnectivityList(t,:),:);
if inpolygon(xMat(i),yMat(i), vertsXY(:,1), vertsXY(:,2))
IN(i) = true;
break;
end
end
end
% Show the result
figure
patch('faces',T.ConnectivityList,'vertices',T.Points,'FaceColor','g')
hold on
plot(xMat(IN),yMat(IN),'b.',xMat(~IN),yMat(~IN),'r.')
How does that work for you?
  5 comentarios
Geert
Geert el 22 de Ag. de 2013
Thanks you guys, nice work!
I was able to improve the speed even more (by a factor 10), by applying some vectorization:
% Query each point
IN = false(size(xMat));
for t = 1:size(T,1)
vertsXY = T.Points(T.ConnectivityList(t,:),:);
IN = IN | inpolygon(xMat,yMat, vertsXY(:,1), vertsXY(:,2));
end
Speeds can be compared with the following code:
% Make some data
pts = rand(50,2);
DT = delaunayTriangulation(pts);
% Find a central triangle to remove
[~,holeTrias] = min(sum(abs(DT.incenter - 0.5),2));
holeTrias = [holeTrias DT.neighbors(holeTrias)];
triasMask = ~ismember(1:DT.size(1), holeTrias);
T = triangulation(DT.ConnectivityList(triasMask,:), DT.Points);
% Define query points
X = 0:0.05:1;
Y = 0:0.05:1;
[xMat,yMat] = meshgrid(X,Y);
tic
% Query each point
IN1 = false(size(xMat));
k = convhull(T.Points);
for i = find(inpolygon(xMat,yMat, T.Points(k,1), T.Points(k,2)))'
for t = 1:size(T,1)
vertsXY = T.Points(T.ConnectivityList(t,:),:);
if inpolygon(xMat(i),yMat(i), vertsXY(:,1), vertsXY(:,2))
IN1(i) = true;
break;
end
end
end
disp(['First method elapsed time = ', num2str(toc)])
tic
IN2 = false(size(xMat));
for t = 1:size(T,1)
vertsXY = T.Points(T.ConnectivityList(t,:),:);
IN2 = IN2 | inpolygon(xMat,yMat, vertsXY(:,1), vertsXY(:,2));
end
disp(['Second method elapsed time = ', num2str(toc)])
% Show the result
figure
subplot(1,2,1)
patch('faces',T.ConnectivityList,'vertices',T.Points,'FaceColor','g')
hold on
plot(xMat(IN1),yMat(IN1),'b.',xMat(~IN1),yMat(~IN1),'r.')
title('first result: IN1')
subplot(1,2,2)
patch('faces',T.ConnectivityList,'vertices',T.Points,'FaceColor','g')
hold on
plot(xMat(IN2),yMat(IN2),'b.',xMat(~IN2),yMat(~IN2),'r.')
title('second result: IN2')
Once again: many thanks!
T. Dunker
T. Dunker el 6 de Jul. de 2022
with R2018b and later this simplifies to
%% Make some data
pts = rand(50,2);
DT = delaunayTriangulation(pts);
% Find a central triangle to remove
[~,holeTrias] = min(sum(abs(DT.incenter - 0.5),2));
holeTrias = [holeTrias DT.neighbors(holeTrias)];
triasMask = ~ismember(1:DT.size(1), holeTrias);
T = triangulation(DT.ConnectivityList(triasMask,:), DT.Points);
% Define query points
X = 0:0.02:1;
Y = 0:0.02:1;
%% use polyshape
tic
[xMat,yMat] = meshgrid(X,Y);
bp = boundaryshape(T);
IN = reshape(isinterior(bp, xMat(:), yMat(:)), size(xMat));
toc
Elapsed time is 0.178962 seconds.
%%
colormap(gray(2))
imagesc(X, Y, IN)
hold on;
patch('faces', T.ConnectivityList, 'vertices', T.Points, ...
'FaceColor', 'r', 'FaceAlpha', .2)
hold off;
axis equal;
axis tight;

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Más información sobre Triangulation Representation en Help Center y File Exchange.

Community Treasure Hunt

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

Start Hunting!

Translated by