在OpenCv中使用Ptr <iplimage>会导致内存异常

时间:2015-08-21 09:09:45

标签: opencv out-of-memory

void hello(Mat original)
{
  Mat a=original.clone();
  Ptr<IplImage> b = &a.operator IplImage();
  return;
}

此函数将导致内存异常。因为我必须使用一个旧的函数,哪个参数是IplImage *,我将Mat转换为Ptr并导致内存异常。以上功能只是一个简化版本。

2 个答案:

答案 0 :(得分:0)

Ptr<T>是一个模板类,可以自动销毁包装的对象指针(有关它的详细信息,请参阅official documentation)。

在您的代码段中,ab都是函数hello中的局部变量,因此当此函数返回时它们将被销毁,并且以相反的构造顺序销毁,因此a被破坏后,b将被销毁。

可能发生内存异常,因为两个变量(ab)都指向相同的内存区域:事实上,函数Mat::operator IplImage 不会复制基础数据,但会为这些矩阵数据创建Mat标头。

因此,当IplImage析构函数试图销毁对象Mat时,专用于基础数据的内存部分已经被a解除分配。

答案 1 :(得分:0)

来自OpenCV doc

  

运算符为矩阵创建IplImage标头,而不复制基础数据。 您应该确保在使用IplImage标头时不会释放原始矩阵。

您可以将返回标头的引用传递给接受IplImage*的函数,如下面代码中的void foo(IplImage* img)

#include <opencv2\opencv.hpp>
using namespace cv;

void foo(IplImage* img)
{
    // Set to blue
    cvSet(img, Scalar(255,0,0));
}

int main()
{
    // Small green image
    Mat3b img(10, 10, Vec3b(0, 255, 0));

    {
        // Doesn't modify original image
        Mat mat = img.clone();
        IplImage ipl = mat;
        foo(&ipl);

        // ipl and mat are blue now
        // img is still green
    }

    {
        // Modify original image
        IplImage ipl = img;
        foo(&ipl);

        // ipl and img are blue now
    }

    // img is blue

    return 0;
}