In which case Mat data is in continuous memory block and which case is not?

asked 2016-03-24 14:33:20 -0500

cuongvt101 gravatar image

updated 2016-03-24 15:30:56 -0500

I know that OpenCV has the method isContinuous() to check. However, what I want to know is in which cases we know for sure that Mat data is in continuous memory block. So far, based on what I've been searching around, it seems that in these cases Mat data would be in continuous memory block:

  • Read an image using imread()
  • Create a new Mat using Mat() constructor
  • Using create() method
  • Using initializers like zeros(), ones(), etc.

In these cases Mat data would NOT be in continuos memory block:

  • Take ROI from an existing Mat
  • Take some columns from an existing Mat

Is it correct? Is there any other cases? Or can you provide a more generalized look? Please don't tell me that I should not worry about memory management as OpenCV takes care of it internally. It's much easier if we know for sure which cases we have continuous memory block.

Thanks a lot.

PS: The reason I come up with this question is from the accepted answer in SO: http://stackoverflow.com/questions/41...

in this part:

for (size_t dc = 0; dc < dataSize; ++dc) {
          ar & m.data[dc];
}

I think he assumes the Mat data is in continuous memory block, which I know is not always the case.

edit retag flag offensive close merge delete

Comments

Usually a ROI of a cv::Mat is not continuous for example:

cv::Mat image(cv::Size(512, 512, CV_8U);
cv::Mat subImage = image(cv::Rect(256, 256, 128, 128));

where subImage is not continiuous, but the single columns are continuous regardless. This is important if you access cv::Mat using pointer or intrinsics. This gives you a very good overview about data storage of cv::Mat

matman gravatar imagematman ( 2016-03-24 15:50:03 -0500 )edit

If you like, you can use the forEach function in 3.0 or newer. It will take the function you give it and apply it to each pixel in the Mat.

But your list looks about right. If you use the non-default constructors you can pass strides and so forth to construct a non-continuous one. That's the only thing I can think of that isn't on your list.

Tetragramm gravatar imageTetragramm ( 2016-03-24 16:01:44 -0500 )edit

@matman: Thanks, I have read about basic Mat before asking the question but I could not find the answer for my question there. Sure it talks about storage but doesn't say about continuous block of memory or not.

cuongvt101 gravatar imagecuongvt101 ( 2016-03-24 16:14:31 -0500 )edit

@ Tetragramm: Thanks. I care more about the case where we surely have a continuous block of memory. As a matter of fact, I need to serialize a large Mat (may be of 100M rows and 128 columns, think of a visual dictionary in Bag-Of-Word model) and I need to do it right.

cuongvt101 gravatar imagecuongvt101 ( 2016-03-24 16:17:18 -0500 )edit

I think each row is guaranteed to be continuous. So if you do it row-wise, you're good no matter what.

Tetragramm gravatar imageTetragramm ( 2016-03-24 16:31:41 -0500 )edit

I think cv::Mat is very similar to std::vector so if you don't split your data it is continuous

matman gravatar imagematman ( 2016-03-24 16:52:49 -0500 )edit