使用 Windows Form 的 OpenCV 不断抛出有关堆栈溢出的异常

OpenCV using Windows Form keeps on throwing exceptions about stack overflowing

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

我的故障排除猜测如下:

  1. picturebox中的图片占用资源,程序退出时不清除
  2. 后台还在忙

这是我的代码,在此先感谢!


Elements

Picturebox called videobox
Button called btnOpenCamera_Click
Button called btnCloseCamera_Click
Label called backgroundworkerStatus


Variables

Global

Mat videoFrame;
VideoCapture video(0);

Private

bool flag_cameraStatus = true;
bool flag_backgroundworkerStatus = false;


Functions

private: System::Void MainForm_FormClosing

// this event is triggered when application is closing

video.release();

/* Exception is thrown here "System.WhosebugException" */
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

为了解决这个问题,给 DoWork 添加延迟

私人:System::Void backgroundWorker1_DoWork

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

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