Opencv читает jpeg изображение из буфера

У меня есть буфер unsigned char*, содержащий данные jpeg-изображения. Я хотел бы отобразить это изображение с помощью С++ и opencv. Если я сделаю:

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

Я получаю шумный шум пикселей.

Я предполагаю это, потому что данные jpeg (с заголовком). Потому что это работает:

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

НО я не могу использовать функцию imdecode, как это из highgui.h, которая основана на GTK 2, и в моем проекте я использую GTK 3.

Итак, как я могу отобразить данные буфера? Есть ли способ декодировать jpeg-образ, отличный от imdecode в opencv, если это проблема. Я действительно не хочу, чтобы перестроить opencv с помощью Qt...

Любые другие предложения?

(с использованием Linux)

Ответ 1

Я декомпрессировал изображение JPEG с помощью libjpeg, используя стандартную процедуру, описанную в документации API libjpeg в разделе "Детали декомпрессии".

После распаковки данных вы можете использовать его для построения cv::Mat. Имейте в виду, что декомпрессированное изображение находится в формате RGB, тогда как openCV использует формат BGR, поэтому необходима операция cvtColor() с форматом CV_RGB2BGR.

Ответ 2

Я видел много ответов на этот вопрос в сети, говоря, что вы должны вызвать libjpeg напрямую и обходить процедуру OpenCV imread().

Это НЕ НЕОБХОДИМО! Вы можете использовать imdecode() для декодирования буфера необработанного изображения из памяти. Способ сделать это НЕ интуитивно понятен и недостаточно документирован, чтобы помочь людям, пытающимся сделать это в первый раз.

Если у вас есть указатель/размер для ваших необработанных данных файла (fread() непосредственно из .jpg,.png,.tif, файлов и т.д.

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
}

Это IT!

Надеюсь, это поможет кому-то в будущем.