Verständnisfragen in Richtung Konturen eines Bilds erkennen, Eckpunkte finden/zurückgeben.



  • Hallo liebe Community,
    ich habe eigentlich so gut wie keine Erfahrung in Bildverarbeitung, deswegen mache ich im Moment an der Uni ein kleines Projekt( wobei es für mich eher als riesiges und komplexes Projekt erscheint 😞 ).

    Es geht darum die Eckkoordinaten eines Rechteckigen Objektes zu übermitteln. Dafür habe ich erstmal die Konturen erkennnen wollen.
    Ich habe bis jetzt die Konturen erkennen können und habe die in Schwarz gemalt, aber die Linien sind nicht so ganz gerade(Ursache ist die Kamera nehme ich an!). Deswegen würde ich erstmal gerade Linien bzw. ein Rechteck drauf malen möchte.

    Zu meinen Fragen:
    1- liege ich erstmal richtig, wenn ich auch noch Rechteck zeichnen möchte? weil, ich denke mir, so wie meine Programmierung ist, erkennt mein Programm keine Linie bzw. Rechteck sondern nur nacheinander stehende Pixel.

    2- ich habe mir den Befehl Boundingrect ( ist es überhaupt der richtige Befehl dafür?) angeschaut und ich verstehe ehrlich gesagt nicht, wie ich ihn benutzen kann. Vor allen und ich glaube dass, das mein Problem ist: Wie man die Vektordeklaration/Initialisierung macht und wie sie zu verstehen sind.

    3-ich will dann an Ende die Eckpunkten davon haben. Wie gehe ich da vor:
    -Befehl (Hough Transformation benutzen?) und am Bestens würde ich gern verstehen , was dann im Programm Passiert.

    Ich weiß ich habe viele bestimmt dumme Fragen und kriege vielleicht keine detaillierte Antwort, aber wenn es ein Link sein sollte, wo es auch erklärt ist wäre super und am bestens auf Deutsch.. Deutsch ist zwar nicht meine Muttersprache,doch ist Englisch wirklich schlimm bei mir 😞 ( ich weißß..ich mache noch Kurse in den Ferien 🕶 ).
    Hier ist einfach mal mein Code , was ich bis jetzt gemacht habe.

    Ich habe das Bild in einem anderem Forum posten können. Ich hoffe, ihr werdet es öffnen können: http://www.developpez.net/forums/d1531838/c-cpp/bibliotheques/opencv/optimiser-rectangle-detecte-opencv-eliminer-autres-objets-detectes/

    Das obere bild ist mit cvcanny gemacht und das untere mit cvfindcontours. Ich will mit cvfindcontours weiterarbeiten.

    Danke im Voraus.

    #include<cv.h>
    #include<highgui.h>
    #include<iostream>
    #include "opencv2/imgproc/imgproc.hpp"
    #include "opencv2/highgui/highgui.hpp"
    
    using namespace std;
    using namespace cv;
    
    int main()
    {
    	//Bild hochladen
    	IplImage* image = cvLoadImage("imaga.jpg", CV_LOAD_IMAGE_UNCHANGED);
    
    	//Prüfen auf erfolgreichen Hochladen
    	if (!image)
    	{
    		cerr << " could not load image file !" << endl;
    		exit(EXIT_FAILURE);
    	}
    
    	// im Graubild umwanddeln
    	IplImage* image_gray = cvCreateImage(cvGetSize(image),IPL_DEPTH_8U, 1);// einkaliges Bild erzeugen, wo das Graubild gespeichert werden soll!
    	cvCvtColor(image, image_gray, CV_BGR2GRAY);
    
    	//Histogrammausgleich durchführen (optional), um die Auftrittswahrscheinlichkeit aller verfügbaren Graustufen in etwa gleich wird.
    	IplImage* image_normalized = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);
    	cvEqualizeHist(image_gray, image_normalized);
    
    	// GaussFilter ansetzen, um Bild Bildrauschen zu reduzieren..
    	IplImage* image_filter = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);
    	cvSmooth(image_gray, image_filter, CV_GAUSSIAN, 11, 11);
    
    	//Kontourenerkennung mit cvcanny
    	IplImage* image_canny = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);
    
    	cvCanny(image_filter, image_canny, 30, 87, 3);
    
    	//Kontourenerkennung mit cvfindcontours...  
    	//Der Befehl arbeitet mit einem Binärbild, daher muss das Graubild in binär umgewandelt werden(mit dem Befehl threshold). Im gegensatz zu cvCanny, der nur mit Graubilder arbeitet!
    
    	IplImage* image_binaer = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);
    	cvThreshold(image_filter, image_binaer, 170, 255, CV_THRESH_BINARY_INV);// Alle Pixelwerte kleiner als wert1(drittes Argument) bekommen den Wert 0(Scharz), sonst den Wert 255(weiß).
    
    	CvMemStorage* storage = cvCreateMemStorage(0);//Gib frei und verwaltet die gesamte Datenstruktur für den Konturenfilter
    	CvSeq* contours = NULL;//deklariert die variable contours als Datenstruktur
    
    	cvFindContours(image_binaer, storage, &contours, sizeof(CvContour), CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE, cvPoint(0, 0));
    
    	//Konturen zeichen in ein neues Bild
    	IplImage* image_konturen = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);
    	cvDrawContours(image_konturen, contours, cvScalar(0), cvScalarAll(0), CV_FILLED, 1);
    
    	//Fenster zur Veranschaulichung erzeugen und anzeigen
    	cvNamedWindow("Farbbild", CV_WINDOW_AUTOSIZE);
    	cvNamedWindow("Kontourenzeichnung", CV_WINDOW_AUTOSIZE);
    	cvNamedWindow("Beispiel", CV_WINDOW_AUTOSIZE);
    
    	cvShowImage("Farbbild", image);
    	cvShowImage("Kontourenzeichnung", image_konturen);
    	cvShowImage("Beispiel", img);
    
          //Speicherplatz wieder freigeben und Inhalte loeschen
    	cvClearMemStorage(storage);
    	cvReleaseMemStorage(&storage);
    
    	//Fenster Zur Veranschaulichung schließen und Speicherplatz für für Fotos und Video wieder freigeben
    	cvDestroyAllWindows;
    	cvReleaseImage(&image);
    
    	cvWaitKey(0);
    	return(EXIT_SUCCESS);
    }
    


  • Mache derzeit meine ersten Erfahrungen mit C++ und OpenCV (Gesichtserkennung), da fallen mir zwei Sachen auf:

    - die meisten cv-Sachen die da benutzt werden sind für C gedacht und aus Kompatibilitätsgründen vorhanden, für C++ haben die andere Funktionen (z.B. "Mat" statt "IplImage")

    - cvFindContours liefert ein array "contours" zurück, welches in einer Schleife abgearbeitet werden sollte, also jede gefundene Kontur einzeln, dann sieht man viel besser was da wirklich gefunden wurde, ist bei der Gesichtserkennung auch so. So wie du das machst weiß ich garnicht was da passiert.

    Ansonsten empfehle ich funktionierende (modernere) Beispiele zu suchen und sich an denen ranzutasten. Das web ist leider von von Uraltcode.

    ... und am Bestens würde ich gern verstehen , was dann im Programm Passiert.

    Na da musst du einfach ran, das kann dir keiner abnehmen.



  • wie wärs, wenn du dich mal mit Bildverarbeitung beschäftigst, statt irgendwelchen Code aus dem Internet zusammenzukopieren?

    Lies:
    Computergrafik und Bildverarbeitung: Band II: Bildverarbeitung

    Eines der wenigen guten Bücher in deutscher Sprache (was dir ja wichtig ist) zu dem Thema.

    Davor macht es wenig Sinn, sich mit OpenCV zu beschäftigen.



  • fdfsfs schrieb:

    wie wärs, wenn du dich mal mit Bildverarbeitung beschäftigst, statt irgendwelchen Code aus dem Internet zusammenzukopieren?

    Lies:
    Computergrafik und Bildverarbeitung: Band II: Bildverarbeitung

    Eines der wenigen guten Bücher in deutscher Sprache (was dir ja wichtig ist) zu dem Thema.

    Davor macht es wenig Sinn, sich mit OpenCV zu beschäftigen.

    Das muss überhaupt nicht so sein - mir ging es wie ihm, hatte weder von C++ noch von OpenCV Ahnung und habe das Programm trotzdem so hinbekommen wie ich es mir vorgestellt hatte, sämtliches KnowHow aus den Web bezogen. Ich verstehe die Mathematik und Regeln hinter der Bildanalyse nicht (wieder eine Wissenschaft für sich), will es auch garnicht, für meine Zwecke reicht es wenn man gute Beschreibungen und Beispiele der Methoden findet. Erst wenn ich mehr Details benötige investiere ich die Zeit in einen Wälzer.

    EDIT
    sehe gerade dein Buchvorschlag: 55 Euro und 600 Seiten ... bis man das durchgeackert hat gibt es kein C++ mehr



  • deejey schrieb:

    EDIT
    sehe gerade dein Buchvorschlag: 55 Euro und 600 Seiten ... bis man das durchgeackert hat gibt es kein C++ mehr

    1. auf Uni Bib. ausborgen -> 0 Euro
    2. gezielt nur relevante Teile lesen -> Volumen schrumpft auf 100 Seiten
    3. an Lesegeschwindigkeit arbeiten



  • aaaaaaaaaaaaaaaaaa schrieb:

    deejey schrieb:

    EDIT
    sehe gerade dein Buchvorschlag: 55 Euro und 600 Seiten ... bis man das durchgeackert hat gibt es kein C++ mehr

    1. auf Uni Bib. ausborgen -> 0 Euro
    2. gezielt nur relevante Teile lesen -> Volumen schrumpft auf 100 Seiten
    3. an Lesegeschwindigkeit arbeiten

    Aus deinem Usernamen schließe ich du befindest dich gerade auf Toilette



  • Hallo an Alle,
    danke @deejey für deine Antwort. Ich sehe es auch genau so. Ich habe mich natürlich auch mit jeder aus dem Internet gezogene Codezeile auseinander gesetzt, es gab nur ein paar Stellen, wo das nicht so ganz klar war. Ich habe es jetzt noch hinbekommen und zwar ganz gut sogar.

    Grüße


Log in to reply