OpenCV - 在单独的线程中捕获帧

时间:2014-04-02 19:05:20

标签: c++ opencv android-ndk android-camera

我正在尝试使用OpenCV 2.4.8来捕获我的Android应用程序中的帧。我为它编写了一个.SO库,并将OpenCV库链接到它。

从这个链接:http://docs.opencv.org/modules/core/doc/intro.html,我写了一个示例代码,如下所示。

int main() {
  VideoCapture cap(0);
  if(!cap.isOpened()) return -1;
  capture(cap);
}

void capture(VideoCapture cap) {
  for(int i = 0; i<= 3; i++)
  {
    cap >> frame;
  }
}

只要我从主线程运行它,此代码就可以正常运行。如果我尝试在一个单独的线程中运行它,例如

std::thread t(capture, cap);

无法捕捉帧。它在代码行中给了我一些致命的错误

cap>> frame;

在上面的代码中。但是,在上面的OpenCV文档中,它清楚地说“当前的OpenCV实现是完全可以重新输入的。也就是说,相同的函数,类实例的相同常量方法,或者不同类实例的相同非常量方法可以从不同的线程调用。此外,相同的cv :: Mat可以在不同的线程中使用,因为引用计数操作使用特定于体系结构的原子指令。“

知道我在这里缺少什么吗?

编辑:

我尝试在线程中打开相机并修改了capture(),如下所示:

void capture() {
  VideoCapture cap(0); // fails here
  if(!cap.isOpened()) return -1;
  for(int i=0; i <= 3; i++) {
    cap >> frame;
  }
}

打开相机本身时失败,这很奇怪。有什么建议吗?

2 个答案:

答案 0 :(得分:0)

据我所知,线程无法返回结果,因此您需要通过引用传递cap或者如果您使用future更好,使用future with threads可以帮助您返回函数的结果。 而不是使用线程使用异步,这更适合线程。

答案 1 :(得分:0)

您可以尝试以下方法吗?

#include <iostream>
#include <thread>
using namespace cv;

void capture(VideoCapture &cap) 
{
  Mat frame;
  for(int i = 0; i<= 3; i++)
  {
    cap >> frame;
    // do something with frame e.g. imshow("image", frame);
  }
}

int main(int argc, char *argv[]) 
{
  VideoCapture cap(0);
  if(!cap.isOpened()) return -1;
  std::thread t(capture, std::ref(cap));
  // in the meantime do something else here
  t.join();  // wait for the thread to be finalized
  return 0;
}

在这里,我通过引用传递了cv::VideoCapture对象。它应该可以解决您的问题。