1

我需要每秒大约 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 平台,因此我很想找到一个不是平台(或计算机)特定的解决方案。

4

1 回答 1

1

大多数相机在自己的时钟上捕捉图像。然后你是奴隶,而不是主人:你不会触发图像捕捉。相反,只要有新图像可用,您就会收到通知。当有新的相机数据可用时,任何相机 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();
}
于 2015-07-23T00:24:31.923 回答