Ask Your Question
0

Mat to raw Image

asked 2015-09-25 03:54:21 -0600

Cedric_K gravatar image

Hello,

I am having trouble writing a raw image from a Mat. I am using OpenCV 2.3.1. I have seen plenty of replies for the inverse operation (raw to Mat) but not Mat to raw. I am not even sure it is possible the way I do it since no headers are set.

The following code opens a video, and saves the 10 first frames into files. When I try to open those file with XNview (for example), I get a black and striped image. Clearly not the expected image. The .raw file starts with plenty of 00 00 00 00 before the real content. I cannot figure out what I am missing. DO I need to add headers ?

Thanks a lot in advance

Here is the code :

int main( int argc , char *argv[] )
{
  unsigned long lFrameId = 0;

  // open video file
  string mediaPath = "/home/videos/film.mp4";
  VideoCapture captureV;
  Mat frame;

  captureV.open(mediaPath);

   if( !captureV.isOpened() )
   {
     cerr << "capture error" << endl;
     exit(1);
   }

  // set media parameters
  captureV.set(CV_CAP_PROP_CONVERT_RGB, true);

  while (lFrameId < 10
  {
    captureV.read(frame);

    int rows = frame.rows;      // 880)
    int cols = frame.cols;      // 720
    uchar* buffer = frame.data; // 8-bit pixel

    // Write frame data into raw file
    ostringstream filename;
    filename << "Frame_" << lFrameId << ".raw";
    std::ofstream outfile (filename.str().c_str(), ios::out | ios::binary);
    outfile.write ((char*)(buffer), frame.total());  // In byte so frame.total() should be enough ?
    outfile.close();

    ++lFrameId;
  }

  return 0;
}
edit retag flag offensive close merge delete

Comments

3
  • " I am using OpenCV 2.3.1." - ouch ;( reallllllllly, consider an upgrade.
  • "frame.total() should be enough" - no, it is not. your color image actually has 3 times the bytes of that, so use size_t nbytes = frame.total() * frame.elemSize(); (which is also safe, if you by chance got a float buffer or such)
berak gravatar imageberak ( 2015-09-25 05:32:00 -0600 )edit

Thanks. I thought RGB was encoded into one byte (3 bits for R, 3 bits for G and 2 bits for B). So why 3 times the bytes ? I have updated my code with frame.total() * frame.elemSize(); but still no chance to visualize the raw image. I will anyway consider upgrading OpenCV (from legacy system) but still I do not understand why I cannot visualize that raw image.

Cedric_K gravatar imageCedric_K ( 2015-09-25 05:53:47 -0600 )edit

"why 3 times the bytes ?" it is 24bit bgr, (3channels x 8bit) per pixel.

berak gravatar imageberak ( 2015-09-25 06:22:12 -0600 )edit

my guess is - your viewer program understands something completely else as 'raw' , like some 12bit output straight from some sensor. this is not what you get here.

berak gravatar imageberak ( 2015-09-25 08:02:00 -0600 )edit
1

Thank you very much for your help. I was misunderstanding the channels 8-bit coding. Your comment makes sense. I will post feedbacks if I can figure out the raw vizualisation issue.

Cedric_K gravatar imageCedric_K ( 2015-09-25 09:50:12 -0600 )edit
2

also, i guess, even if it is "raw" data, the must still be some kind of header information, like the size of the image

berak gravatar imageberak ( 2015-09-25 09:53:33 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
1

answered 2020-01-27 11:07:09 -0600

h22 gravatar image

updated 2020-01-28 08:03:25 -0600

What you write is really a very "raw" data without even saying how many rows and columns are in the file, and how many bytes per pixel. Maybe some viewers can open this, but they should need some helper text file with absolutely necessary metadata.

Use cv::imwrite to save in formats the image viewer would recognize.

edit flag offensive delete link more

Comments

opencv 3.0 is obsolete use 3.4.8 or 4.2.0 ...

LBerger gravatar imageLBerger ( 2020-01-28 07:05:23 -0600 )edit
1

Link changed to 4.2.0

h22 gravatar imageh22 ( 2020-01-28 08:03:46 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2015-09-25 03:54:21 -0600

Seen: 9,287 times

Last updated: Jan 28 '20