Я использую 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, но не повезло с этим.
Любая полезная идея?
придерживайтесь c++ api и избегайте смешивания в устаревших вызовах c-api, таких как cvCreateImage
, так что это будет:
m_OcvImage = Mat(Size(resolution[0], resolution[1]), CV_8UC3);
переместите вызов cv::namedWindow()
в main. вам не нужно создавать новое окно для каждого вызова processImage()
если вы используете imshow()
, вам нужен соответствующий waitKey()
(и предпочтительно в основном потоке)
[aaand, - то, что @AldurDisciple сказал выше.. многопоточность без каких-либо замков похожа на жонглирование ножами с завязанными глазами. вы не хотите пропустить бит..]
cv::namedWindow("image", cv::WINDOW_AUTOSIZE);
вне процесса изображение в основную. 3. если вы используете imshow (), вам нужен waitKey () (и это желательно в основном потоке)