opencv read jpeg image from buffer
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.
Related videos on Youtube
Matekk
Updated on April 18, 2020Comments
-
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 about 11 yearsCan't you use
libjpeg
for decoding and be done with it ? What is the problem with that ? -
Matekk about 11 years@mmgp I will try libjpeg, just thought I could do the same thing without including another library.
-
mmgp about 11 yearsopencv won't load jpeg image if you don't have
libjpeg
, so there is no other library being included. -
TimZaman about 9 yearsWow 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 about 8 yearsIt did help someone. Note that you used 'size' instead of 'nsize', and you could have initialized rawData directly from the constructor.
-
aCuria about 6 yearsThis 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 about 4 years@aCuria that's probably because you forgot to put cv2.waitKey(0) after imshow()
-
aCuria about 4 yearsThis 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 about 3 yearsno need for
(void*)
, and also set the required flag (cv::IMREAD_COLOR
) in imdecode should do the trick.