Изображение на дисплее во втором потоке, OpenCV?

У меня есть цикл для взятия в изображениях от высокой скорости framegrabbger на уровне 250 футов в секунду.

/** Loop processes 250 video frames per second **/
while(1){
  AcquireFrame();
  DoProcessing();
  TakeAction();
}

В то же время я хотел бы, чтобы пользователь был в состоянии контролировать то, что продолжается. Пользователь только должен видеть изображения на уровне приблизительно 30 кадр/с (или меньше). Как я настраиваю второй поток, который отображает текущий кадр время от времени?

Thread(){
  cvShowImage();
  Wait(30); /** Wait for 30 ms **/
}

Я нахожусь в Windows на четырехъядерном использовании машины Intel MinGW, gcc и OpenCV 1.1. Основные критерии - то, что поток дисплея должен занять как можно меньше времени далеко от моего основного цикла обработки. Каждая миллисекунда количества.

Я попытался использовать CreateThread() создать новый поток с cvShowImage() и cvWaitKey() но по-видимому те функции не ориентированы на многопотоковое исполнение.

Я рассматриваю использование OpenMP, но некоторые люди сообщают о проблемах с OpenMP и OpenCV. Я также рассматриваю попытку использовать DirectX directDraw, потому что, по-видимому, это очень быстро. но это выглядит сложным и evidentally существуют проблемы с помощью Windows DLL с MinGw.

Какой из этих проспектов был бы лучшим местом для запуска?

13
задан AndyL 12 January 2010 в 16:15
поделиться

3 ответа

Хорошо. Как ни странно, мой вопрос также является ответом на него.

Использование CreateThread () , CvShowImage () и CvWaitKey () , как описано в моем вопросе, действительно работает - вопреки некоторым сообщениям в Интернете, которые предлагаю обратное.

В любом случае я реализовал что-то вроде этого:

/** Global Variables **/
bool DispThreadHasFinished;
bool MainThreadHasFinished;
iplImage* myImg;

/** Main Loop that loops at >100fps **/
main() {
  DispThreadHasFinished = FALSE;
  MainThreadHasFinished = FALSE;
  CreateThread(..,..,Thread,..);

  while( IsTheUserDone() ) {
    myImg=AcquireFrame();
    DoProcessing();
    TakeAction();
  }
  MainThreadHasFinished = TRUE;

  while ( !DisplayThreadHasFinished ) {
     CvWaitKey(100);
  }

  return;
}

/** Thread that displays image at ~30fps **/
Thread() {
  while ( !MainThreadHasFinished ) {
    cvShowImage(myImg);
    cvWaitKey(30);
  }
DispThreadHasFinished=TRUE;
return;
}

Когда я первоначально разместил этот вопрос, мой код не работал по не связанным причинам. Надеюсь, это поможет!

10
ответ дан 2 December 2019 в 00:31
поделиться

Так как захват кадров не требует использования пользовательского интерфейса, я бы установил вторичную нить, чтобы обрабатывать захват кадров, и чтобы оригинальная нить, которая обрабатывает пользовательский интерфейс, отображала образцы кадров. Если бы вы попытались отобразить кадр, который в настоящее время захвачен, вам пришлось бы заблокировать данные (что, как правило, довольно медленно). Чтобы избежать этого, я бы отобразил кадр один (или, возможно, два) "позади" захватываемого в данный момент кадра, так что между захватом и отображением данных нет никакой разницы. Вам все равно придется убедиться, что инкрементирование номера текущего кадра безопасно для потока, но это довольно просто - используйте InterlockedIncrement в потоке захвата.

4
ответ дан 2 December 2019 в 00:31
поделиться

Мне жаль, что я не могу дать вам лучший ответ прямо сейчас, но похоже, что ваш вопрос не о структуре вашей программы, а скорее об инструменте, который вы должны использовать для реализации многопоточности. Для этого я бы рекомендовал Qt. Я использую Qt уже некоторое время, но только сейчас начинаю разбираться с многопоточностью.

Мне кажется, что лучшим вариантом для вас будет QReadWriteLock. Это позволит вам читать с изображения, но поток чтения отдаст свою блокировку, когда появится поток записи. В этом случае вы можете сохранить копию изображения, которое вы отображали последним, и отобразить его, если изображение заблокировано для записи.

Еще раз извините, что не могу быть более подробным, но, как я уже сказал, я только начинаю разбираться в этом. В принципе, я пытаюсь сделать то же самое, что и вы, но не так быстро :). Удачи!

0
ответ дан 2 December 2019 в 00:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: