Noob: Open CV - Flood Fill Parameter



  • Hallo,

    ich habe ein Problem. Um ein Bild zu segmentieren benutze ich die so genannte cvFloodFill Funktion von OpenCV. Nun ist es so, dass diese Funktion Regionen von einem Startpunkt aus auffüllt (dem so genannten Seed Point).

    In meinem Programm nutze ich jedoch mehrere Startpunkte, welche jeweils umliegende Regionen auffüllen sollen. Die Funktion lautet folgendermaßen:

    cvFloodFill(
    IntPtr src, //src image
    Point seedPoint, //seed point (x,y)
    MCvScalar newVal, //Füllfarbe
    MCvScalar loDiff, //niederer Grenzwert (grenze zum Auffüllen)
    MCvScalar upDiff, //maximaler Grenzwert
    [OutAttribute] MCvConnectedComp% comp, //connected component (soll eine contour enthalten!)
    FLOODFILL_FLAG flags, (gibt es mehrere Möglichkeiten, fixed range, nur maske)
    IntPtr mask (kann zum einen als Füllgrenze genutzt werden aber auch als maske ausgegeben werden)
    )

    Jetzt mein Anliegen:

    Ich benutze die Funktion natürlich für jeden Seedpoint. Da das src Image auch gleichzeitig das geflutete Image ist, kann ich keinen erneuten Aufruf des gleichen Images durchführen, weil sonst alte Regionen erneut geflutet werden könnten. Dem zu Folge brauche ich die Contour einer Region, oder Masken die sich einfach gegenseitig überlagern. OpenCV bietet dafür connectedcomp an oder mask.

    Ich habe schon ein paar Zwischenausgaben generiert, wobei der connected comp nach dem Aufruf überhaupt keinen Inhalt liefert und mask auch nur schwarze Bilder anzeigt.

    Der beste Weg für mich wäre einfach die Contour nach jedem FloodFill auszulesen und mit cvDrawContours zu malen. Ist mir aber bisher noch nicht gelungen. Hat jemand schonmal damit gearbeitet und kann mir sagen wie man mit Masken bzw. ConnectedComps arbeitet?

    ich bin über jede Hilfe dankbar.

    viele Grüße,

    Zodiak



  • Direkt für dein Problem habe ich jetzt keine Lösung, aber ich kann dir wirklich nur empfehlen, die C++-Variante von OpenCV zu verwenden, damit ist es wirklich viel leichter. Konturen finden ist zum Beispiel viel einfacher als mit dem ursprünglichen.



  • Ich habe das Problem jetzt lösen können!

    Zuerst einmal:

    Der ConnectedComp initialisiert keine Contour. Man kann ihn nutzen um herauszufinden wieviele Pixel gefüllt worden sind aber nicht für die eigentliche Lokalisierung. Die gefüllte Fläche wird sowohl direkt im Bild hinzugefügt als auch innerhalb einer Maske gespeichert. Problematisch dabei ist jedoch nur das per default die gefundenen Werte auf 1 gesetzt werden und deshalb ohne geeignete Skalierung nur ein schwarzes Bild ausgegeben wird.

    Folgendes muss also getan werden:

    IplImage *img_Original, *img_mask;
    img_Original = cvLoadImage("....insert Path here");
    CvConnectedComp comp;
    
    img_mask = cvCreateImage(cvSize(img_Original->width+2,img_Original->height+2),IPL_DEPTH_8U,1);
    cvZero(img_mask);
    
    ....
    
    //Aufruf (x,y) = Seedpoint, floodColorRGB = Füllfarbe
    
    cvFloodFill(img_Original,cvPoint(x,y),floodColorRGB, CV_RGB(8.0,8.0,8.0), CV_RGB(8.0,8.0,8.0), &comp, CV_FLOODFILL_FIXED_RANGE, img_mask);
    
    cvConvertScale(img_mask,img_mask,255,0); // setzt einfach 1 auf weiß und 0 auf schwarz
    
    cvNamedWindow("1", CV_WINDOW_AUTOSIZE );
    cvShowImage("1",img_mask);
    cvWaitKey(0);
    

    Auch wenn es trivial ist, ich habe es nur durch eine kleine Anmerkung in einem OpenCV Buch herausgefunden.

    Um jetzt z.B. mit mehreren Seedpoints zu arbeiten kann man z.B.

    1. von seedpoint aus füllen
    2. auf schwarz weiß skalieren
    3. contour per cvFindContours finden und als Seq speichern
    4. contour per cvDrawContours mit der Füllfarbe malen
    5. altes Bild wiederherstellen und zu 1.


Log in to reply