使用Windows窗体的OpenCV继续抛出有关堆栈溢出的异常

时间:2018-06-10 19:22:48

标签: opencv c++-cli windows-forms-designer

我一直在编写一个程序,每次关闭我的表单时都会抛出异常,说我的堆栈溢出了关闭后台工作程序的行...
我已经面对这个问题已经有一段时间了,我已经尝试了谷歌搜索问题,但我还没有找到任何想要的解决方案......

我的疑难解答猜测如下:

  1. 图片框中的图片占用资源,在中止程序时不会被清除
  2. 后台工作人员仍然忙着
  3. 这是我的代码,提前谢谢!

      

    元素

         

    Picturebox名为 videobox
      按钮名为 btnOpenCamera_Click
      按钮名为 btnCloseCamera_Click
      标签名为 backgroundworkerStatus


      

    变量

         

    全局

    Mat videoFrame;
    VideoCapture video(0);
    
         

    私人

    bool flag_cameraStatus = true;
    bool flag_backgroundworkerStatus = false;
    


      

    功能

         

    private:System :: Void MainForm_FormClosing

    // this event is triggered when application is closing
    
    video.release();
    
    /* Exception is thrown here "System.StackOverflowException" */
    backgroundWorker->CancelAsync();
    
    if (backgroundWorker->IsBusy == false) {
        checkBackgroundworkerStatus();
        this->Close();
    }
    else {
        MessageBox::Show("Backgroundworker not aborted");
        e->Cancel = true;
    }
    
         

    private:System :: Void btnOpenCamera_Click

    // this is a button for turning on camera
    
    flag_cameraStatus = true;
    backgroundWorker->RunWorkerAsync();
    
         

    private:System :: Void btnCloseCamera_Click

    // this is a button for turning off camera
    
    flag_cameraStatus = false;
    videoBox->Image = nullptr;
    
         

    int openCamera()

    // this is a button for turning off camera
    
    if (!video.isOpened()) {
        MessageBox::Show("Cannot Find Camera!");
        return -1;
    }
    
    while (flag_camera) {
    
      video >> videoFrame;
      if (videoFrame.empty()) {
            break;
      }
    
      /* These lines of code converts Opencv mat to bitmap for picturebox to display */
      System::Drawing::Graphics^ graphics = videoBox->CreateGraphics();
      System::IntPtr ptr(videoFrame.ptr());
      System::Drawing::Bitmap^ b = gcnew System::Drawing::Bitmap(videoFrame.cols, videoFrame.rows, videoFrame.step, System::Drawing::Imaging::PixelFormat::Format24bppRgb, ptr);
      System::Drawing::RectangleF rect(0, 0, videoBox->Width, videoBox->Height);
      graphics->DrawImage(b, rect);
    
      /* Was wondering if I need these lines of code below */
      /* delete graphics;                                  */
    
    if (flag_camera == false) {
        videoBox->Image = nullptr;
        return 0;
    }
    
         

    void checkBackgroundworkerStatus()

    // this function is used to check if backgroundworker is busy
    // it will identify the status via the backcolor of label backgroundworkerStatus
    
    if(backgroundWorker->IsBusy==true)
    backgroundworkerStatus->BackColor = Color::Green;
    else
    backgroundworkerStatus->BackColor = SystemColors::Control;
    
         

    private:System :: Void backgroundWorker_DoWork

    // this event is triggered when background worker is working
    
    if (backgroundWorker->CancellationPending == false) {
        checkBackgroundworkerStatus();
        openCamera();
    }
    else {
        this->backgroundWorker->CancelAsync();
    }
    
         

    private:System :: Void backgroundWorker_RunWorkerCompleted

    // this event is triggered when background worker is done working
    
    checkBackgroundworkerStatus();
    


    一些最后的注释......

    我确实设置了

    WorkerSupportsCancellation = true
    WorkerReportsProgress = true
    

1 个答案:

答案 0 :(得分:0)

要解决此问题,请向DoWork添加延迟

private:System :: Void backgroundWorker1_DoWork

  

using namespace System::Threading   
  /* your DoWork tasks */   
  Thread::Sleep(50)

注意
Thread :: Sleep以毫秒为单位计算,您可以根据相机fps更改为您想要的数字。 我的笔记本电脑摄像头约。 15帧/秒,每帧66.66毫秒,睡眠时间应该> =这个ms /帧,但我没有问题,运行它只有50毫秒的延迟。