Как я могу синхронизировать полученное изображение, которое обновляется каждые 20 миллисекунд?

0

Я использую c++ и обрабатываю асинхронные вызовы с boost. У меня есть основная функция, которая вызывает процессор изображения каждые 20 миллисекунд, а с помощью OpenCV я пытаюсь показать изображение, которое я получаю из другой программы.

Основная функция выглядит так:

 void Master::StartControlTimer()
 {
     m_ControlTimer.expires_from_now(boost::posix_time::milliseconds( m_ControlTimerPeriod ));

     m_ControlTimer.async_wait(boost::bind(&Master::OnControlTimerElapsed, this, boost::asio::placeholders::error));
 }

OnControlTimerElapsed вызывает функцию, которая получает изображение из программы, и я хочу обработать изображение и отобразить его с помощью OpenCV:

void ImageProcessor::processImage(unsigned char* image, int resolution[2])
{
  m_OcvImage = cvCreateImage(cvSize(resolution[0], resolution[1]), 8, 3);

  for (unsigned int i = 0; i < resolution[1]; i++){
    for (unsigned int j = 0; j < resolution[0]; j++){
        int r, g, b;
        r = cvRound(255 * image[3 * ((resolution[1] - i)*resolution[0] + j) + 0]);
        g = cvRound(255 * image[3 * ((resolution[1] - i)*resolution[0] + j) + 1]);
        b = cvRound(255 * image[3 * ((resolution[1] - i)*resolution[0] + j) + 2]);

        m_OcvImage.at<cv::Vec3b>(i, j) = cv::Vec3b((uchar)b, (uchar)g, (uchar)r);

    }
  }
  cv::namedWindow("image", cv::WINDOW_AUTOSIZE);
  cv::imshow("image", m_OcvImage);
  m_OcvImage.release();
}

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

Как синхронизировать изображение с помощью библиотеки boost?

Я пробовал использовать:

 boost::mutex::scoped_lock lok(m_ImageMutex)

где m_ImageMutex был boost :: mutex, прямо перед вызовом функции cvCreateImage, но не повезло с этим.

Любая полезная идея?

  • 1
    1. избегать устаревших вызовов c-api, таких как cvCreateImage, придерживайтесь cv :: Mat. 2. переместить cv::namedWindow("image", cv::WINDOW_AUTOSIZE); вне процесса изображение в основную. 3. если вы используете imshow (), вам нужен waitKey () (и это желательно в основном потоке)
  • 0
    Спасибо. Я дам ему попробовать
Показать ещё 2 комментария
Теги:
opencv
boost

1 ответ

1
Лучший ответ
  • придерживайтесь c++ api и избегайте смешивания в устаревших вызовах c-api, таких как cvCreateImage, так что это будет:

    m_OcvImage = Mat(Size(resolution[0], resolution[1]), CV_8UC3);
    
  • переместите вызов cv::namedWindow() в main. вам не нужно создавать новое окно для каждого вызова processImage()

  • если вы используете imshow(), вам нужен соответствующий waitKey() (и предпочтительно в основном потоке)

[aaand, - то, что @AldurDisciple сказал выше.. многопоточность без каких-либо замков похожа на жонглирование ножами с завязанными глазами. вы не хотите пропустить бит..]

Ещё вопросы

Сообщество Overcoder
Наверх
Меню