2012-04-17 110 views
3

我有下面的图片,并尝试找到OpenCV的最大的矩形这些线路findContours使内存堆错误

std::vector< std::vector<cv::Point> > contours; 
cv::findContours(result,contours,CV_RETR_LIST,CV_CHAIN_APPROX_SIMPLE); 

但上述原因内存堆错误的语句。任何人都可以给我一个线索为什么发生这种情况?过去几个小时我一直在伸展头发。

我认为这是与cv :: Point分配器有关,因为调用堆栈指示它。

更新:我刚刚用CvFindContours运行该程序,而没有任何问题。所以它必须是OpenCV 2.3.1。

Update2:感谢@karlphillip答案,我重新审视了我的项目,这是我的Visual Studio项目设置。由于恼人的memork泄漏消息,我将MFC作为静态库链接。这是问题的原因。当我使用MFC作为共享DLL时,问题就消失了。

enter image description here

+0

什么操作系统是什么? Linux呢?视窗?你能提供一个最小的应用程序来重现问题吗?这两行似乎不是错误的原因。 – karlphillip 2012-04-18 12:59:27

+0

@karlphillip这是Windows 7 64位。你是对的。对不起,我的懒惰。我会尝试想出一个方法来制作一个小测试应用程序。 – 2012-04-18 14:07:33

回答

2

我刚刚测试the following application与Linux和Windows XP(32位)和我的OpenCV 2.3.1没有任何问题。

除非您可以编写一个最小的应用程序来重现您正在观察的问题,否则这就像我一样。

这是input image,而且代码的正下方:

#include <cv.h> 
#include <highgui.h> 

using namespace cv; 

double angle(cv::Point pt1, cv::Point pt2, cv::Point pt0) 
{ 
    double dx1 = pt1.x - pt0.x; 
    double dy1 = pt1.y - pt0.y; 
    double dx2 = pt2.x - pt0.x; 
    double dy2 = pt2.y - pt0.y; 
    return (dx1*dx2 + dy1*dy2)/sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) + 1e-10); 
} 


void find_squares(Mat& image, vector<vector<Point> >& squares) 
{ 
    // blur will enhance edge detection 
    Mat blurred(image); 
    medianBlur(image, blurred, 9); 

    Mat gray0(blurred.size(), CV_8U), gray; 
    vector<vector<Point> > contours; 

    // find squares in every color plane of the image 
    for (int c = 0; c < 3; c++) 
    { 
     int ch[] = {c, 0}; 
     mixChannels(&blurred, 1, &gray0, 1, ch, 1); 

     // try several threshold levels 
     const int threshold_level = 2; 
     for (int l = 0; l < threshold_level; l++) 
     { 
      // Use Canny instead of zero threshold level! 
      // Canny helps to catch squares with gradient shading 
      if (l == 0) 
      { 
       Canny(gray0, gray, 10, 20, 3); // 

       // Dilate helps to remove potential holes between edge segments 
       dilate(gray, gray, Mat(), Point(-1,-1)); 
      } 
      else 
      { 
        gray = gray0 >= (l+1) * 255/threshold_level; 
      } 

      // Find contours and store them in a list 
      findContours(gray, contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE); 

      // Test contours 
      vector<Point> approx; 
      for (size_t i = 0; i < contours.size(); i++) 
      { 
        // approximate contour with accuracy proportional 
        // to the contour perimeter 
        approxPolyDP(Mat(contours[i]), approx, arcLength(Mat(contours[i]), true)*0.02, true); 

        // Note: absolute value of an area is used because 
        // area may be positive or negative - in accordance with the 
        // contour orientation 
        if (approx.size() == 4 && 
          fabs(contourArea(Mat(approx))) > 1000 && 
          isContourConvex(Mat(approx))) 
        { 
          double maxCosine = 0; 

          for (int j = 2; j < 5; j++) 
          { 
            double cosine = fabs(angle(approx[j%4], approx[j-2], approx[j-1])); 
            maxCosine = MAX(maxCosine, cosine); 
          } 

          if (maxCosine < 0.3) 
            squares.push_back(approx); 
        } 
      } 
     } 
    } 
} 

int main() 
{  
    Mat img = imread("paper.jpg"); 

    vector<vector<Point> > squares; 
    find_squares(img, squares); 

    std::cout << "squares size: " << squares.size() << std::endl; 
    getchar(); 

    return 0; 
} 
+0

它也适用于我。所以是我。如果可以的话,我想给你1000分。非常感谢。 – 2012-04-18 14:22:15

+1

你的答案不是解决方案,但帮助我找到一个。这就是我接受你的答案的原因。 – 2012-04-18 14:50:16