opencv库的双向链表已损坏

rn0zuynd  于 2023-02-05  发布在  其他
关注(0)|答案(2)|浏览(165)

嗨我写了一个简单的程序
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显示图像时,程序崩溃了,显示了corrupted double linked list错误!
为什么我不能显示这个图像,如果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 ...
5jvtdoz2

5jvtdoz21#

这个错误来自标准的C库,表明您已经损坏了堆。
具体来说,除非在 * 您自己的代码 * 中有匹配的addref(),否则不应该在Cv::mat上调用release()Cv::mat的行为类似于Qt中常见的隐式共享值(例如QImage),您不应该担心手动管理它的引用计数。
显而易见的建议是删除“一些计算”部分。对于更多的图像,你显示的代码 as is 应该可以在没有计算的情况下工作(没有release())。
将您显示的代码转换为单独的单个文件项目,并确保它可以运行-因为它应该运行。然后,错误仅限于您的计算-只有当您进行计算时,错误才会显现出来,这是计算问题的症状。
也许是计算分配了内存?
下面是一个运行良好的自包含示例,它演示了所示代码不仅正常,而且即使您一次在内存中存储100张图像,所有内容也都正常。

#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;
}
noj0wjuj

noj0wjuj2#

库巴的回答很好地描述了潜在的问题。
在我的例子中,我传递了一个cv::Mat作为函数的参数给图像,但是当主线程访问这个垫子时,接收图像的工作线程已经删除了它。
解决方案是通过垫子的克隆。

...
    cv::Mat const img = recordImage();
    myWindow->setImage(img);
} // end of function, img will get deleted
...
    cv::Mat const img = recordImage();
    myWindow->setImage(img.clone());
} // img will get deleted, but the clone will persist

相关问题