Data-array "organisation" of image Mat. (Mat->GIF)

asked 2016-12-03 09:10:18 -0500

Fly gravatar image

updated 2016-12-03 11:28:20 -0500

I'm trying to export some frames as a GIF by using this library:

Unfortunately, it seems that the char-array the library requires for each frame is ordered differently than Mat#data. Which led me to memory errors when trying to simply pass the Mat-data-array as argument.

I did read the documentation of "Mat", but can't say that I truly understood, and thus don't know how to properly convert it.

I tried to convert it like this:

const int dim = resolution.width * resolution.height * 4;
uint8_t* pixels = (uint8_t*)alloca(sizeof(uint8_t) * dim);
for (int y = 1; y <= res.width; y++){
    for (int x = 1; x <= res.height; x++){
        uint8_t* pixel = NULL; 
        f->pixelAt(x-1, y-1, pixel);
        pixels[(y*x-1)] = pixel[0];
        pixels[(y*x - 1) + 1] = pixel[1];
        pixels[(y*x - 1) + 2] = pixel[2];
        pixels[(y*x - 1) + 3] = 255;

Where f->pixelAt(x, y, pixel) equals to:

void OpenCV_Frame::pixelAt(int x, int y, uint8_t* retVal){
    retVal = new uint8_t[3];
    cv::Vec3b vec = at<cv::Vec3b>(y, x);
    retVal[0] = vec[0];
    retVal[1] = vec[1];
    retVal[2] = vec[2];

I get a stackoverflow error when allocating the uint8_t array. I know that the array is ridiculously big, but I'm not sure how to approach this problem otherwise.

Help appreciated, thanks!

edit retag flag offensive close merge delete


try to convert to rgba first (it seems to expect 4 channels, not 3 and clearly says so in the readme ;) )

berak gravatar imageberak ( 2016-12-03 09:49:07 -0500 )edit

@berak Right, just noticed that too - Thanks! I actually tried converting it now, but failed horribly at doing so (Stack Overflow error)... I'll put the code I wrote in my post.

Fly gravatar imageFly ( 2016-12-03 11:24:10 -0500 )edit

bloody, use cvtColor(src,dst,COLOR_BGR2RGBA), not your shoddy loop !

( there's not a single item correct there ! )

berak gravatar imageberak ( 2016-12-03 11:28:55 -0500 )edit

@berak It works. OMG. Thank you so much! Just for the record though, what exactly are all the things that are wrong with my loop :D?

Fly gravatar imageFly ( 2016-12-03 11:52:43 -0500 )edit

(apologies again, for being so harsh, but i really owe you some explanation here)

so for the record:

  • you're comparing y to W and x to H (wrong way)
  • we start counting at 0 in c++, not 1
  • <= is one over the top
  • for a 4 channel img, pointer offsets are: pixels[(4 * (y*W + x) + channel] (not your blunder)

again, - lesson is simply: never write that kind of loop, there's always something better, faster, less error-prone already builtin. try to use opencv, not defeat it.

berak gravatar imageberak ( 2016-12-03 11:57:24 -0500 )edit