OpenCV с помощью Windows Form продолжает генерировать исключения о переполнении стека - PullRequest
0 голосов
/ 10 июня 2018

Я пишу программу, и каждый раз, когда я закрываю свою форму, она выдает исключение, сообщающее, что мой стек переполнен в строке, закрывающей фоновый рабочий ...
Я столкнулся с этой проблемой уже некоторое время, яЯ пытался найти решение проблемы, но я пока не нашел нужного решения ...

Мои предположения по устранению неполадок следующие:

  1. Изображения в картинке занимают ресурсы ине сбрасываются при отмене программы
  2. Фоновый рабочий все еще занят

Вот мой код, заранее спасибо!


Элементы

Picturebox называется видеобокс
Кнопка называется btnOpenCamera_Click
Кнопка называется btnCloseCamera_Click
Метка называется backgroundworkerStatus


Переменные

Global

Mat videoFrame;
VideoCapture video(0);

Личное

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.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 голосов
/ 14 июня 2018

Чтобы решить эту проблему, добавьте задержку в DoWork

private: System :: Void backgroundWorker1_DoWork

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

Примечание
Thread :: Sleep рассчитывает в миллисекундах, вы можете изменить его на желаемое число в соответствии с частотой кадров вашей камеры.Мой ноутбук веб-камера ок.15 кадров в секунду, что составляет 66,66 мс на кадры, время ожидания должно быть> = это мс / кадр, но у меня нет проблем при запуске с задержкой всего 50 мс.

...