Comment puis-je afficher les contours d'une image à l'aide d'OpenCV Python?
J'ai suivi ce tutoriel officiel la documentation. J'ai exécuter leur code:
import numpy as np
import cv2
im = cv2.imread('test.jpg')
imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(imgray,127,255,0)
contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(img, contours, -1, (0,255,0), 3)
Qui est ok: pas d'erreurs, mais rien ne s'affiche.Je veux afficher le résultat qu'ils ont obtenu comme ils l'ont montré sur la photo:
Comment puis-je afficher le résultat de la countours comme ça (juste le résultat de gauche ou de droite) ?
Je sais que je doit utiliser cv2.imshow(something)
mais comment dans ce cas précis ?
Vous devez vous connecter pour publier un commentaire.
Tout d'abord, cet exemple vous montre seulement comment dessiner les contours d'un simple rapprochement. Gardez à l'esprit que même si vous dessinez les contours avec le simple rapprochement, il sera affiché comme ayant un contour bleu dessiné tout autour du rectangle comme on le voit dans l'image de gauche. Vous ne serez pas en mesure d'obtenir le droit à l'image, simplement en dessinant les contours sur l'image. En outre, vous voulez comparer deux ensembles de contours - la version simplifiée sur la droite avec sa représentation complète sur la gauche. Plus précisément, vous devez remplacer le
cv2.CHAIN_APPROX_SIMPLE
drapeau aveccv2.CHAIN_APPROX_NONE
pour obtenir la pleine représentation. Jetez un oeil à la OpenCV doc surfindContours
pour plus de détails: http://docs.opencv.org/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html#findcontoursEn outre, même si vous dessinez les contours sur l'image, il n'affiche pas les résultats. Vous aurez besoin de demander
cv2.imshow
pour que. Toutefois, en dessinant les contours eux-mêmes ne sera pas vous montrer la différence entre la pleine et la version simplifiée. Le tutoriel mentionne que vous avez besoin de dessiner des cercles à chaque point de contour, de sorte que nous ne devrions pas utilisercv2.drawContours
pour cette tâche. Ce que vous devez faire est d'extraire les points des contours et des dessiner des cercles à chaque point.En tant que tel, créer deux images comme:
Prendre note que le code ci-dessus est pour OpenCV 2. Pour OpenCV 3, il y a une sortie supplémentaire pour
cv2.findContours
c'est la première sortie que vous pouvez ignorer dans ce cas:Maintenant, nous allons marcher à travers le code lentement. La première partie du code est ce que vous avez fourni. Nous passons maintenant à ce qui est nouveau.
Étape #1 - Détecter les contours à l'aide des deux méthodes
À l'aide de la thresholded image, nous détecter des contours en utilisant à la fois complète et simple d'approximations. C'est stockée dans deux listes,
contours1
etcontours2
.Étape #2 - Remodeler pour les matrices 2D
Les contours eux-mêmes stockés en tant que liste des tableaux NumPy. Pour la simple image fournie, il ne devrait être qu'un contour détecté, afin d'extraire le premier élément de la liste, puis utilisez
numpy.reshape
pour remodeler les matrices 3D dans leurs formes 2D où chaque ligne est un(x, y)
point.Étape #3 - Dessiner les points comme des cercles à l'image de
La prochaine étape serait de prendre chaque
(x, y)
point de chaque ensemble de contours et de dessiner sur l'image. Nous faire deux copies de l'image de l'original en couleur à la forme, alors nous utilisonscv2.circle
et itérer sur chaque paire de(x, y)
points pour les deux ensembles de contours et de remplir deux images différentes, une pour chaque ensemble de contours.Maintenant, pour obtenir le chiffre que vous voyez ci-dessus, il ya deux façons que vous pouvez faire ceci:
matplotlib
, combiné avecsubplot
etimshow
de sorte que vous pouvez afficher deux images dans une fenêtre.Je vais vous montrer comment le faire en utilisant deux méthodes:
Méthode #1
Simplement empiler les deux images côte à côte, puis afficher l'image après:
Je les empiler horizontalement de sorte qu'ils sont réunis dans une même image, puis de montrer ce avec
cv2.imshow
.Méthode #2
Vous pouvez utiliser
matplotlib
:Cela doit afficher deux images distinctes subfigures à l'intérieur d'un chiffre global de la fenêtre. Si vous jetez un oeil à la façon dont je vais appeler
imshow
ici, vous verrez que j'ai fait de permuter les canaux RVB parce que OpenCV lit en images dans BGR format. Si vous voulez afficher des images avecmatplotlib
, vous aurez besoin pour inverser les canaux que les images sont au format RGB (comme ils devraient l'être).À répondre à votre question dans votre commentaire, vous prendriez lequel le contour de la structure que vous souhaitez (
contours1
oucontours2
) et de rechercher les points des contours.contours
est une liste de tous les contours possibles, et au sein de chaque contour est une matrice 3D qui est en forme dans unN x 1 x 2
format.N
serait le nombre total de points qui représentent le contour. Je vais supprimer le singleton deuxième dimension de sorte que nous pouvons obtenir ceN x 2
de la matrice. Aussi, nous allons utiliser la pleine représentation des contours pour l'instant:Je vais supposer que votre image a seulement un objet, d'où ma indexation dans
contours1
avec l'index 0. Je démêler la matrice de sorte qu'il devient un vecteur ligne, puis de les remodeler la matrice de sorte qu'il devientN x 2
. Ensuite, on peut trouver le minimum de points par:np.argmin
trouve le emplacement de la plus petite valeur dans un tableau que vous fournissez. Dans ce cas, nous voulons opèrent le long de lax
coordonner, ou les colonnes. Une fois que nous trouvons cet endroit, nous avons simplement indice dans notre contour 2D point de tableau et d'en extraire le point de contour.Y
axe va du plus petit au plus grand?x
valeur , parx
je veux dire lax
dep(x,y)
oùp
est le pixel en question.Ajouter ces 2 lignes à la fin:
Aussi, soyez conscient que vous avez
img
au lieu deim
dans votre dernière ligne.tl;dr
réponse si!Vous devez ajouter cv2.imshow("Titre", img) à la fin de votre code. Il devrait ressembler à ceci: