用于定期网络摄像头帧捕获的中断计时器c ++

时间:2015-07-22 23:33:49

标签: c++ timer webcam interrupt periodic-task

我需要从网络摄像头捕获一帧大约每秒30次。基本上,我正在寻找一种方法来实现以下内容:

mainloop:
while( // scan is in process )
{
    // process current image
    // discard current image and dequeue next image (pop it off the front of the queue)
}

interrupt routine: // execute 30 times per second
{
    // capture newImage with webcam
    // enqueue newImage (push it onto the back of the queue)
    // reset timer and return from interrupt 
}

我担心我没有足够的经验来确切知道我在寻找什么。如果有人有关于如何每30秒在背景中拍照的更好建议,我会很高兴听到它。我是OpenCV的新手,虽然我在课堂环境中有相当多的C ++经验。我的项目的最终目标是使用特征检测和匹配,以便在每两帧之间提取帧到帧的变换矩阵(换句话说,跟踪表面上的摄像机运动)。

目标操作系统:OSX Yosemite 10.10.4,运行XCode 6.3.1 *最终这个解决方案将转移到Windows平台,所以我很乐意找到一个非平台(或计算机)特定的解决方案。

1 个答案:

答案 0 :(得分:0)

大多数相机都会在自己的时钟上捕捉图像。你是奴隶,而不是主人:你不会触发图像捕获。相反,只要有新图像,您就会收到通知。任何相机API(OpenCV,Qt Multimedia等)都可以在新的相机数据可用时通知您。如果API没有异步通知,您可以旋转线程并同步执行捕获。用OpenCV说:

void process(const cv::Mat & frame) { ... }

int main() {
  bool quit = false;
  std::condition_variable queue_cv;
  std::mutex queue_mutex;
  std::deque<cv::Mat> queue;
  auto capture = cv::VideoCapture(0);

  // Worker thread - source of frames
  auto thread = std::thread([&]{
    int frame_count = 0;
    while (! quit) {
      cv::Mat frame;
      if (! capture.read(frame)) break;
      frame_count ++;
      if (frame_count >= 30) {
        std::unique_lock<std::mutex> lock(queue_mutex);
        queue.push_back(frame);
        lock.unlock();
        queue_cv.notify_one();
        frame_count = 0;
      }
    }
    quit = true;
  });

  // Main thread - consumer of frames
  while (!quit) {
    std::unique_lock<std::mutex> lock(queue_mutex);
    queue_cv.wait(queue_lock, []{ return queue.size() > 0; });
    // we own the lock here
    auto frame = queue.pop_front();
    lock.unlock();
    // lock is released, process the frame
    process(frame);
  }
  thread.join();
}