opencv库损坏的双链表

时间:2014-04-03 15:24:40

标签: c++ qt opencv

您好我写了这个简单的程序

Main.cpp的

std::vector<cv::Mat> PD_Classifier_VEC;
#define Folder_Address ""
int Main()
{
        int overall_counter=0;

        for(int j = 0 ; j < 600 ; j++)
          {
               QString address = Folder_Address + QString::number(overall_counter++) +".jpg";
               cv::Mat image = cv::imread(address.toUtf8().constData(),0);
               PD_Classifier_VEC.push_back(image);
               PD();
          }
}

PD功能

void PD()
{
            static int Total_Frame_Number=0;
            Total_Frame_Number++;
            cv::Mat Point_MAT = cv::Mat(PD_Classifier_VEC[0].size(),CV_8UC1,cv::Scalar::all(0)); 

   ....//Some Calculation //

       PD_Classifier_VEC[0].release();
       PD_Classifier_VEC.erase(PD_Classifier_VEC.begin());

}

此代码正常工作直到j = 56,之后Qt显示此错误并退出!!!

*** Error in `/home/parsa/QtProjects/QtVLPR/QtVLPR': corrupted double-linked list: 0x0000000000dcf880 ***

我在调试器模式下运行代码并将此if语句代码添加到PD()函数:

void PD()
{
            static int Total_Frame_Number=0;
            Total_Frame_Number++;
            cv::Mat Point_MAT = cv::Mat(PD_Classifier_VEC[0].size(),CV_8UC1,cv::Scalar::all(0)); 

   ....//Some Calculation //

        if(Total_Frame_Number==56)
        {
        std::cout<<Point_MAT<<"\n";            //it displays the elements perfectly
        int Nonz = cv::countNonZero(Point_MAT);  //it runs too
        cv::imshow("Point_MAT",Point_MAT);          //here the error appears !!!
        cv::waitKey();
        }
       PD_Classifier_VEC[0].release();
       PD_Classifier_VEC.erase(PD_Classifier_VEC.begin());

}

正如您所看到的,前两行上面提供的注释工作正常,但是当我尝试使用imshow显示图像时,程序崩溃并显示损坏的双链表错误!这有什么不对?

为什么我无法显示此图像,如果POINT_MAT图像损坏,前两行如何正常工作?

P.S 如果我从j = 57启动程序,它可以正常工作直到它完成并且没有错误出现,所以

//some calculation 

代码工作正常,我很确定。

我已经测试了许多其他功能,例如阈值,减法和...,它们可以处理图像的数据部分并且它们工作正常但是当我添加一个处理元数据+数据部分的函数时,会出现损坏的双链表再次!!!

cv::subtract(Point_MAT,Point_MAT,temp); //works fine because it only works on data part
Point_MAT.copyTo(Temp_MAT); //gives error cause it works on header part too ...

1 个答案:

答案 0 :(得分:0)

错误来自标准C库,表示您已损坏堆。

具体而言,除非您在自己的代码中匹配release(),否则不应在Cv::mat上致电addref()Cv::mat的行为类似于Qt中常见的隐式共享值(比如说QImage),您不必担心手动管理其引用计数。

明显的建议是删除“某些计算”部分。对于更多图像,您显示的代码应该可以工作(没有release())而无需计算。

将您显示的代码转换为单独的单个文件项目,并确保它运行 - 因为它应该。然后错误仅限于您的计算 - 事实上它只在您进行计算时表现出来,这是计算问题的症状。

也许计算分配内存?

下面是一个工作的,自包含的示例,它演示了所显示的代码不仅正常,但即使您一次在内存中存储了一百个图像,一切都能正常工作。图像大小各为2MB。

#include <QImage>
#include <QTemporaryFile>
#include <QDebug>
#include <vector>
#include <opencv2/opencv.hpp>

std::vector<cv::Mat> PD_Classifier_VEC;

void PD()
{
  cv::Mat Point_MAT = cv::Mat(PD_Classifier_VEC[0].size(),CV_8UC1,cv::Scalar::all(0));

  //Some Calculation //

  std::stringstream stream;
  stream<<Point_MAT<<"\n";
  int Nonz = cv::countNonZero(Point_MAT);
  cv::imshow("Point_MAT",Point_MAT);

  PD_Classifier_VEC.erase(PD_Classifier_VEC.begin());
}

int main()
{
  QTemporaryFile file;
  file.setFileTemplate(file.fileTemplate() + ".jpg");

  const int N = 100;
  for(int j = 0 ; j < N ; j++)
  {
    file.open();
    QImage img(800, 600, QImage::Format_RGB32);
    img.save(&file);
    file.close();
    QString address = file.fileName();
    cv::Mat image = cv::imread(address.toStdString(),0);
    PD_Classifier_VEC.push_back(image);
  }
  while (!PD_Classifier_VEC.empty()) PD();
  cv::waitKey();
  return 0;
}