使用 Windows Form 的 OpenCV 不断抛出有关堆栈溢出的异常
OpenCV using Windows Form keeps on throwing exceptions about stack overflowing
我一直在写一个程序,每次我关闭我的表单时它都会抛出一个异常,说我的堆栈在关闭后台工作者的那一行溢出了...
我已经遇到这个问题一段时间了,我已经尝试用谷歌搜索这个问题,但我还没有想出任何想要的解决方案......
我的故障排除猜测如下:
- picturebox中的图片占用资源,程序退出时不清除
- 后台还在忙
这是我的代码,在此先感谢!
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 的延迟。
我一直在写一个程序,每次我关闭我的表单时它都会抛出一个异常,说我的堆栈在关闭后台工作者的那一行溢出了...
我已经遇到这个问题一段时间了,我已经尝试用谷歌搜索这个问题,但我还没有想出任何想要的解决方案......
我的故障排除猜测如下:
- picturebox中的图片占用资源,程序退出时不清除
- 后台还在忙
这是我的代码,在此先感谢!
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 的延迟。