繁体   English   中英

安全地在boost :: thread中更新cv :: capturevideo帧

[英]updating cv::capturevideo frame in a boost::thread safely

我想同时通过openGL 2camera渲染。 我想尽快刷新每个帧。 为了更新那些框架,我在无限循环中使用了一个线程。

我的实际问题是,如果我将这些相机的分辨率提高到高水平,程序就会崩溃。 160:120没问题。 但是,如果我将最大分辨率(1920:1080)设置为崩溃之前,则只有5或6个图像更新。 注意:崩溃前更新次数并不总是相同

我想如果分辨率足够低,则frame_L和frame_R的更改速度会足够快,以至于主循环和线程之间不会产生任何细菌。

所以我想我的互斥锁没有做应该做的事情。 我应该怎么做?

(我不是线程和变量安全方面的专家)

我的代码:

#include <boost/thread/mutex.hpp>
#include <boost/thread/thread.hpp>

#include <opencv2/opencv.hpp>


boost::mutex m; //for an other thread
boost::mutex n;

cv::VideoCapture capture_L(0);
cv::VideoCapture capture_R(1);

cv::Mat frame_L;
cv::Mat frame_R;

void MyThreadFunction()
{
    while (1)
    {

        {
          boost::mutex::scoped_lock lk(n);

          if (capture_L.grab()){
             capture_L.retrieve(frame_L);
             cv::transpose(frame_L, frame_L);
          }

          if (capture_R.grab()){
            capture_R.retrieve(frame_R);
            cv::transpose(frame_R, frame_R);
          }
        }
    }

}

int main()
{

  capture_L.set(CV_CAP_PROP_FRAME_WIDTH, 160);
  capture_L.set(CV_CAP_PROP_FRAME_HEIGHT, 120);
  capture_R.set(CV_CAP_PROP_FRAME_WIDTH, 160);
  capture_R.set(CV_CAP_PROP_FRAME_HEIGHT, 120);

  boost::thread thrd(&MyThreadFunction);

  while(1)
  {
       [  use  frame_L and frame_R  ]  
  }  

}

这是我用于螺纹摄像头抓取的代码。 它是相机对象的一部分(例如,每个相机都有它自己的对象和用于捕获的线程)。

void Camera::setCapture(cv::VideoCapture cap)
{
    pthread_mutex_lock(&latestFrameMutex);
    videoCapture = cap;
    videoCapture.read(latestFrame);
    pthread_mutex_unlock(&latestFrameMutex);
    int iret = pthread_create(&cameraGrabThread,NULL,&Camera::exec,this);
}

void *Camera::exec(void* thr)
{
   reinterpret_cast<Camera *> (thr)->grabFrame();
}

这样可以确保在为该摄像机设置捕获时启动新线程。 以下代码由线程的exec部分运行,以实际抓取帧。

void *Camera::grabFrame()
{
    while(videoCapture.isOpened())
    {
        pthread_mutex_lock(&latestFrameMutex);
        if(!videoCapture.read(latestFrame))
            std::cout << "Unable to read frame" << std::endl;
        pthread_mutex_unlock(&latestFrameMutex);

        usleep(8000); // Sleep 8ms
    }
}

最后,相机需要能够返回最新的画面。

cv::Mat Camera::getLatestFrame()
{
    while (getMilisecSinceLastCapture() < 35) //Enforce min time of 35 ms between frame requests.
    {
        usleep(5000);
    }
    pthread_mutex_lock(&latestFrameMutex);
    cv::Mat result = latestFrame.clone();
    pthread_mutex_unlock(&latestFrameMutex);
    return result.clone();
}

更改大小可以通过使用

void Camera::setImageSize(const cv::Size& size)
{    
    pthread_mutex_lock(&latestFrameMutex);
    videoCapture.set(CV_CAP_PROP_FRAME_HEIGHT, size.height);
    videoCapture.set(CV_CAP_PROP_FRAME_WIDTH, size.width);
    pthread_mutex_unlock(&latestFrameMutex);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM