OpenCV findContours - 2.4.5 Heap Corruption
OpenCV findContours - 2.4.5 Heap Corruption
我在findContours函数上100%确定发生堆损坏。当我不使用它时,一切都很好。
unsigned char* UCFromMatUC(cv::Mat& input)
{
int size = input.size.p[0] * input.size.p[1];
unsigned char* result = new unsigned char[size];
memcpy(result, input.data, size);
return result;
}
unsigned char* CannyEdgeCV(unsigned char* input, int width, int height)
{
std::vector<std::vector<cv::Point> > contours;
std::vector<cv::Vec4i> hierarchy;
cv::RNG rng(12345);
cv::Mat inp(cv::Size(width, height), CV_8UC1, input);
cv::Mat canny_output;
cv::Mat outp;
cv::blur(inp, outp, cv::Size(3,3));
cv::Canny(outp, canny_output, 4.0, 8.0);
if(canny_output.type()!=CV_8UC1){
return NULL;
}
cv::findContours( canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cv::Point(0, 0) );
cv::Mat drawing = cv::Mat::zeros( canny_output.size(), CV_8UC3 );
for( int i = 0; i< contours.size(); i++ )
{
cv::Scalar color = cv::Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
drawContours( drawing, contours, i, color, 2, 8, hierarchy, 0, cv::Point() );
}
cv::imwrite( "contours.jpg", drawing );
unsigned char* result = UCFromMatUC(canny_output);
return result;
}
最初我只使用精明的边缘地图,但后来我想测试轮廓功能的结果。
Canny Edge工作得很好,我得到了预期的图像,但是findContours(代码和注释版本)失败了堆损坏错误。是什么原因造成的?
此入口点是CannyEdgeCV(),并使用640x480的8bit灰度图像调用。
编辑:更新后的代码。
Edit2:当我试图创建一个最小的例子来复制这个,我的代码失败了,甚至imread("imagename.bmp");这真的很奇怪,所以我开始调查可能导致这种情况的原因。现在有人在相应的SO问题中写道,你不能混合调试/发布模式库,所以如果你在调试中,你必须使用调试dll,现在这对我有效,我得到了预期的结果。
主要原因是您使用了cv::Mat*
和new
。这是个坏主意。动态分配cv::Mat
对象是不必要的,而且经常会出现问题(正如您已经发现的那样)。一个更好的解决方案是通过值或const
引用传递它们,因为底层图像数据被重新计数,并且cv::Mat
被浅层复制。
第一个具体问题是您在CVMatFromUC()
中手动分配data
成员:
resultMat->data = input
你不应该这样做。cv::Mat
有其他成员也引用数据位置,你是在自找麻烦。如果您需要为外部数据创建一个cv::Mat
头,您应该创建一个cv::Mat
,如下所示:
cv::Mat inp(cv::Size(width, height), CV_8UC1, input); //Create cv::Mat header, no memory copied
另外,您对canny_output
的类型检查是不正确的。首先计算!canny_output.type()
,然后隐式地转换为true
, CV_8UC1
也是如此。所以表达式总是true
。您需要的条件是:canny_output.type() != CV_8UC1
鉴于此,CVMatFromUC()
函数是不必要的。函数的改进版本如下:
uchar* CannyEdgeCV(uchar* input, int width, int height)
{
std::vector<std::vector<cv::Point> > contours;
std::vector<cv::Vec4i> hierarchy;
cv::Mat inp(cv::Size(width, height), CV_8UC1, input); //Create cv::Mat header, no memory copied
cv::Mat canny_output;
cv::Mat outp;
cv::blur(inp, outp, cv::Size(3,3));
cv::Canny(outp, canny_output, 10.0, 15.0);
if(canny_output.type()!=CV_8UC1){
return NULL;
}
cv::findContours(canny_output, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE );
//cv::findContours( canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cv::Point(0, 0) );
unsigned char* result = UCFromMatUC(&inp);
return result;
}
我应该注意到,CannyEdgeCV
似乎返回了它接收到的相同数据,因此可以完全删除对UCFromMatUC()
的调用和相关的数据副本。但是,我尝试了一下,出现了内存错误,因此可能在其他地方潜伏着其他问题。
-如下所示更改findContoursfindContours(灰色,轮廓,CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);
-
如果它不工作了,你的问题可能是未初始化内存。你可以尝试创建一个新的Mat outP2,并将原来的Mat克隆到这个
-
然后从以下步骤使用outP2:
cv::Canny(*outP2, canny_output, 10.0, 15.0);…div…
- 为什么我的 heap.h 文件给我一个LNK2001错误?
- 当为可变性配置时,boost::heap::d_ary_heap 保留的额外 std::list 的目的是什么?
- 了解 Linux 虚拟内存:valgrind 的 massif 输出显示了有和没有 --pages-as-heap 的主要差异
- 逻辑'double free or corruption (fasttop)'错误
- emplace_back和push_back给出错误'double free or corruption (fasttop)'尽管定义了复制和移动构造函数
- 从 MSVC14 切换到 MSVC16 会导致"compiler is out of heap space (C1060)"错误
- 庞大的初始化列表,如何修复"fatal error C1060: compiler is out of heap space"
- C++ 调用析构函数后动态模板队列"double free or corruption (out)"
- 为什么这段代码会导致"heap corruption detected"?
- Windows heap corruption C++C
- Heap corruption after new char[strlen
- Corruption Of Heap
- 如何调试我的"heap corruption"?(C++)
- E_OUTOFMEMORY, Heap corruption
- OpenCV findContours - 2.4.5 Heap Corruption
- 释放内存时获得"Heap Corruption Detected: after Normal block"
- Heap corruption C++
- Convex hull & Heap corruption with openCV
- 为什么在这里返回一个 malloc'd 指针会导致免费"HEAP CORRUPTION"?
- C++ Heap Corruption