bw = poly2mask (x, y, m, n) code> 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. p>
poly2mask code> 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. p> blockQuote>
problème: strong> Étant donné un tel masque binaire BW code> d'un quadrilatère convexe, quel serait le moyen le plus efficace de déterminer les quatre coins? P>
E.g., P>
p>
meilleure solution jusqu'à présent: strong> Utilisez bord code> 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. p>
BTW,
Convuhull code> ne renvoie pas toujours 4 points (peut-être que quelqu'un peut suggérer
qhull code> options pour empêcher cela): il retourne quelques points sur les bords. p>
EDIT: strong> 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 θ fort> et moyen des "coins" autour d'un coin réel, mais le problème principal est l'utilisation de
ordre (1:10) code>. p>
est
10 code> suffisamment pour tenir compte de tous les coins ou cela exclure un "coin" dans un vrai coin? P>
5 Réponses :
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. P>
Utiliser 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. P> bwtraceboundary () code> à 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 CODE> TH Point le long de la limite du
Delta code> 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! P>
Je viens de réaliser que vous avez déjà une image binaire BW. Par conséquent, vous pouvez passer directement à la partie d'obtenir les limites à partir de l'appel à BWBoundiaires b>
+1 - Pour la signature des limites. Mais il y a des préoccupations que j'ai détaillées dans le poste édité.
@Amro: Merci beaucoup pour l'idée de signature des limites, mais j'ai décidé de creuser mon ancienne mise en œuvre du détecteur de coin Harris et de l'utiliser.
Vous pourriez si une technique d'approximation de la ligne pour résoudre le problème de duplication d'angle. OpenCV fait-il que dans FindContours fonctionne à l'aide du drapeau CV_CHAIN_APRROX_SIMPLE. Quant à Matlab, je n'ai pas trouvé de manière intégrée de le faire, mais j'ai trouvé une implémentation de l'algorithme de simplification de Douglas-Péucker sur Exchange de fichiers MATHWORKS.COM/MATLABENTRAL/FILEEXCHANGE/.../a>
OpenCV EnvironPolyDP implémente également l'algorithme Douglas-Petucker Docs.OPENCV. org / modules / imgProc / doc / ...
@Osaad: Merci pour la référence. En réalité, il n'y a pas si longtemps, il y avait un problème similaire sur Steve Eddins Blog qui a été transformé en un Cody Challenge , à propos de Comment simplifier la sortie de bwboundiaires code> en cas de polygones .. Je pense que la technique de simplification de la ligne a été mentionnée :)
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*');
joli! comme une note, j'aime mettre # code> après
% code> dans matlab comments, de sorte qu'il devient correct de la couleur
Merci! Toute solution avec l'utilisation de ' code>?
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); code> Vous obtiendrez des angles en double (même lorsque vous avez essayé de régler les autres paramètres) et devrez augmenter
ncorners code> 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 i>, 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 i> le polygone en masquant les métriques d'angle avec le polygone d'origine.
Si vous avez le Boîte à outils de traitement d'image , il existe une fonction appelée Cornésine code>
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 ... p>
La première étape consiste à charger les données: p> Suivant , calculez la métrique d'angle en utilisant Les régions marquées sont ensuite dilatées (en utilisant 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 et nous pouvons maintenant obtenir Les coordonnées de pixels des coins à l'aide de et voici un test avec une région en forme de diamant: p> Cornésine code>
. 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 em> le polygone (c'est-à-dire d'essayer de trouver les pixels d'angle du polygone). imrégionalmax code>
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 CODE> A >:: p>
imdilate code>
) avec un élément de structuration en forme de disque (créé à l'aide de strel code>
): p> régionProps code>
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: p> Trouver CODE> A > et
ismember code>
: P >
+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.
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é. p> p>