OpenCV in C++: Distanz zwischen zwei HoughLineP



  • Ich habe bereits vieles zum Berechnen der Distanz zweier Punkte gefunden, ABER ich benötige die Distanz zweier Linien, die mit HooughLinesP erstellt wurden. All meine Linien sind vertical, sodass man aufgrund der Senkrechte eigentlich die Distanz berechnen sollte. Bloß wie kann ich auf die nächste Linie zugreifen und die Distanz berechnen? Mein Code soweit:

    void HoughTransf(Mat src) {
    Canny(src, dst, 150, 100, 3, false);
    cvtColor(dst, cdst, CV_GRAY2BGR);
    
    Sobel(cdst, dx, CV_32F, 1, 0);
    Sobel(cdst, dy, CV_32F, 1, 0);
    
    HoughLinesP(dst, lines, 1, CV_PI / 2, 50, 50, 10);
    
    for (size_t i = 0; i < lines.size(); i++) {
            Vec4i l = lines[i];
            Point pt1 = Point(l[0], l[1]);
            Point pt2 = Point(l[2], l[3]);
            double angle = atan2(pt2.y - pt1.y, pt2.x - pt1.x) * 180.0 / CV_PI;
            if (angle) {
                line(cdst, pt1, pt2, Scalar(0, 0, 255), 2, CV_AA);
            }
    }
    

    Danke schon mal!



  • Hi,

    wenn ich das richtig sehe, hast du deine Linien durch zwei Punkte definiert.

    Du kannst entweder mithilfe der Punkte eine 2d geraden Gleichung aufstellen und eine Senkrechte, schauen wo die Senkrechte die nächste Gerade schneidet und den Abstand zwischen Startpunkt der Senkrechten und Schnittpunkt berechnen.

    Oder Geradengleichung mit Vektoren aufstellen (Stützvektor und Richtungsvekor und so). Die Normale zum Richtungsvektor bestimmen, wieder den Schnittpunkt bestimmen und die Distanz zwischen Startpunkt und Schnittpunkt ist deine Distanz.

    Wie du auf deine Linien zugreifst hast du ja quasi schon implementiert. Du iterierst dadurch. Wenn du die Distanz zwischen allen möglichen Linien brauchst, wird du aber nicht drum herum kommen, noch eine zweite Schleife zu implementieren.

    Ich kann dir jetzt nicht sagen, ob OpenCV sowas von hause aus vorbereitet hat. Ich habe grade mal kurz in die Doku geschaut und muss sagen, die ist immer noch so unübersichtlich wie vor 5 Jahren 😉



  • @Schlangenmensch,
    also ich habe nun die Methode um Folgendes erweitert:

    void HoughTranf(Mat src) {
            //...
    
    	for (size_t i = 0; i < lines.size(); i++) {
            //...
       	mid = (pt1 + pt2)*.5;
    
    	///calculate distance between each line
    	Point dir = ((pt1.x - pt2.x), (pt1.y - pt2.y));
    	double mag = sqrt(dir.x * dir.x + dir.y * dir.y);
    	dir.x = dir.x / mag;
    	dir.y = dir.y / mag;
    
    	double length = 300;
    
    	pt3.x = pt2.x + dir.x * length;
    	pt3.y = pt2.y + dir.y * length;
    
    	line(cdst, mid, pt3, Scalar(0, 255, 0));
    
    	Point2f pti;
    	cout << mid << endl;
    	intersectionPoint(pt1.x, pt1.y, pt2.x, pt2.y, mid.x, mid.y, pt3.x, pt3.y, pti.x, pti.y);
    
    	}
    }}
    

    Dabei habe ich eine weitere Methode geschrieben, die schaut, ob ein Schnittpunkt vorhanden ist und idealerweise diesen mir ausgibt:

    /// Finds the intersection of two lines, or returns false.
    bool intersection(float p1x, float p1y, float p2x, float p2y,
    	float p3x, float p3y, float p4x, float p4y, float ix, float iy)
    {
    	float s1x, s1y, s2x, s2y;
    	s1x = p2x - p1x;     s1y = p2y - p1y;
    	s2x = p4x - p3x;     s2y = p4y - p3y;
    
    	float s, t;
    	s = (-s1y * (p1x - p3x) + s1x * (p1y - p3y)) / (-s2x * s1y + s1x * s2y);
    	t = (s2x * (p1y - p3y) - s2y * (p1x - p3x)) / (-s2x * s1y + s1x * s2y);
    
    	if (s >= 0 && s <= 1 && t >= 0 && t <= 1)
    	{
    		//collision detected
    		if (ix != NULL)
    			ix = p1x + (t * s1x);
    		if (iy != NULL)
    			iy = p1y + (t * s1y);
    		cout << ix << iy << endl;
    		return true;
    	}
    
    	//no collision
    	return false;
    }
    
    inline Point2d intersectionPoint(float p1x, float p1y, float p2x, float p2y,
    	float p3x, float p3y, float p4x, float p4y, float ix, float iy) {
    
    	return intersection(p1x, p1y, p2x, p2y, p3x, p3y, p4x, p4y, ix, iy);
    }
    

    Was jedoch nicht der Fall ist, ich kriege da nur Nuller raus.. Wäre um jede Hilfe dankbar! 🙂 😕



  • In Zeile 21 deines ersten Codeabschnittes erstellst du einen Punkt. Ich denke das Standardinitialisierung dafür (0, 0) sein dürfte. Die Werte übergibst du an intersection(....) als ix und iy.
    Und wenn diese != NULL sind (teste doch auf 0, NULL ist für Pointer gedacht und da nimmt man heutzutage nullptr) machst du was mit denen.
    Anschließend gibst du ix und iy aus.

    Du führst aber nie eine Operation auf denen aus, weil:

    ix != NULL

    für ix = 0

    immer als false ausgewertet wird.



  • Hallo @Schlangenmensch,

    erstmal vielen lieben Dank für die schnelle Antwort!
    Wenn ich jetzt allerdings pti initialisiere, kriege ich als "Schnittpunkt" immer den Mittelpunkt raus, was ja auch falsch ist.



  • Hi, du hast einmal s und t verwechselt. Du willst sicher nicht an beiden Stellen mit t multiplizieren.


Anmelden zum Antworten