【问题标题】:cv::connectedComponentsWithStats in OpenCV 3.2.0 sometimes crashes with gcc 6.2OpenCV 3.2.0 中的 cv::connectedComponentsWithStats 有时会在 gcc 6.2 中崩溃
【发布时间】:2017-02-15 22:36:10
【问题描述】:

使用这个简单的独立演示:

#include <opencv2/opencv.hpp>

#include <iostream>

int main(int argc, char *argv[]) {
  // unsigned char data[] = {1, 0, 1}; // crashes
  unsigned char data[] = {1, 1, 0}; // does not crash

  cv::Mat1b testImage = cv::Mat1b(3, 1, data);

  cv::Mat labeledImage;
  cv::Mat stats;
  cv::Mat centroids;
  int neighborhood = 8;

  int componentCount = cv::connectedComponentsWithStats(
      testImage, labeledImage, stats, centroids, neighborhood);

  std::cout << "componentCount: " << componentCount << std::endl;

  return EXIT_SUCCESS;
}

使用 gcc 5.4 它适用于两个“数据”值。使用 gcc 6.2,它适用于 {1,1,0},但使用 data = {1,0,0} 转储它:

======= Memory map: ========
00400000-00407000 r-xp 00000000 08:01 15214967                           /home/doria/build/Examples/c++/OpenCV/Bug/Bug
00606000-00607000 rw-p 00006000 08:01 15214967                           /home/doria/build/Examples/c++/OpenCV/Bug/Bug
020b2000-0216c000 rw-p 00000000 00:00 0                                  [heap]
7f2608000000-7f2608021000 rw-p 00000000 00:00 0 
7f2608021000-7f260c000000 ---p 00000000 00:00 0 
7f260cc1d000-7f260cc24000 r-xp 00000000 08:01 10883576                   /lib/x86_64-linux-gnu/librt-2.23.so
7f260cc24000-7f260ce23000 ---p 00007000 08:01 10883576                   /lib/x86_64-linux-gnu/librt-2.23.so
7f260ce23000-7f260ce24000 r--p 00006000 08:01 10883576                   /lib/x86_64-linux-gnu/librt-2.23.so
7f260ce24000-7f260ce25000 rw-p 00007000 08:01 10883576                   /lib/x86_64-linux-gnu/librt-2.23.so
7f260ce25000-7f260ce28000 r-xp 00000000 08:01 10883446                   /lib/x86_64-linux-gnu/libdl-2.23.so

有什么想法吗?

【问题讨论】:

  • 嗨大卫!我想我发现了这个错误。我会给算法的作者发一封电子邮件,看看他是否有进一步的见解

标签: c++ opencv opencv3.0


【解决方案1】:

我对这个错误负责……叹息。

问题在于该算法在图像上以 2x2 块的形式工作。标签的最大数量是每个块一个。不幸的是,如果图像具有奇数行和/或列数,则块数的估计是错误的。所以要解决这个问题,我们应该这样做:

const size_t Plength = ((img.rows + 1) / 2) * ((img.cols + 1) / 2);

我们今天将为此向 OpenCV 提交拉取请求。加上一组改进的测试。顺便说一句,我们仍在等待包含算法的并行版本(多核)。 我们已经在 11 月提交了pull request 用于该算法的并行版本(多核),该算法也修复了该错误。

您可以在 OpenCV 3.3 中找到自 2017 年 6 月以来的固定版本。此外,它还包括并行版本。

【讨论】:

    【解决方案2】:

    我可以使用 Visual Studio 2015 (vc14 x64) 重现此错误。

    问题似乎在352 of connectedcomponents.cpp

     //A quick and dirty upper bound for the maximimum number of labels.
     const size_t Plength = img.rows*img.cols / 4;
     LabelT *P = (LabelT *)fastMalloc(sizeof(LabelT)* Plength);
    

    使用您的测试图像,此 PLength 的计算结果为 0

     Plength = (3*1)/4 = 0
    

    所以*P 有零个元素。

    但是,算法中的几个地方有这样的赋值:

     P[lunique] = lunique;
    

    lunique 的值为&gt;0。所以这会导致堆损坏有时

    解决方法应该是提供对上限Plength 的更好估计。

    【讨论】:

    • 我希望我能给 +5 :) 今天这引起了严重的头痛。
    • 我同时使用了电栅栏和 valgrind(一次一个),实际上两者都没有在我表示为“崩溃”的情况下崩溃。否则你会如何追踪这样的事情?
    • @David 我想视觉工作室调试器做得很好。崩溃位于PfastFree 附近,因此很清楚要寻找什么
    猜你喜欢
    • 1970-01-01
    • 2012-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-04
    相关资源
    最近更新 更多