【问题标题】:Why is Loading from an XML File in OpenCV Corrupting my Data?为什么从 OpenCV 中的 XML 文件加载会损坏我的数据?
【发布时间】:2015-11-08 04:26:29
【问题描述】:

我似乎遇到的问题是,当我加载存储为 xml 文件的 IplImgaes 时,与 IplImage 对象关联的一些数据成员已损坏。例如,d1->width 应该是 1024,d1->height 应该是 768。相反,似乎无论我加载这些图像的方式如何,我都会得到像 -72538984、-1272467456 和 0 这样的垃圾值。我也有测试了包含类似垃圾值的 d1->depth 和 d1->nChannels。我正在使用 OpenCV C API xml 持久性在磁盘中写入和读取这些图像。我已阅读并重新阅读相关文档以确保我正确使用 API,但似乎无论我如何阅读图像,仍然存在某种形式的数据丢失或损坏。

我使用 xml 持久性的原因是当我在获取图像的程序中使用函数 cvSaveImage 时,该函数会将数据从 16 位格式截断为 8 位格式。我的理解是使用 xml 持久化可以避免这个问题。另外,我试图避免在这个项目中使用 C++ API,因为它是之前已经使用 C API 编写的工作的扩展。根据我在下面包含的代码,我能否确定我正确地执行了这部分,并且问题出在图像创建、存储、检索和使用过程中的其他地方?还是我在这里做的事情显然是错误的?非常感谢您的帮助。

方法 1

CvFileStorage * fs1 = cvOpenFileStorage("/home/bot/luca-HSV/HSVD/GRID1/SQUARE4/DEPTH180.xml", 0, CV_STORAGE_READ); 
CvFileStorage * fs2 = cvOpenFileStorage("/home/bot/luca-HSV/HSVD/GRID1/SQUARE4/DEPTH144.xml", 0, CV_STORAGE_READ);

d1 = (IplImage*) cvReadByName(fs1, 0, "depthImage");
d2 = (IplImage*) cvReadByName(fs2, 0, "depthImage");

cvReleaseFileStorage(&fs1);
cvReleaseFileStorage(&fs2);

方法 2

CvFileStorage * fs1 = cvOpenFileStorage("/home/bot/luca-HSV/HSVD/GRID1/SQUARE4/DEPTH180.xml", 0, CV_STORAGE_READ); 
CvFileStorage * fs2 = cvOpenFileStorage("/home/bot/luca-HSV/HSVD/GRID1/SQUARE4/DEPTH144.xml", 0, CV_STORAGE_READ);

CvFileNode * node1 = cvGetFileNodeByName(fs1, 0, "depthImage");
CvFileNode * node2 = cvGetFileNodeByName(fs2, 0, "depthImage");

d1 = (IplImage*) cvRead(fs1, node1);
d2 = (IplImage*) cvRead(fs2, node2);

cvReleaseFileStorage(&fs1);
cvReleaseFileStorage(&fs2);

方法 3

d1 = (IplImage*) cvLoad("/home/bot/luca-HSV/HSVD/GRID1/SQUARE4/DEPTH180.xml"/*, NULL, NULL, NULL*/);
d2 = (IplImage*) cvLoad("/home/bot/luca-HSV/HSVD/GRID1/SQUARE4/DEPTH144.xml"/*, NULL, NULL, NULL*/);
// I have tried both using and not using these three NULL parameters. It
// does not seem to make a lot of difference

在所有这些方法之前,我包括以下几行:

IplImage * d1 = cvCreateImage(cvSize(IMG_WIDTH, IMG_HEIGHT), IPL_DEPTH_64F, 3);
IplImage * d2 = cvCreateImage(cvSize(IMG_WIDTH, IMG_HEIGHT), IPL_DEPTH_64F, 3);

示例 XML 文件标题

<?xml version="1.0"?>
<opencv_storage>
<depthImage type_id="opencv-matrix">
  <rows>768</rows>
  <cols>1024</cols>
  <dt>"3d"</dt>
  <data> 

【问题讨论】:

  • 我相信 C++ API 的 imwrite 函数只允许 16 位无符号,我需要能够保持负值。
  • 有人能解释一下为什么我的问题被否决了吗?我从我能想到的问题的各个角度提供了详尽的细节,而不包括一堆不必要的代码。问题的第一行也清楚地说明了核心问题,下面提供了相关细节。这个问题怎么不清楚或没有很好的研究?
  • 我同意,这个问题很好地提出:+1。看看答案,看看它是否适合你。

标签: c xml image opencv


【解决方案1】:

在您的 xml 文件中,您保存了 CvMat (type_id="opencv-matrix"),而不是 IplImage (type_id="opencv-image")。

所以当你加载它时,你应该转换为CvMat*,否则你会得到垃圾值。

例如,这将起作用:

CvFileStorage* fs = cvOpenFileStorage("path_to_xml", 0, CV_STORAGE_READ);
CvMat* img = (CvMat*)cvReadByName(fs, NULL, "depthImage", NULL);
cvReleaseFileStorage(&fs);

【讨论】:

  • 感谢您的帮助,但实际上我几分钟前才弄清楚。我(有点尴尬)在生成图像的程序中混合了 C++ 和 C API 调用。您的解决方案可能也很有效,因为使用 C++ API 调用编写结构似乎与 IplImage 类型不完全兼容,因为它使用 type_id="opencv-matrix" 保存文件。现在是“opencv-image”。我猜他们真的希望人们切换到新版本。真的,非常感谢!
  • 很高兴你成功了。 C api 已弃用,如果你能切换到 C++,那就更好了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-10
  • 2011-01-29
  • 2012-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多