首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >无法访问IplImage数据

无法访问IplImage数据
EN

Stack Overflow用户
提问于 2013-01-31 15:51:32
回答 1查看 723关注 0票数 1

我一直在尝试比较我的IplImage对象中的数据内容。

我有以下几点:

代码语言:javascript
运行
复制
   IplImage img1 = IplImage(cv::imread("C:\\TestIm\\barrier_snapshot1.png"),            
                                                   CV_LOAD_IMAGE_GRAYSCALE);
   for (int i=0; i < img1.widthStep * img1.height; i++) {
       cout << img1.imageData[i] << endl;
   }

但是当我试图打印它时,它会导致异常,我甚至无法捕捉到它来打印消息并查看我做错了什么。我的图像是灰度,我相信如果我不使用cvCreateImage(),它是可以的吗?我知道这将是一些愚蠢或与数组访问相关的事情,我似乎无法从IplImage文档中轻松获得。

*为什么在我的设计中我会费心地混合C和C++代码?*

不幸的是,我别无选择!我正在致力于一个项目,是与改进的运动检测应用程序。我的遗留应用程序源代码使用了大量的BOOST和OpenCV之类的东西。特别是,它使用IplImage* (我讨厌它,使生活很困难,并导致内存泄漏)来存储诸如图像掩码之类的东西。我知道,如果我保存IplImage*在长期内,我将有非法的引用和访问违规。因此,我保存了IplImage*所指向的实际内容的副本。举例说明:

代码语言:javascript
运行
复制
// getLongHistory() returns IplImage*
IplImage history_long = *(motionHistory.getLongHistory()); 

共有6个面具图像是使用IplImage*制作的。此时,我正在谴责在IplImage*中决定这么做的程序员。当我试图加载那些掩码图像时,问题就出现了,我就是这样做的:

代码语言:javascript
运行
复制
// Passing pointer to the address of the mask stored (alive in the memory)
motionHistory.setLongHistory(&(matcher.getCurrentSceneObject().getLongHistory()));

我相信我在IplImage对象的深拷贝和浅拷贝方面有问题。我相信将其保存为从IplImage*保存为cv::Mat,并将其作为IplImage*从cv::Mat加载可能会减轻负担,因为我怀疑它可能会在高级别函数下执行操作,以便对数据和ROI进行相应的复制。但是,作为一名纽比人,我可以假设任何事情。请帮帮我!

更新

在我的代码中,我过去是这样做的:

代码语言:javascript
运行
复制
/* I store all my mask images in a vector of pairs made of <int, IplImage>
 * __MASK_LONG__ etc. are predefined intergers
 * getMaskLong() etc. methods return IplImage* to the respective mask images.
 */

  myImages.clear(); // To make sure that I have no extra stuff
  myImages.push_back(std::make_pair<int, IplImage>(_MASK_LONG_, maskHistory.getMaskLong()));
  myImages.push_back(std::make_pair<int, IplImage>(_MASK_SHORT_, maskHistory.getMaskShort()));

然而,在得到一些建议并做了一些基本的研发工作之后,我现在这样做是为了防止肤浅的复制:

代码语言:javascript
运行
复制
  myImages.clear(); 
  myImages.push_back(std::make_pair<int, IplImage>(_MASK_LONG_, *cvCloneImage(maskHistory.getMaskLong())));
  myImages.push_back(std::make_pair<int, IplImage>(_MASK_SHORT_, *cvCloneImage(maskHistory.getMaskShort())));

我可以确认这是可行的,因为我可以看到最新的面具图像加载到OpenCV窗口!我非常肯定,在任何编程任务中,至少做2/3次深度复制是多么重要。所以谢谢你让我走上正轨。但现在,我在实现这些更改时想到了一个问题--内存分配失败。并收到了这样的信息:

代码语言:javascript
运行
复制
OpenCV Error: Insufficient memory (Failed to allocate 3686404 bytes) in OutOfMemoryError, 
file /home/naresh/OpenCV-2.4.0/modules/core/src/alloc.cpp, line 52

如果我对C/C++有足够深入的了解,那么首先,我犯了把它们混合在一起的罪行(我别无选择!)它是一个遗留应用程序!)。其次,在alloc.cpp文件中存在一种不匹配,即对malloc/free的一组不正确的调用(产生问题的地方)。或者可能只是堆已经损坏或满了。我是不是太蠢了?

EN

回答 1

Stack Overflow用户

发布于 2013-01-31 18:22:33

不要将( OpenCV的C接口)与C++接口混合使用。

理想情况下,您应该使用独占的C++接口来解决这个问题,如下所示:

代码语言:javascript
运行
复制
cv::Mat gray = cv::imread("C:\\TestIm\\barrier_snapshot1.png", CV_LOAD_IMAGE_GRAYSCALE);

cv::Mat_<uchar>::iterator it = gray.begin<uchar>();
cv::Mat_<uchar>::iterator end = gray.end<uchar>();
for (; it != end; ++it)
{
    cout << *it << endl;        
}

或者:

代码语言:javascript
运行
复制
cv::Mat gray = cv::imread("C:\\TestIm\\barrier_snapshot1.png", CV_LOAD_IMAGE_GRAYSCALE);

for (int i = 0; i < gray.cols; i++)
{
    for (int j = 0; j < gray.rows; j++)
    {
        cout << gray[gray.cols * j + i] << endl;
    }
}

是的,cv::imread()也可以以灰度的形式加载输入图像。但是,如果您确实需要继续使用C接口,那么请删除cv::imread()并使用cvLoadImage()。有几个帖子解释如何做到这一点,使用搜索框。

如果您决定继续混合接口(请不要),check this thread,因为它解释了如何将IplImage*转换为cv::Mat

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14629719

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档