我的 Qt C++ 程序以不寻常的方式终止

Posted

技术标签:

【中文标题】我的 Qt C++ 程序以不寻常的方式终止【英文标题】:My Qt C++ program terminates in an unusual way 【发布时间】:2015-03-29 12:12:19 【问题描述】:

我有一个包含 2 个主要按钮的 gui 应用程序,第一个按钮帮助用户选择 10 个图像并将它们保存在一个 Mat 数组中。第二个按钮用于背景减法和绘制边界矩形。当我第一次运行该程序时,它运行良好。但是当我再次单击第一个按钮并选择其他图像并尝试使用第二个按钮处理它们时,有时它工作正常但有时我的程序以不寻常的方式终止,而控制台中没有任何错误消息(只有这个:退出代码 255。)。 这是我的代码:

void Principale::chooseImages_clicked()

    QFileDialog* _f_dlg = new QFileDialog(this);
  _f_dlg->setFileMode(QFileDialog::ExistingFiles);
  _f_dlg->setOption(QFileDialog::DontUseNativeDialog, true);

  QListView *l = _f_dlg->findChild<QListView*>("listView");
  if (l) 
    l->setSelectionMode(QAbstractItemView::MultiSelection);
   
  QTreeView *t = _f_dlg->findChild<QTreeView*>();
   if (t) 
     t->setSelectionMode(QAbstractItemView::MultiSelection);
    

  _f_dlg->exec();
  _fnames = _f_dlg->selectedFiles();
  if(_fnames.size()!=10)
      QMessageBox::information(this, "Error!","choose 10 images!");

  else
  
      image_choosed=true;
      for(int i=0;i<10;i++)
          Tab_IMG[i]=imread(_fnames.at(i).toStdString(),CV_16UC1);

      Entree entree;
      entree.setModal(true);
      entree.exec();
  

void Principale::on_processing_clicked()

    if(!image_choosed)
        QMessageBox::information(this, "error!","choose 10 images!");
    else
    
        chut=0;
        Mat BG; double moyenne=0;
        char chaine[20]="";int j=1;
        //Mat Subs;
        Vec3b couleur_dst,couleur_FG,couleur_sortie;
        for(int i=1;i<10;i++)
        
            BG=imread(_fnames.first().toStdString(),CV_16UC1);


// background substraction

                Mat Subs(480, 640, CV_16UC1);
                absdiff(Tab_IMG[i],BG,Subs);
                BG.convertTo(BG,CV_8UC1,1.0/255.0);
                Tab_IMG[i].convertTo(Tab_IMG[i],CV_8UC1,1.0/255.0);
                Subs.convertTo(Subs,CV_8UC1);
                threshold(Subs,Subs,25, 255,THRESH_BINARY);
                Mat ones(3,3,CV_8UC1);
                morphologyEx(Subs,Subs,MORPH_OPEN,ones,Point(1,-1),1); // try 2 instead of 1
                erode(Subs,Subs,ones,Point(1,-1),1);

//--------------------- bounding rectangle 


            Rect bounding_rect;
            int largest_area=0;
            int largest_contour_index=0;
            Mat dst(Subs.rows,Subs.cols,CV_8UC1,Scalar::all(0));
            Mat thr=Subs;
            vector<vector<Point> > contours;
            vector<Vec4i> hierarchy;
            findContours( thr, contours, hierarchy,CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );
            for( int k = 0; k< contours.size(); k++ )
            
                double a=contourArea( contours[k],false);
                if(a>largest_area)
                
                   largest_area=a;
                   largest_contour_index=k;
                   bounding_rect=boundingRect(contours[k]);
                
            

            Scalar color( 255,255,255);
            drawContours( dst, contours,largest_contour_index, color, CV_FILLED, 8, hierarchy );
            rectangle(dst, bounding_rect,Scalar(255,0,0),2, 8,0);
            int compteur=0; double moyenne=0;  int seuille=255; double depth;
            Mat sortie(Tab_IMG[i].rows,Tab_IMG[i].cols,CV_8UC1);
            sortie.setTo(0);
            Vec3b couleur_dst,couleur_FG,couleur_sortie;
            for(int x=0;x<dst.cols;x++)
            
                for(int y=0;y<dst.rows;y++)
                
                    couleur_dst= dst.at<Vec3b>(Point(x,y));
                    couleur_FG=Tab_IMG[i].at<Vec3b>(Point(x,y));
                    if((couleur_dst.val[0]==255)&&(couleur_dst.val[1]==255)&&(couleur_dst.val[2]==255))
                    
                        sortie.at<Vec3b>(Point(x,y)) = couleur_FG;
                        seuille=couleur_FG.val[0];
                        depth=(3640*couleur_FG.val[0])/255;
                        moyenne+=depth;
                        compteur++;
                    
                 
             
             moyenne=moyenne/compteur;
             Tab_dist[i]=moyenne;
             Tab_silh[i]=sortie;
             Tab_rect[i]=bounding_rect;
             Tab_surf[i]=bounding_rect.width*bounding_rect.height;
             if(i==1)
                  surf_one=Tab_surf[i];
             else
                  moy_dif_surf+=Tab_surf[i]-surf_one;
            Tab_rect[i]=bounding_rect;

         Tab_silh[0]=imread("C:\\Users\\Eden\\Desktop\\Images\\noire.png",CV_16UC1);
        /*Sortie sortie;
        sortie.setModal(true);
        sortie.exec();*/
    



【问题讨论】:

问题不在于背景减法,因为我试图删除它下面的代码,无论我点击这两个按钮多少次,程序都可以正常工作,我认为问题在于边界矩形代码.请帮我检测一下:) 你确定 moyenne=moyenne/compteur 中的 compteur > 0? 你真的应该使用调试器。 Qt-Creator 内置了一个。您可以在 creator 中打开您的 pro 文件并使用开始调试按钮来深入了解程序终止的原因 是的,因为我初始化它(int compteur=0;)然后在(if 条件)内递增它 "控制台中没有任何错误消息" 是的,OpenCV 错误“内存不足”和抛出的异常可能只是娱乐性的,与您的问题完全无关。 ;-) 【参考方案1】:

(Answer moved from comments to a community wiki.)

OP 写道:

问题出在这条指令sortie.at&lt;Vec3b&gt;(Point(x,y)) = couleur_FG; 中,正是当我尝试以Vec3b 访问像素时,这是不正确的,因为图像被定义为单通道图像。解决方案是使用uchar 而不是Vec3b

【讨论】:

以上是关于我的 Qt C++ 程序以不寻常的方式终止的主要内容,如果未能解决你的问题,请参考以下文章

此应用程序已请求运行时以不寻常的方式终止它[重复]

OpenCV、Python 和 C++:应用程序请求运行时以异常方式终止

具有 char 数组的 C++ 结构以不寻常的方式初始化为零

Flutter 应用重新打开后以不寻常的方式启动

Java中以不寻常方式定义的对象回调

每当导入 Cython 模块时,Python 程序 abort()-ed 在正常退出时