OpenCV - Problem mit cvSaveImage



  • Hallo,

    habe da mal wieder eine kurze Frage die bestimmt schnell beantwortet werden kann.

    Ich möchte Bilder mit einer fortlaufenden Nummer in mein Projektverzeichnis Ordner "pic" speichern. Dabei soll es egal sein ob mein Projektverzeichnis direkt unter C:/ liegt oder wie im Beispiel unter c:/workspace/FaceRec/

    Wenn ich (fortlaufende Nummer noch nicht realisiert)

    cvSaveImage(".../pic/0001.JPG", img);
    

    verwende, bricht er an dieser Stelle ab 😞

    Wenn ich

    cvSaveImage("c:/workspace/FacRec/pic/0001.JPG", img);
    

    funktioniert es. Welch Wunder! 🙄

    Kann mir da jemand einen Tipp geben??
    Hab leider keinen Beitrag dazu gefunden 😞


  • Mod

    Versuch mal in den Kombinationen:
    "../foo/bar.jpg"
    oder
    "foo/bar.jpg"



  • PERFEKT...

    wobei cvSaveImage(".../pic/0001.JPG", img); eh nicht funktioniert hät 😉 Mit ... aber egal

    die Lösung war cvSaveImage("pic/0001.JPG", img);

    Dankeschön... 🙂



  • Hallo,

    habe auch ein Problem mit openCV cvSaveImage. Ich arbeite mit Ubuntu 8.04.
    Habe ein ganz einfaches Programm zum lesen und schreiben eines Bildes geschrieben:

    // LoadSaveimage.cpp
    #include <highgui.h>
    
    int main(){
      IplImage* im;
      im = cvLoadImage("input.jpg",1);
    
      cvSaveImage("output.jpg",im);
    }
    

    Kompiliert habe ich mit:
    g++ -I/usr/local/include/opencv -L/usr/local/lib -lhighgui -o LoadSaveimage LoadSaveimage.cpp

    keine Fehler. Allerdings beim ausführen:

    ./LoadSaveimage

    OpenCV ERROR: Unspecified error (could not find a filter for the specified extension)
    	in function cvSaveImage, loadsave.cpp(497)
    Terminating the application...
    	called from cvUnregisterType, cxpersistence.cpp(4933)
    Terminating the application...
    	called from cvUnregisterType, cxpersistence.cpp(4933)
    Terminating the application...
    	called from cvUnregisterType, cxpersistence.cpp(4933)
    Terminating the application...
    	called from cvUnregisterType, cxpersistence.cpp(4933)
    Terminating the application...
    	called from cvUnregisterType, cxpersistence.cpp(4933)
    Terminating the application...
    	called from cvUnregisterType, cxpersistence.cpp(4933)
    Terminating the application...
    	called from cvUnregisterType, cxpersistence.cpp(4933)
    Terminating the application...
    	called from cvUnregisterType, cxpersistence.cpp(4933)
    Terminating the application...
    	called from cvUnregisterType, cxpersistence.cpp(4933)
    Terminating the application...
    

    Ubuntu läuft unter Virtualbox.
    Hab grad keine Idee warum der fehler auftritt..



  • Hat sich geklärt.

    habe zum probieren eine anderes Bildformat genommen (png) vorher jpg, hat wohl mit jpg etwas probleme gehabt.



  • Wie kann ich in OpenCV fortlaufende Bilder speichern?
    Also z.B. Bild1.jpg, Bild2.jpg, Bild3.jpg, ...

    Dachte da an irgendetwas wie

    cvSaveImage("Bild"n".jpg", image);
    

    wobei das "n" eine fortlaufende Zahl in einer Schleife sein soll und das "image" immer wieder neu in dieser Schleife gezeichnet werden soll.
    Habe bisher nichts darüber gelesen und funktionieren tut das so ja selbstverständlich nicht 🙂
    Gruß Saul



  • Saul schrieb:

    Wie kann ich in OpenCV fortlaufende Bilder speichern?
    Also z.B. Bild1.jpg, Bild2.jpg, Bild3.jpg, ...

    Dachte da an irgendetwas wie

    cvSaveImage("Bild"n".jpg", image);
    

    wobei das "n" eine fortlaufende Zahl in einer Schleife sein soll und das "image" immer wieder neu in dieser Schleife gezeichnet werden soll.
    Habe bisher nichts darüber gelesen und funktionieren tut das so ja selbstverständlich nicht 🙂
    Gruß Saul

    Du musst den String vorher zusammensetzen und dann an die Funktion übergeben. Das ginge z.B. mit sprintf/snprintf:

    int num=5;
    char filename[260]={0};
    snprintf(filename,260,"Bild%n",num);
    //filename an cvSaveImage übergeben
    

    Oder mit std::string:

    int num=5;
    std::string str("Bild");
    str+='0'+num;
    //str.c_str() an cvSaveImage übergeben
    

    Übrigens hättest du ruhig einen neuen Thread aufmachen können, anstatt dich an diesen uralten dranzuhängen. 🙂



  • Also scheinbar nimmt die cvSaveImage-Funktion keine sprintf-Funktion als Attribut an...
    Fehlermeldung "Konvertierung von 'int' in 'const char *' nicht möglich."
    Aber danke dir trotzdem!
    Gruß Saul



  • Saul schrieb:

    Also scheinbar nimmt die cvSaveImage-Funktion keine sprintf-Funktion als Attribut an...
    Fehlermeldung "Konvertierung von 'int' in 'const char *' nicht möglich."
    Aber danke dir trotzdem!
    Gruß Saul

    So habe ich das auch nicht gesagt...

    Ok, schau mal:

    Eher der C-Weg:

    int num=5;
    char filename[260]={0};
    snprintf(filename,260,"Bild%n.jpg",num);
    //filename an cvSaveImage übergeben, bedeutet:
    cvSaveImage(filename, image);
    

    Eher der C++-Weg:

    int num=5;
    std::string str("Bild");
    str+='0'+num;
    str+=".jpg";
    //str.c_str() an cvSaveImage übergeben, bedeutet:
    cvSaveImage(str.c_str(), image);
    

    Schau dir doch bitte mal die Doku zu den gezeigten Funktionen/Klassen an.

    EDIT: Übrigens würde ich dir raten, doch noch ein wenig die Basics zu lernen, bevor du dich an OpenCV ranmachst. Es mag dir unter den Fingern jucken bei den ganzen schönen Funktionen, die die lib bietet, aber letztlich wirst du weiter kommen, wenn du das Programmieren Schritt für Schritt lernst und dich nicht gleich an eine solche Bibliothek heranwagst, die genug Stolperfallen für Ungeübte bereithält.



  • Super, danke matze! Jetz hab ichs verstanden. Genau danach habe ich gesucht.

    Und nun wollte ich das gleiche nocheinmal für das öffnen von Bildern realisieren.
    Wenn ich das nun aufs öffnen anwende, sollte das ja so aussehen (hab mal die c variante übernommen):

    const char* bild="bild1";
    sprintf(bild, %s.jpg", bild);
    IplImage* image=cvLoadImage(bild, 1);
    

    Dabei soll "char* bild" aber variabel sein und nicht konstant. So, das er alle Bilder mit der Endung .jpg öffnet.
    Dafür muss ich denke ich mal das ganze Verzeichnis durchsuchen und die Dateinamen in einem Array speichern, indem nur die letzten vier bzw. drei Zeichen von Bedeutung sind.
    Kann mir zufällig jemand sagen, wie ich die Dateinamen einlese?
    Gruß Saul





  • Hallo Matze,
    is zwar schon ne Weile her, wollte mich aber nochmal für deinen Hinweis bedanken.
    Aber ich habs jetzt mit der dirent.h gelöst. Also mit opendir, readdir und closedir.
    Also bis denn dann, Gruß
    Saul


  • Mod

    _matze schrieb:

    Oder mit std::string:

    int num=5;
    std::string str("Bild");
    str+='0'+num;
    //str.c_str() an cvSaveImage übergeben
    

    Übrigens hättest du ruhig einen neuen Thread aufmachen können, anstatt dich an diesen uralten dranzuhängen. 🙂

    Nimm lieber std::stringstream und den op <<.
    Deine Lösung funktioniert nur bis num < 10.

    Und ja, macht lieber einen eigenen Thread auf, dies soll ja kein Sammelthread sein.


Anmelden zum Antworten