8
votes

Trouver les coins d'un polygone représenté par un masque de région

bw = poly2mask (x, y, m, n) calcule un Masque de la région binaire d'intérêt (ROI), BW, d'un polygone ROI, représenté par les vecteurs x et y. La taille de bw est m-by-n.

poly2mask définit les pixels en BW qui sont à l'intérieur du polygone (x, y) à 1 et définit des pixels à l'extérieur du polygone pour 0.

problème: Étant donné un tel masque binaire BW d'un quadrilatère convexe, quel serait le moyen le plus efficace de déterminer les quatre coins?

E.g.,

exemple

meilleure solution jusqu'à présent: Utilisez bord pour trouver les lignes de liaison, la transformation de Hough pour trouver les 4 lignes de l'image de bord, puis recherchez les points d'intersection de ces 4 lignes ou utilisez un détecteur d'angle sur l'image de bord. Semble compliqué, et je ne peux pas m'empêcher de sentir qu'il y a une solution plus simple là-bas.

BTW, Convuhull ne renvoie pas toujours 4 points (peut-être que quelqu'un peut suggérer qhull options pour empêcher cela): il retourne quelques points sur les bords.

EDIT: Réponse d'Amro semble assez élégant et efficace. Mais il pourrait y avoir plusieurs "coins" dans chaque coin véritable depuis que les sommets ne sont pas uniques. Je pourrais les reposer en fonction de θ et moyen des "coins" autour d'un coin réel, mais le problème principal est l'utilisation de ordre (1:10) .

est 10 suffisamment pour tenir compte de tous les coins ou cela exclure un "coin" dans un vrai coin?


0 commentaires

5 Réponses :


4
votes

J'aime résoudre ce problème en travaillant avec une frontière, car il réduit cela à partir d'un problème 2D à un problème de 1D.

Utiliser bwtraceboundary () à partir de la boîte à outils de traitement d'image pour extraire une liste de points sur la limite. Puis convertissez la limite en une série de vecteurs tangents (il y a un certain nombre de façons de le faire, une manière de subrailler la I TH Point le long de la limite du Delta thip.) Une fois que vous avez une liste de vecteurs, prenez le produit DOT des vecteurs adjacents. Les quatre points avec les plus petits produits DOT sont vos coins!

Si vous voulez que votre algorithme fonctionne sur des polygones avec un nombre abri de sommets, puis recherchez simplement des produits DOT qui sont un certain nombre d'écarts types sous le produit MEDIAN DOT.


0 commentaires

12
votes


2
votes

J'ai décidé d'utiliser un Détecteur de coin Harris (voici a Description plus formelle ) pour obtenir les coins. Cela peut être mis en œuvre comme suit:

%% Constants
Window = 3;
Sigma = 2;
K = 0.05;
nCorners = 4;

%% Derivative masks
dx = [-1 0 1; -1 0 1; -1 0 1];
dy = dx';   %SO code color fix '

%% Find the image gradient
% Mask is the binary image of the quadrilateral
Ix = conv2(double(Mask),dx,'same');   
Iy = conv2(double(Mask),dy,'same');

%% Use a gaussian windowing function and compute the rest
Gaussian = fspecial('gaussian',Window,Sigma);
Ix2 = conv2(Ix.^2,  Gaussian, 'same');  
Iy2 = conv2(Iy.^2,  Gaussian, 'same');
Ixy = conv2(Ix.*Iy, Gaussian, 'same');    

%% Find the corners
CornerStrength = (Ix2.*Iy2 - Ixy.^2) - K*(Ix2 + Iy2).^2;
[val ind] = sort(CornerStrength(:),'descend');    
[Ci Cj] = ind2sub(size(CornerStrength),ind(1:nCorners));

%% Display
imshow(Mask,[]);
hold on;
plot(Cj,Ci,'r*');


6 commentaires

joli! comme une note, j'aime mettre # après % dans matlab comments, de sorte qu'il devient correct de la couleur


Merci! Toute solution avec l'utilisation de '?


Nan. Écoutez que je testais votre approche, et il semble que ce n'est pas parfait non plus (ce qui est toujours le cas dans la vision de l'ordinateur!). Essayez le masque suivant avec votre code ci-dessus: x = [16 282 276 30 16]; y = [14 29 200 225 14]; BW = Poly2mask (x, Y, 246 300); Vous obtiendrez des angles en double (même lorsque vous avez essayé de régler les autres paramètres) et devrez augmenter ncorners aussi ..


