2013-02-06 23 views
11

Mam bufor unsigned char* zawierający dane obrazu jpeg. Chciałbym wyświetlić ten obraz za pomocą C++ i opencv. Jeśli to zrobię:opencv odczytanie obrazu jpeg z bufora

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

Dostaję hałaśliwy bałagan pikseli.

Przypuszczam, że to dlatego, że dane to jpeg (z nagłówkiem). Ponieważ to działa:

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

ale nie można korzystać z funkcji imdecode jak to jest z highgui.h która jest oparta na GTK 2, a w moim projekcie używam GTK 3.

Więc, jak mogę wyświetlić dane bufora? Czy istnieje sposób dekodowania obrazu jpeg innego niż imdecode w opencv, jeśli to jest problem. Naprawdę nie chcę odbudować opencv z Qt ...

Jakieś inne sugestie?

(Korzystanie Linux)

+2

nie można użyć 'libjpeg' do dekodowania i być z nim zrobić? na czym polega problem z tym? – mmgp

+0

@mmgp postaram libjpeg, tylko, że nie mogłem zrobić to samo, bez dołączania innej biblioteki – Matekk

+1

opencv nie ładuje obrazu JPEG, jeśli nie nie ma "libjpeg", więc nie ma dołączonej żadnej innej biblioteki. – mmgp

Odpowiedz

4

Mam dekompresji obrazu JPEG przy użyciu libjpeg stosując standardową procedurę opisaną w libjpeg API documentation w "szczegóły dekompresji.

Po rozpakowaniu danych można użyć go do skonstruowania cv::Mat. Pamiętaj, że zdekompresowany obraz jest w formacie RGB, podczas gdy openCV używa formatu BGR, więc potrzebna jest operacja cvtColor() o formacie CV_RGB2BGR.

27

Widziałem wiele odpowiedzi na to pytanie w sieci, mówiąc, że powinieneś bezpośrednio wywoływać libjpeg i ominąć procedurę imread() OpenCV.

To NIE jest konieczne! Można użyć metody imdecode(), aby odszyfrować surowy bufor obrazu z pamięci. Sposób wykonania tego zadania NIE jest intuicyjny i nie jest wystarczająco udokumentowany, aby pomóc ludziom próbującym to zrobić po raz pierwszy.

Jeśli masz wskaźnik/rozmiar dla danych surowych plików (fread() bezpośrednio z .jpg, .png, .tif, plików, itp ...

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 
} 

to jest to!

Nadzieja to pomaga komuś w przyszłości.

+0

To pomogło komuś. Zauważ, że użyłeś "size" zamiast "nsize" i możesz zainicjować rawData bezpośrednio z konstruktora. –

Powiązane problemy