Data stored in OpenCV cv::Mats are not always continuous in memory, which can be verified via API Mat::isContinuous(). Instead, it follows the following rules:
Matrices created by imread(), clone(), or a constructor will always be continuous.
The only time a matrix will not be continuous is when it borrows data from an existing matrix (i.e. created out of an ROI of a big mat), with the exception that the data borrowed is continuous in the big matrix, including
borrow a single row;
borrow multiple rows but with full original width.
The following code demonstrates this in a better way (see the inline comments for further explanation).
mats[0] = cv::Mat::ones(1000, 800, CV_32FC3); // continuous as created using constructor mats[1] = mats[0](cv::Rect(100, 100, 300, 200)); // NOT continuous as borrowed data is not continuous (multiple rows and not full original width) mats[2] = mats[1].clone(); // continuous as created using clone() mats[3] = mats[2].row(10); // continuous for single row always mats[4] = mats[2](cv::Rect(5, 5, 100, 2)); // NOT continuous as borrowed data is not continuous (multiple rows and not full original width) mats[5] = mats[2](cv::Rect(0, 5, mats[2].cols, 2)); // continuous as borrowed data is continuous (multiple rows with full original width) mats[6] = mats[2].col(10); // NOT continuous as borrowed data is not continuous (multiple rows and not full original width)
for (size_t i = 0; i < mats.size(); ++i) { if (mats[i].isContinuous()) { std::cout << "Data of mats[" << int(i) << "] is continuous with size =" << mats[i].size() << std::endl; } else { std::cout << "Data of mats[" << int(i) << "] is NOT continuous with size =" << mats[i].size() << std::endl; } }