2013-02-06 5 views
11

Ho un buffer unsigned char* contenente i dati di un'immagine jpeg. Mi piacerebbe mostrare quell'immagine usando C++ e opencv. Se lo faccio:opencv legge l'immagine jpeg dal buffer

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

Ottengo un caos rumoroso di pixel.

Suppongo che sia perché i dati sono jpeg (con un'intestazione). Perché questo funziona:

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

ma non riesco a utilizzare la funzione imdecode quanto è da highgui.h che si basa su GTK 2, e nel mio progetto che uso GTK 3.

Così, come posso mostra i dati del buffer? C'è un modo per decodificare l'immagine jpeg diversa da imdecode in opencv, se questo è il problema. Non voglio davvero ricreare opencv con Qt ...

Altri suggerimenti?

(Utilizzo di Linux)

+2

non è possibile utilizzare 'libjpeg' per la decodifica e da fare con esso? Qual è il problema? – mmgp

+0

@mmgp cercherò libjpeg, solo pensato che avrei potuto fare il stessa cosa senza includere un'altra libreria. – Matekk

+1

opencv non caricherà l'immagine jpeg se lo fai non ha 'libjpeg', quindi non ci sono altre librerie incluse. – mmgp

risposta

4

ho decompresso l'immagine JPEG utilizzando libjpeg seguendo la procedura standard descritta nel libjpeg API documentation sotto 'i dettagli di decompressione.

Dopo aver decompresso i dati, è possibile utilizzarlo per costruire lo cv::Mat. Intendiamoci, l'immagine decompressa è in formato RGB, mentre openCV utilizza un formato BGR quindi è necessaria l'operazione cvtColor() con il formato CV_RGB2BGR.

27

Ho visto molte risposte a questa domanda in rete dicendo che dovresti chiamare libjpeg direttamente e bypassare la routine imread() di OpenCV.

Questo NON è necessario! È possibile utilizzare imdecode() per decodificare un buffer di immagini raw dalla memoria. Il modo per farlo NON è intuitivo e non è sufficientemente documentato per aiutare le persone a provare a farlo per la prima volta.

Se si dispone di un puntatore/dimensioni per i dati dei file grezzi (fread() direttamente dal jpg, png, tif, file, ecc ...

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 
} 

il gioco è fatto!

Spero che questo aiuti qualcuno in futuro.

+0

Ha aiutato qualcuno. Nota che hai usato 'size' invece di 'nsize', e potresti aver inizializzato rawData direttamente dal costruttore. –