J'ai deux listes de régions (regionsA
, regionsB
) définies avec des limites (coordonnées sur une image de taille 1024x1024) (.mat
fichier available here). Je veux calculer le chevauchement de chaque paire possible de régions entre ces deux listes. Et je m'attendais à ce que ce soit lent, mais pas si lent.Existe-t-il un moyen efficace de calculer le chevauchement entre plusieurs limites dans MATLAB?
Actuellement, je suis en utilisant le code ci-dessous et il prend 20 - 40 secondes pour 50x60 objets pour moi:
intersect_matrix = zeros(length(regionsA), length(regionsB)); % for storing true/false
intersect_matrix_iou = zeros(size(intersect_matrix_iou)); % for storing IoU (intersect over union)
for i = 1:length(regionsA)
for j = 1:length(regionsB)
% get coordinates
x1 = regionsA{i}(:,1);
y1 = regionsA{i}(:,2);
x2 = regionsB{j}(:,1);
y2 = regionsB{j}(:,2);
% move coordinates to origin (start at zero)
% this is not necessary but reduces the size of the mask created by poly2mask(), hence reduces consumed memory is
minX = min([x1(:); x2(:)]);
minY = min([y1(:); y2(:)]);
x1 = x1 - minX;
x2 = x2 - minX;
y1 = y1 - minY;
y2 = y2 - minY;
% create object masks in n x m window
m = max([x1(:); x2(:)]);
n = max([y1(:); y2(:)]);
objMask1 = poly2mask(y1,x1,m,n);
objMask2 = poly2mask(y2,x2,m,n);
save('regionsAB','regionsA', 'regionsB');
intersection = objMask1 & objMask2;
union = objMask1 | objMask2;
% store info
intersect_matrix(i,j) = (bwarea(intersection) ~= 0); % store true/false
if (bwarea(intersection) ~= 0)
intersect_matrix_iou(i,j) = bwarea(intersection)/bwarea(union);
else
intersect_matrix_iou(i,j) = 0; % avoid division by zero
end
end; clear j;
end; clear i;
Avant, je me suis approché d'abord le problème avec les opérations de polygone. C'était encore lent (12 sec) mais beaucoup mieux. Cependant, j'ai dû changer cela au code ci-dessus, puisque dans certains cas, j'ai obtenu NaN
valeurs, comme polybool
/polyarea
/... ont des problèmes avec les zones non connectées. L'utilisation de masques de pixels est robuste à ces problèmes. Cette remplace le contenu des boucles for:
% polygonal overlap
x1 = regionsA{i}(:,1);
y1 = regionsA{i}(:,2);
x2 = regionsB{j}(:,1);
y2 = regionsB{j}(:,2);
[x_i,y_i] = polybool('intersection',x1,y1,x2,y2);
[x_u,y_u] = polybool('union',x1,y1,x2,y2);
% store info
%intersect_matrix_geo{i, j} = [x_i,y_i];
intersect_matrix(i,j) = ~isempty([x_i,y_i]);
if ~isempty([x_i,y_i])
intersect_matrix_iou(i,j) = polyarea(x_i, y_i)/polyarea(x_u, y_u);
else
intersect_matrix_iou(i,j) = 0;
end
Question: Y at-il des moyens plus efficaces/plus rapides à mettre en œuvre ce?
sont ces région convexe? – user2999345
@ user2999345 malheureusement pas. Avant de travailler avec des objets convexes et là l'implémentation avec 'polybool' /' polyarea' fonctionnait bien, mais maintenant j'ai besoin de plus général. – Honeybear