trouver l'intersection de deux lignes tracées à l'aide de houghlines opencv
Comment puis-je obtenir les points d'intersection des lignes vers le bas à l'aide d'opencv Hough lignes de l'algorithme?
Voici mon code:
import cv2
import numpy as np
import imutils
im = cv2.imread('../data/test1.jpg')
gray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray, 60, 150, apertureSize=3)
img = im.copy()
lines = cv2.HoughLines(edges,1,np.pi/180,200)
for line in lines:
for rho,theta in line:
a = np.cos(theta)
b = np.sin(theta)
x0 = a*rho
y0 = b*rho
x1 = int(x0 + 3000*(-b))
y1 = int(y0 + 3000*(a))
x2 = int(x0 - 3000*(-b))
y2 = int(y0 - 3000*(a))
cv2.line(img,(x1,y1),(x2,y2),(0,255,0),10)
cv2.imshow('houghlines',imutils.resize(img, height=650))
cv2.waitKey(0)
cv2.destroyAllWindows()
De sortie:
Je veux obtenir tous les points d'intersection.
Vous devez vous connecter pour publier un commentaire.
Vous ne voulez pas d'obtenir les intersections des lignes parallèles; seules les intersections des lignes verticales avec ceux des lignes horizontales. Aussi, puisque vous avez la ligne verticale, calcul de la pente sera susceptible d'entraîner l'explosion ou inf pentes, de sorte que vous ne devriez pas utiliser la
y = mx+b
équations. Vous devez faire deux choses:Avec
HoughLines
, vous avez déjà le résultat commerho, theta
de sorte que vous pouvez facilement segment en deux classes d'angle avectheta
. Vous pouvez l'utiliser pour, par exemple,cv2.kmeans()
avectheta
que vos données que vous voulez partager.Alors, pour calculer les intersections, vous pouvez utiliser la formule pour calculer les intersections de deux points de chaque ligne. Vous êtes déjà calculer de deux points de chaque ligne:
(x1, y1), (x2, y2)
de sorte que vous pouvez simplement stocker et de les utiliser. Edit: en Fait, comme on le voit ci-dessous dans mon code, il y a une formule que vous pouvez utiliser pour calculer les intersections de lignes avec lerho, theta
forme queHoughLines
donne.J'ai répondu à une question similaire avant avec du code python que vous pouvez vérifier; note ce a l'aide de
HoughLinesP
qui vous donne seulement des segments de ligne.Exemple de Code
Vous ne fournissez pas votre image d'origine donc je ne peux pas l'utiliser. Au lieu de cela, je vais utiliser la norme de sudoku image utilisée par OpenCV sur leur Hough transformer et seuillage tutoriels:
Tout d'abord, nous allons viens de lire cette image et de binariser l'aide de seuillage adaptatif comme ce qui est utilisé dans ce tutoriel OpenCV:
Alors nous trouverons la Hough lignes avec
cv2.HoughLines()
:Maintenant, si nous voulons trouver les intersections, vraiment nous voulons trouver les intersections seulement des lignes perpendiculaires. Nous ne voulons pas que les intersections de la plupart des lignes parallèles. Nous avons donc besoin de segmenter nos lignes. Dans cet exemple particulier, vous peut facilement vérifier que la ligne est horizontale ou verticale basée sur un test simple; les lignes verticales ont un
theta
de autour de 0 ou 180; les lignes horizontales ont unetheta
autour de 90. Toutefois, si vous voulez un segment sur la base d'un nombre arbitraire d'angles, automatiquement, sans que vous la définition de ces angles, je pense que la meilleure idée est d'utilisercv2.kmeans()
.Il est une chose la plus délicate à obtenir le droit.
HoughLines
renvoie des lignes dansrho, theta
forme (Hesse forme normale), et letheta
retournée est entre 0 et 180 degrés, et les lignes autour de 180 et 0 degrés sont similaires (ils sont tous les deux proches de l'horizontale des lignes), nous avons donc besoin d'un moyen d'obtenir cette périodicité danskmeans
.Si nous tracé de l'angle sur le cercle unité, mais de multiplier l'angle par deux, puis les angles à l'origine autour de 180 degrés deviendra près de 360 degrés et devra donc
x, y
valeurs sur le cercle unité près le même pour les angles à 0. Donc, nous pouvons obtenir quelques belles "proximité" ici, en traçant des2*angle
avec les coordonnées sur le cercle unité. Ensuite, nous pouvons exécutercv2.kmeans()
sur ces points, et le segment automatiquement avec toutefois de nombreuses pièces que nous voulons.Nous allons donc créer une fonction pour faire la segmentation:
Maintenant pour l'utiliser, il suffit de l'appeler:
Ce qui est bien c'est là que l'on peut spécifier un nombre arbitraire de groupes en spécifiant l'argument optionnel
k
(par défaut,k = 2
donc je n'ai pas le spécifier ici).Si nous avons tracé les lignes de chaque groupe avec une couleur différente:
Et maintenant tout ce qui reste est de trouver les points d'intersection de chaque ligne dans le premier groupe, à l'intersection de chaque ligne dans le deuxième groupe. Depuis les lignes sont dans la Hesse forme normale, il y a une belle algèbre linéaire formule pour le calcul de l'intersection des lignes à partir de ce formulaire. Voir ici. Nous allons créer deux fonctions ici; celle qui la trouve à l'intersection de deux lignes, et une fonction qui parcourt toutes les lignes dans les groupes et l'utilise de plus simple fonction de deux lignes:
Ensuite pour l'utiliser, il est tout simplement:
Et le traçage de toutes les intersections, nous obtenons:
Comme mentionné ci-dessus, ce code peut segment des lignes en plus de deux groupes d'angles ainsi. Ici, il est en cours d'exécution sur un dessinés à la main en triangle, et de calculer les points d'intersection de la détection des lignes avec
k=3
:Si vous avez déjà le segment de ligne, juste se substituer à eux dans une équation de droite ...
u peut être trouvé en utilisant l'une des options suivantes ...
Tout d'abord, vous avez besoin pour améliorer la sortie de la transformation de Hough (j'ai l'habitude de le faire par k-means clustering basé sur certains critères, par exemple, de la pente et/ou des centroïdes des segments). Dans votre problème, par exemple, il semble que la pente de toutes les lignes est généralement dans le voisinage de 0, 180, 90 degrés, de sorte que vous pouvez faire de clustering sur cette base.
Ensuite, il ya deux façons que vous pouvez obtenir des points d'intersection(qui est techniquement le même):
P. S. bien faite est un wrapper autour d'un puissant C++ de la géométrie de la bibliothèque, mais SymPy est pur Python. Vous pouvez prendre cela en considération dans le cas où votre application est critique.