OpenCV:对齐多个图像时内存损坏

时间:2015-04-23 21:49:12

标签: opencv memory

我正在处理图像对齐问题。

我从一台相机拍摄了几张照片(每幅480x640张)。这些图像形成一个圆柱面,每对调整后的图像共享几个相似的列,以帮助将所有图像对齐成全景图像。

开始时,我假设每对之间没有旋转或缩放/缩放,所以我只计算两幅图像之间的偏移矢量而不是层析成像矩阵。

我的代码是:

//Store all images into a cv::Mat vector
std::vector<cv::Mat> image = ...
//Create a result Mat and set its content using the first image
cv::Mat result = image[0];

for (int i = 1; i < image.size(); i++) {
    //calculate the shift vector(image[i]-result) based on feature points using SURF.
    //this function works correctly and matched_diff[0] is det_x, and matched_diff[1] is det_y
    std::vector<int> matched_diff= surfMatch (result,image[i]);

    //Create a new Mat with size after combination
    cv::Mat temp(image[i].rows+abs(matched_diff[1]),image[i].cols+abs(matched_diff[0]),CV_8UC3);

    // Copy old result to its new position in temp
    // Copy image[i] to its new position in temp
    // Calculate pixel value of mixed range and copy them to their positions in temp
    ...

    //store the new result and go back to the first step
    result = temp.clone();
}

每次组合后,det_x将增加约300px,当然程序需要更多时间才能完成下一次组合。

当我使用两个或三个图像测试时,代码效果很好。

但是在正确组合了几张图像(大约14张)后,程序崩溃了,错误:

  

malloc():内存损坏:0x0000000000cdae50 ***

我使用GDB检查内存问题发生的位置,但它告诉我result = temp.clone();引起的问题。

我认为原因是经过多次组合后,图像(Mat)变得非常大,需要更多内存来创建temp,这会导致内存损坏错误。

我的问题是,根据我对OpenCV的理解,temp对象将在每个for循环后被解构。崩溃时,下一个temp大小应为3000px * 640px。所以它需要的总内存是3000 * 640 * 3Byte = 5.5Kb。 (对于cv :: Vec3b,每个像素需要3个8位来存储它的R G B值。),但是GDB说它需要更多来克隆它。

因此,我真的想知道我的理解是否有任何不妥之处,我怎样才能确定是否是我自己的错误是内存问题?

谢谢!

2 个答案:

答案 0 :(得分:2)

您可能正在耗尽RAM内存

调整图像大小以使其大小为原始大小的一半,然后重试。如果失败,将其大小减少一半。重复此过程直到成功。

如果没有,问题可能是其他问题,您必须共享MCVE (Minimal, Complete, and Verifiable example)才能获得更多帮助。

答案 1 :(得分:0)

如果有人和我有同样的情况,我想更新我找到的解决方案。

我按照@karlphillip的建议,将图像尺寸更改为原始图像的1/4。然后我的程序运行得更快,内存更少。所以在这种情况下我很容易调试。

当您在内存的不存在部分中复制或分配值时,总会发生内存损坏。

在图像对齐问题中,两个图像之间有四个相关位置。

-----              -----         -----                 ----- 
| A |              | A |         | B |                 | B |
---------      ---------         ---------         ---------
    | B |      | B |                 | A |         | A |
    -----      -----                 -----         -----

我们可以根据相关位置轻松确定detRow和detCol应该是正面的还是负面的。

然后我们可以计算出合并后新图像的大小。

然而,实际上还有8个案例容易被忽略。

您应确定A和B之间的大小关系。即新图像的行/列不应小于A和B的行/列。或者您将数据复制到Mat的位置,这会导致内存问题。