OpenCV image size limit

后端 未结 2 1385
小蘑菇
小蘑菇 2021-01-20 17:17

I\'m trying to pass a huge Mat image (98304x51968) between openCV and itk using the ITK to openCV Bridge. I have an error :

Insufficient memory (OverFlow for imageS

2条回答
  •  轻奢々
    轻奢々 (楼主)
    2021-01-20 18:05

    Good news, since this pull request: handle huge matrices correctly #11505, you should be able to do something like this (code taken from the test):

    Mat m(65000, 40000, CV_8U);
    ASSERT_FALSE(m.isContinuous());
    
    uint64 i, n = (uint64)m.rows*m.cols;
    for( i = 0; i < n; i++ )
        m.data[i] = (uchar)(i & 255);
    
    cv::threshold(m, m, 127, 255, cv::THRESH_BINARY);
    int nz = cv::countNonZero(m);  // FIXIT 'int' is not enough here (overflow is possible with other inputs)
    ASSERT_EQ((uint64)nz, n / 2);
    

    Since countNonZero() returns an int, overflow is possible. This means that you should be able to create huge matrix but not all OpenCV function can handle correctly huge matrix.


    Regarding your issue, this is the code for ITKImageToCVMat in v5.0a02:

    template
    cv::Mat
    OpenCVImageBridge::ITKImageToCVMat(const TInputImageType* in, bool force3Channels)
    {
      // Extra copy, but necessary to prevent memory leaks
      IplImage* temp = ITKImageToIplImage(in, force3Channels);
      cv::Mat out = cv::cvarrToMat( temp, true );
      cvReleaseImage(&temp);
      return out;
    }
    

    As you can see, IplImage image is still used and should be the source of your error. Your best option currently should be to do the conversion yourself. Maybe something like (I don't know ITK, same input and output type, one channel):

    typename ImageType::RegionType  region = in->GetLargestPossibleRegion();
    typename ImageType::SizeType    size = region.GetSize();
    unsigned int w = static_cast< unsigned int >( size[0] );
    unsigned int h = static_cast< unsigned int >( size[1] );
    Mat m(h, w, CV_8UC1, in->GetBufferPointer());
    

    No copy is involved here. If you want to copy, you can do:

    Mat m_copy = m.clone();
    

提交回复
热议问题