Vous êtes complètement à droite - on dirait que la clustering est requise pour certains polygones.


Je ne veux pas pousser mon idée trop fortement, mais je pense que la méthode de signature pourrait être perfectionnée pour la plupart quadrilatère si nous localisons les 4 pics exacts thêta , qui sont après tout visible dans la parcelle . Choisir les n-points les plus élevés n'a peut-être pas été le meilleur moyen, mais peut-être que quelqu'un peut améliorer cette partie ..


J'ai trouvé un moyen de prendre en compte plusieurs points à Corners en ajoutant du bruit aux valeurs métriques maximales d'angle (j'ai mis à jour ma réponse à l'inclure). J'ai également pu m'assurer que ma mise en œuvre choisirait toujours un point de coin à partir des pixels dans le polygone en masquant les métriques d'angle avec le polygone d'origine.



8
votes

Si vous avez le Boîte à outils de traitement d'image , il existe une fonction appelée Cornésine qui peut implémenter un détecteur de coin Harris ou shi et la méthode minimale de la proprevalue minimale de Tomasi. Cette fonction est présente depuis la version 6.2 de la boîte à outils de traitement d'image (version MATLAB R2008B).

Utilisation de cette fonction, j'ai proposé une approche légèrement différente des autres réponses. La solution ci-dessous est basée sur l'idée qu'une zone circulaire centrée sur chaque point de coin "vrai" se chevauchera le polygone par une quantité inférieure à une zone circulaire centrée sur un coin de coin erroné qui est effectivement sur le bord. Cette solution peut également gérer des cas où plusieurs points sont détectés au même coin ...

La première étape consiste à charger les données: xxx

Suivant , calculez la métrique d'angle en utilisant Cornésine . Notez que je masque la métrique de coin par le polygone d'origine, de sorte que nous recherchons des points d'angle à l'intérieur le polygone (c'est-à-dire d'essayer de trouver les pixels d'angle du polygone). imrégionalmax est ensuite utilisé pour trouver le Maxima locale. Étant donné que vous pouvez avoir des grappes de plus de 1 pixel avec la même métrique de coin, je ajoute ensuite du bruit à la maxima et recomgrez-vous de sorte que je n'ai que 1 pixel dans chaque région maximale. Chaque région maximale est ensuite étiquetée à l'aide de BWLABEL :: xxx

Les régions marquées sont ensuite dilatées (en utilisant imdilate ) avec un élément de structuration en forme de disque (créé à l'aide de strel ): xxx

maintenant que les régions d'angle marquées ont été dilaté, ils chevauchent partiellement le polygone d'origine. Les régions sur un bord du polygone auront environ 50% de chevauchements, tandis que les régions situées sur un coin auront environ 25% de chevauchements. La fonction régionProps peut être utilisé pour Trouvez les zones de chevauchement pour chaque région marquée et les 4 régions dont la moindre quantité de chevauchement peut ainsi être considérée comme les vrais coins: xxx

et nous pouvons maintenant obtenir Les coordonnées de pixels des coins à l'aide de Trouver et ismember : xxx

 Entrez la description de l'image ici

et voici un test avec une région en forme de diamant:

 Entrer Imprimer descriptions ici


2 commentaires

+1 Je ne connaissais pas celui-ci. En examinant sa mise en œuvre, c'est semblable à @ Jacob de cependant plus optimisé.


J'utilise R2009A, alors je suppose que c'est un ajout relativement nouveau.



1
votes

Voici un exemple en utilisant Ruby et Hornetseye . Fondamentalement, le programme crée un histogramme de l'orientation gradient de Sobel quantifiée pour trouver des orientations dominantes. Si quatre orientations dominantes se trouvent, des lignes sont montées et les intersections entre les lignes voisines sont supposées être les coins du rectangle projeté. xxx

 image avec position estimée des coins


0 commentaires