【问题标题】:Converting cv::Mat to IplImage*将 cv::Mat 转换为 IplImage*
【发布时间】:2011-06-07 13:02:42
【问题描述】:

这方面的文档似乎参差不齐。

我基本上有一个空的 IplImage*s (IplImage** imageArray) 数组,我正在调用一个函数来导入一个 cv::Mats 数组 - 我想将我的 cv::Mat 转换为 IplImage * 所以我可以将它复制到数组中。

目前我正在尝试这个:

while(loop over cv::Mat array)
{
    IplImage* xyz = &(IplImage(array[i]));
    cvCopy(iplimagearray[i], xyz);
}

这会产生段错误。

也在尝试:

while(loop over cv::Mat array)
{
    IplImage* xyz;
    xyz = &array[i];
    cvCopy(iplimagearray[i], xyz);
}

这给了我一个编译时错误: error: cannot convert ‘cv::Mat*’ to ‘IplImage*’ in assignment

不知道如何走得更远,希望得到一些建议:)

【问题讨论】:

  • OpenCV C++ and cvSmooth 的可能重复项
  • 更新:从 OpenCV 4 开始,IplImage 以及他们现在称为“遗留 C API”的所有内容将被逐步删除。在 OpenCV 4.0“alpha”中,IplImage 已经消失了 - CvMat 也是如此。

标签: c++ opencv


【解决方案1】:

cv::Mat 是 OpenCV2.X 中引入的新类型,而 IplImage* 是“传统”图像结构。

虽然cv::Mat确实支持在构造函数参数中使用IplImage,但默认库不提供其他方式的功能。您将需要手动提取图像标题信息。 (请记住,您需要分配 IplImage 结构,这在您的示例中是缺少的)。

【讨论】:

  • 它确实提供了到 IplImage 的转换,在不复制数据的情况下创建标题。所以IplImage* img = new IplImage(mat); 应该可以工作。
  • 实际上,您可以这样做:IplImage iplimg = mat;,只要在需要IplImage 的地方使用&iplimg。不需要动态分配。
  • @etarion IplImage 没有任何可以进行这种转换的函数。为什么 IplImage* img = new IplImage(mat) 有效?
  • @ajaxhe cv::Mat 有一个转换为 IplImage 的运算符。
  • 这个答案是错误的。查看其他答案,它可以很容易地转换,应该从接受的答案中删除,因为它可能会混淆其他用户。
【解决方案2】:
Mat image1;
IplImage* image2=cvCloneImage(&(IplImage)image1);

猜猜这会完成这项工作。

编辑:如果您遇到编译错误,请尝试以下方法:

cv::Mat image1;
IplImage* image2;
image2 = cvCreateImage(cvSize(image1.cols,image1.rows),8,3);
IplImage ipltemp=image1;
cvCopy(&ipltemp,image2);

【讨论】:

  • 你能解释一下这个 sn-p 吗?
  • @chepseskaf cast 语法显式转换。
  • @William:我在使用上述代码时收到获取临时地址警告
  • 这是一个次优的解决方案,因为您需要手动复制像素。
  • 您是否设法仅使用标题进行转换?此外,IplImage 已过时。如果您需要高效的代码,请改用cv::Mat
【解决方案3】:
 (you have cv::Mat old)
 IplImage copy = old;
 IplImage* new_image = ©

您使用 new 作为最初声明的 IplImage*。

【讨论】:

  • 这是最好的方法,它就像一个魅力!所有其他方法都太复杂了,这是最好的方法。为我工作
  • 第一行给出编译器错误“不存在从“cv::Mat”到“IplImage”的合适的用户定义转换”。
【解决方案4】:

这是针对 dlib 用户 link 的最新修复

cv::Mat img = ...
IplImage iplImage = cvIplImage(img);

【讨论】:

  • 这是唯一的解决方案,不会产生编译器错误。我用 opencv420+dlib-19.8 将它插入到我的项目中
【解决方案5】:

我个人认为这不是类型转换引起的问题,而是缓冲区溢出问题;就是这一行

cvCopy(iplimagearray[i], xyz);   

我认为会导致段错误,我建议你确认数组 iplimagearray[i] 有足够大小的缓冲区来接收复制的数据

【讨论】:

    【解决方案6】:

    根据 OpenCV cheat-sheet 这可以如下完成:

    IplImage* oldC0 = cvCreateImage(cvSize(320,240),16,1);
    Mat newC = cvarrToMat(oldC0);
    

    cv::cvarrToMat 函数负责处理转换问题。

    【讨论】:

    • 我认为 cvarrToMat 不再存在于 opencv 2.4.5
    【解决方案7】:

    如果是灰色图像,我正在使用此功能,它工作正常!但是您必须注意功能特性;)

    CvMat * src=  cvCreateMat(300,300,CV_32FC1);      
    IplImage *dist= cvCreateImage(cvGetSize(dist),IPL_DEPTH_32F,3);
    
    cvConvertScale(src, dist, 1, 0);
    

    【讨论】:

      【解决方案8】:

      一个问题可能是:在您的项目中使用外部 ipl 并定义 HAVE_IPL 时,ctor

      _IplImage::_IplImage(const cv::Mat& m)
      {
          CV_Assert( m.dims <= 2 );
          cvInitImageHeader(this, m.size(), cvIplDepth(m.flags), m.channels());
          cvSetData(this, m.data, (int)m.step[0]);
      }
      

      在 ../OpenCV/modules/core/src/matrix.cpp 中找到未使用/实例化且转换失败。

      你可以用类似的方式重新实现它:

      IplImage& FromMat(IplImage& img, const cv::Mat& m)
      {
          CV_Assert(m.dims <= 2);
          cvInitImageHeader(&img, m.size(), cvIplDepth(m.flags), m.channels());
          cvSetData(&img, m.data, (int)m.step[0]);
          return img;
      }
      
      IplImage img;
      FromMat(img,myMat);
      

      【讨论】:

        猜你喜欢
        • 2013-04-02
        • 2012-04-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-01-25
        • 2012-06-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多