opencv read jpeg image from buffer

37,694

Solution 1

I have decompressed the JPEG image using libjpeg using the standard procedure described in the libjpeg API documentation under 'Decompression details'.

After having decompressed the data you can use it to construct the cv::Mat. Mind you, the decompressed image is in RGB format, whereas openCV uses a BGR format so a cvtColor() operation with format CV_RGB2BGR is needed.

Solution 2

I have seen many responses to this question around on the net saying that you should call libjpeg directly and bypass OpenCV's imread() routine.

This is NOT necessary! You can use imdecode() to decode a raw image buffer from memory. The way to do it is NOT intuitive, and isn't documented enough to help people trying to do this for the first time.

If you have a pointer/size for your raw file data (fread() directly from the .jpg, .png, .tif, files, 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
}

That's IT!

Hope this helps someone in the future.

Share:
37,694

Related videos on Youtube

Matekk
Author by

Matekk

Updated on April 18, 2020

Comments

  • Matekk
    Matekk about 4 years

    I have an unsigned char* buffer containing data of a jpeg image. I would like to display that image using c++ and opencv. If i do:

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

    I get a noisy mess of pixels.

    I suppose it's because the data is jpeg (with a header). Because this works:

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

    BUT I cannot use the imdecode function as it is from highgui.h which is based upon GTK 2, and in my project I use GTK 3.

    So, how can I display the buffer data? Is there a way to decode the jpeg image other than imdecode in opencv, if that's the problem. I don't really want to have to rebuild opencv with Qt...

    Any other suggestions?

    (Using Linux)

    • mmgp
      mmgp about 11 years
      Can't you use libjpeg for decoding and be done with it ? What is the problem with that ?
    • Matekk
      Matekk about 11 years
      @mmgp I will try libjpeg, just thought I could do the same thing without including another library.
    • mmgp
      mmgp about 11 years
      opencv won't load jpeg image if you don't have libjpeg, so there is no other library being included.
    • TimZaman
      TimZaman about 9 years
      Wow what you are doing is really not okay. In your Mat imgbuf(...) line you read in data in 640x480x3 fields. Since jpegs are compressed, the jpeg will indeed fit in there with ease. So the rest of the spots are then filled in with random data from memory, that's very, very bad. After that you load in the Mat, that includes the JPEG and a bunch of random memory data, and decode it. Instead, first put your unsigned char buffer in a vector or mat exactly the size of your buffer and THEN feed it in imdecode.
  • Admin
    Admin about 8 years
    It did help someone. Note that you used 'size' instead of 'nsize', and you could have initialized rawData directly from the constructor.
  • aCuria
    aCuria about 6 years
    This did NOT work for me. Reading images from a network stream, saving to file works but calling imdecode gives me a grey window with cv::imshow("Window", decodedImage)
  • Amir Rasti
    Amir Rasti about 4 years
    @aCuria that's probably because you forgot to put cv2.waitKey(0) after imshow()
  • aCuria
    aCuria about 4 years
    This was from a really long time ago, but i could display other images (loaded from file) so I dont think the waitKey was the issue.
  • Hossein
    Hossein about 3 years
    no need for (void*), and also set the required flag (cv::IMREAD_COLOR ) in imdecode should do the trick.