-1

When I setting a cv::Mat object with large width and height, the code would run exception... or print "bgModel.size != tsize." And when I lower width or height, print "bgModel.size == tsize." It seems that cv::Mat has a size limitation. Is there any method that can modify limitations?

software info. : windows 10 OS, Visual Studio 2015, OpenCV 2.4.13.5 hardware info. : i7-9700 CPU, 64GB Ram.

The C++ Code below:

int main()
{
    int nWidth = 13529;
    int nHeight = 10198;

    unsigned long long int tSize = static_cast<long long int>(nWidth)*static_cast<long long int>(nHeight)*static_cast<long long int>(25);
    
    try
    {
        cv::Mat bgModel;
        bgModel.create(1, nHeight*nWidth*25, CV_32F);
        
        if (bgModel.cols*bgModel.rows == tSize)
        {
            cout << "bgModel.size == tsize" << endl;
        }
        else
        {
            cout << "bgModel.size != tsize" << endl;
        }

        bgModel.release();
    }
    catch (...)
    {
        cout << "thrown exception...." << endl;
    }
    return 0;
}
Sebin Sunny
  • 1,753
  • 10
  • 9
  • yeah, the issue is that cv::Mat constructors and functions like `create` take in `int` as the type for width/height. So you're limited by the API. – PeterT Jul 02 '21 at 07:42
  • @PeterT I really don't call it API limitation really. it is 2147483647 for each dimension of Mat..... I think it is more case of trying to implement an idea without optimizing. – Afshin Jul 02 '21 at 07:47
  • You might think the limitation is reasonable, I would've thought so too in the year 2000. Doesn't change the fact that it's a limitation. – PeterT Jul 02 '21 at 07:53
  • @PeterT but we should consider that opencv in for image processing, and this limit covers almost any type of normal image. – Afshin Jul 02 '21 at 08:14

1 Answers1

3

I'm not sure why you need such huge cv::Mat, but its size is at least 12GB!!! So this code will not work if your code is compiled to 32-bit binary. I'm pretty sure that your exception comes from memory limits.

And finally: bgModel.cols and bgModel.rows are int, if you multiply them it will overflow and your calculation will be incorrect. so you need to cast it like you have done for tSize.

Another problem is that create() method is defined like this:

void cv::Mat::create(int rows, int cols, int type)  

and as you see int data type range for cols cannot handle nHeight*nWidth*25 which is 3,449,218,550. Max int can handle is 2,147,483,647.

Afshin
  • 8,839
  • 1
  • 18
  • 53
  • Even I try bgModel.create(nWidth*5, nHeight*5, CV_32F), the rows and cols are in range of int. It also not feasible.... Maybe I should think another method to handle such large data, not to use only one cv::Mat. – Alennex Cheng Jul 02 '21 at 08:25
  • @AlennexCheng You should consider trying not to load whole data in memory first if you can. – Afshin Jul 02 '21 at 08:30