简体   繁体   English

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

[英]OpenCV - Capture frames in a separatethread

I'm trying to use OpenCV 2.4.8 to capture frames in my android application.我正在尝试使用 OpenCV 2.4.8 在我的 android 应用程序中捕获帧。 I write a .SO library for it and link OpenCV libraries to it.我为它编写了一个 .SO 库并将 OpenCV 库链接到它。

From this link: http://docs.opencv.org/modules/core/doc/intro.html , I wrote a sample code as below.从这个链接: 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;
  }
}

This code works just fine as long as I run it from main thread.只要我从主线程运行这段代码就可以正常工作。 If I try to run it in a separate thread eg如果我尝试在单独的线程中运行它,例如

std::thread t(capture, cap);

It can't capture the frames.它无法捕获帧。 It gives me some fatal error at the code line它在代码行中给了我一些致命错误

cap>> frame;

in the above code.在上面的代码中。 However, in the above OpenCV documentation, it clearly says "The current OpenCV implementation is fully re-enterable. That is, the same function, the same constant method of a class instance, or the same non-constant method of different class instances can be called from different threads. Also, the same cv::Mat can be used in different threads because the reference-counting operations use the architecture-specific atomic instructions."但是,在上面的OpenCV文档中,明确说“目前的OpenCV实现是完全可重入的。即同一个函数,同一个类实例的同一个常量方法,或者不同类实例的同一个非常量方法都可以可以从不同的线程调用。此外,相同的 cv::Mat 可以在不同的线程中使用,因为引用计数操作使用特定于体系结构的原子指令。”

Any idea what I'm missing here?知道我在这里缺少什么吗?

EDIT:编辑:

I tried opening camera within the thread and modified capture() as below:我尝试在线程中打开相机并修改 capture() 如下:

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

It fails while opening the camera itself which is quite strange.打开相机本身时失败,这很奇怪。 Any suggestions?有什么建议?

As far as I know the thread cant return results, so you need to pass cap by reference or it is better if you use future, using future with threads help you return results from a function.据我所知线程不能返回结果,所以你需要通过引用传递 cap 或者如果你使用未来会更好,使用未来与线程可以帮助你从函数返回结果。 Instead of using threads use async which is a better fit with threads.不使用线程,而是使用更适合线程的异步。

Can you try the following:您可以尝试以下操作:

#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;
}

Here I'm passing the cv::VideoCapture object by reference.在这里,我通过引用传递cv::VideoCapture对象。 It should solve your problem.它应该可以解决您的问题。

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

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