opencv liest JPEG-Bild aus Puffer

Lesezeit: 3 Minuten

Benutzer-Avatar
Matekk

ich habe ein unsigned char* Puffer, der Daten eines JPEG-Bildes enthält. Ich möchte dieses Bild mit c++ und opencv anzeigen. Wenn ich mache:

Mat img(Size(640, 480), CV_8UC3, data);
namedWindow("image", 1);
imShow("image", img);

Ich bekomme ein verrauschtes Durcheinander von Pixeln.

Ich nehme an, es liegt daran, dass die Daten JPEG sind (mit einem Header). Denn das funktioniert:

Mat imgbuf(Size(640, 480), CV_8UC3, data);
Mat img = imdecode(imgbuf, CV_LOAD_IMAGE_COLOR);

ABER ich kann die imdecode-Funktion nicht verwenden, da sie von highgui.h stammt, die auf GTK 2 basiert, und in meinem Projekt verwende ich GTK 3.

Wie kann ich also die Pufferdaten anzeigen? Gibt es eine andere Möglichkeit, das JPEG-Bild als imdecode in opencv zu decodieren, wenn dies das Problem ist. Ich möchte OpenCV nicht wirklich mit Qt neu erstellen müssen …

Irgendwelche anderen Vorschläge?

(unter Linux)

  • Kannst du nicht verwenden libjpeg für die Dekodierung und fertig? Was ist das Problem daran?

    – mmp

    6. Februar 2013 um 20:34 Uhr

  • @mmgp Ich werde libjpeg ausprobieren, dachte nur, ich könnte dasselbe tun, ohne eine andere Bibliothek einzuschließen.

    – Matekk

    7. Februar 2013 um 8:49 Uhr


  • opencv lädt kein JPEG-Bild, wenn Sie es nicht haben libjpegsodass keine andere Bibliothek enthalten ist.

    – mmp

    7. Februar 2013 um 12:19 Uhr

  • Wow, was du tust, ist wirklich nicht in Ordnung. In deiner Mat imgbuf(...) Zeile lesen Sie Daten in 640x480x3-Feldern ein. Da JPEGs komprimiert sind, passt das JPEG tatsächlich problemlos hinein. Also werden die restlichen Spots dann mit Zufallsdaten aus dem Gedächtnis aufgefüllt, das ist sehr, sehr schlecht. Danach laden Sie die Mat, die das JPEG und eine Reihe zufälliger Speicherdaten enthält, und decodieren sie. Legen Sie stattdessen zuerst Ihren unsignierten Zeichenpuffer in einen Vektor oder eine Matte, die genau die Größe Ihres Puffers hat, und füttern Sie ihn DANN in Imdecode.

    – Tim Zaman

    3. März 2015 um 9:53 Uhr

Benutzer-Avatar
Jeff Reeder

Ich habe im Internet viele Antworten auf diese Frage gesehen, die besagen, dass Sie libjpeg direkt aufrufen und die imread() -Routine von OpenCV umgehen sollten.

Dies ist nicht erforderlich! Sie können imdecode() verwenden, um einen Rohbildpuffer aus dem Speicher zu decodieren. Der Weg, dies zu tun, ist NICHT intuitiv und nicht ausreichend dokumentiert, um Leuten zu helfen, die dies zum ersten Mal versuchen.

Wenn Sie einen Zeiger/eine Größe für Ihre Rohdateidaten haben (fread() direkt aus den .jpg-, .png-, .tif-Dateien usw. …

int    nSize = ...       // Size of buffer
uchar* pcBuffer = ...    // Raw buffer data


// Create a Size(1, nSize) Mat object of 8-bit, single-byte elements
Mat rawData( 1, nSize, CV_8UC1, (void*)pcBuffer );

Mat decodedImage  =  imdecode( rawData /*, flags */ );
if ( decodedImage.data == NULL )   
{
    // Error reading raw image data
}

Das ist es!

Hoffe, das hilft jemandem in der Zukunft.

  • Es hat jemandem geholfen. Beachten Sie, dass Sie „size“ anstelle von „nsize“ verwendet haben und dass Sie rawData direkt vom Konstruktor hätten initialisieren können.

    Benutzer1418330

    22. April 2016 um 22:08 Uhr


  • Dies hat bei mir NICHT funktioniert. Das Lesen von Bildern aus einem Netzwerkstream, das Speichern in einer Datei funktioniert, aber beim Aufrufen von imdecode wird ein graues Fenster mit cv::imshow(“Window”, decodedImage) angezeigt.

    – eine Kurie

    12. März 2018 um 5:43 Uhr

  • @aCuria das liegt wahrscheinlich daran, dass Sie vergessen haben, cv2.waitKey(0) nach imshow() zu setzen

    – Amir Rasti

    26. Februar 2020 um 6:58 Uhr

  • Das war vor sehr langer Zeit, aber ich konnte andere Bilder anzeigen (aus einer Datei geladen), also glaube ich nicht, dass der WaitKey das Problem war.

    – eine Kurie

    27. Februar 2020 um 9:36 Uhr

  • kein Bedarf für (void*)und setzen Sie auch das erforderliche Flag (cv::IMREAD_COLOR ) in imdecode sollte den Zweck erfüllen.

    – Hossein

    21. April 2021 um 7:11 Uhr

Ich habe das JPEG-Bild mit dekomprimiert libjpeg unter Verwendung des Standardverfahrens, das in beschrieben ist libjpeg-API-Dokumentation unter ‘Dekompressionsdetails’.

Nachdem Sie die Daten dekomprimiert haben, können Sie sie verwenden, um die zu konstruieren cv::Mat. Wohlgemerkt, das dekomprimierte Bild ist im RGB-Format, während openCV ein BGR-Format verwendet, also a cvtColor() Betrieb mit Format CV_RGB2BGR wird gebraucht.

1015580cookie-checkopencv liest JPEG-Bild aus Puffer

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy