2013-02-06 14 views
11

Ich habe einen unsigned char* Puffer mit Daten eines JPEG-Bilds. Ich möchte dieses Bild mit C++ und opencv anzeigen. Wenn ich das tue:opencv lesen JPEG-Bild aus dem Puffer

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

Ich bekomme eine laute Durcheinander von Pixeln.

Ich nehme an, es liegt daran, dass die Daten jpeg (mit einem Header) ist. Da dies 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 es aus highgui.h ist, die auf GTK 2, und in meinem Projekt basiert ich GTK verwenden 3.

Also, wie kann ich Anzeige der Pufferdaten? Gibt es eine Möglichkeit, das JPEG-Bild anders als imdecode in opencv zu dekodieren, wenn das das Problem ist. Ich möchte Opencv mit Qt nicht wirklich neu aufbauen wollen ...

Irgendwelche anderen Vorschläge?

(mit Linux)

+2

können Sie nicht verwenden 'libjpeg' zur Decodierung und mit ihr geschehen? Was ist das Problem mit dem? – mmgp

+0

@mmgp ich werde libjpeg versuchen, dachte nur, ich das tun könnte Gleiches, ohne eine andere Bibliothek einzubinden – Matekk

+1

opencv wird JPEG-Bild nicht laden, wenn Sie das tun nicht 'libjpeg', also ist keine andere Bibliothek enthalten. – mmgp

Antwort

4

Ich habe das Bild JPEG dekomprimiert libjpeg das Standardverfahren in den libjpeg API documentation unter 'Decompression Details' erhalten werden.

Nachdem Sie die Daten dekomprimiert haben, können Sie sie verwenden, um die cv::Mat zu konstruieren. Beachten Sie, dass das dekomprimierte Bild im RGB-Format vorliegt, während openCV ein BGR-Format verwendet, so dass ein cvtColor()-Vorgang mit dem Format CV_RGB2BGR erforderlich ist.

27

Ich habe viele Antworten auf diese Frage im Internet gesehen, die sagen, dass Sie libjpeg direkt aufrufen und OpenCVs inread() Routine umgehen sollten.

Dies ist NICHT notwendig! Sie können imdecode() verwenden, um einen Rohbildpuffer aus dem Speicher zu dekodieren. Die Art, dies zu tun, ist NICHT intuitiv und nicht ausreichend dokumentiert, um Menschen zu helfen, die dies zum ersten Mal tun.

Wenn Sie einen Zeiger/Größe für Ihre RAW-Dateidaten (fread() direkt vom .jpg, .png, .tif, Dateien, etc ...

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 jemand in der Zukunft.

+0

Es hat jemandem geholfen. Beachten Sie, dass Sie "Größe" anstelle von "Größe" verwendet haben und Sie RawData direkt vom Konstruktor initialisiert haben könnten. –

Verwandte Themen