C ++ OpenCV Max. Storage capacity cv :: Mat

In my program, I upload some images, extract some functions from them, and use them cv::Matto store these functions. Based on the number of images that I know, the size cv::Matwill be 700,000 x 256 (x col lines), which is about 720 MB. But when I run my program, when it receives about 400,000 x 256 (400 MB) and tries to add more, it just crashes with Fatal Error. Can anyone confirm that 400Mb is really the capacity limit cv::Mat? Should I check for additional issues? Possible solutions to this problem?

+4
source share
3 answers

Dig the source code using push_back:

it checks if there is enough space for the new element, if not, it redistributes the matrix with space for (current_size * 3 + 1) / 2 ( see here ). In your example about 400 000 * 256 (total 102 400 000 elements) it tries to perform a different distribution, so it attempts to allocate space for 001/2 = 307 200 153 600 000 elements. But in order to move this, he needs to allocate a new space, and then copy the data

From matrix.cpp :

Mat m(dims, size.p, type());
size.p[0] = r;
if( r > 0 )
{
    Mat mpart = m.rowRange(0, r);
    copyTo(mpart);
}

*this = m;

So this is essential:

  • Selects a new matrix using the default constructor for all newly created elements.
  • Copy data and delete old data
  • ( )

, (600 000 + 400 000) * 256 - 1 4 . 600 000 , 2400 000 .

, , 600 000 , 900 000x256 (900Mb) + 600 000x256 (600Mb) + 600 000 (~ 3.4Mb). , ( push_back), .

: , reserve . ( ).

, , , , .

: realloc malloc/memcpy?

+2

. CV_8UC4, 700 . . , 400Mb . 700Mb . (1400000 , 1.4Gb) - ( BMP , ).

const unsigned int N_rows = 700000;
const unsigned int N_cols = 256;
cv::Mat m(N_rows, N_cols, CV_8UC4);
for (int r = 0; r < m.rows; ++r)
{
    for (int c = 0; c < m.cols; ++c)
    {
        m.data[(r*N_cols + c) * 4] =  c % 256;
    }
}
cv::imwrite("test.bmp", m);

:

  • cv::Mat , , . , .
  • 32-, , 64-, .
  • 32- 720Mb . , , . , , 2Gb. - .
  • , , , , , OpenCV , , .
  • , /// , .
+1

cv::Mat. , .

, , cv::Mat::push_back . rows cols , a.data, .

#include <opencv2/opencv.hpp>
int main()
{
  int rows = 1, cols = 10000;
  cv::Mat a(rows, cols, CV_8UC1);
  while(1) {
    a.push_back(cv::Mat(1, cols, CV_8UC1));
    std::cout << (size_t) a.data << std::endl;
  }
}

, . a.

Remember that, like C ++ 11 std::vector, elements in cv::Matare contiguous. Access to basic data can be obtained through a member cv::Mat::data. Calling std::vector::push_backor cv::Mat::push_backcontinuously may result in a redistribution of base memory. In this case, the memory should be transferred to the new address, and approximately twice as much memory may be required to move from the old to the new (prohibiting any complex algorithm that uses less memory).

+1
source

Source: https://habr.com/ru/post/1660355/


All Articles