简体   繁体   中英

OpenCV - Capture frames in a separatethread

I'm trying to use OpenCV 2.4.8 to capture frames in my android application. I write a .SO library for it and link OpenCV libraries to it.

From this link: http://docs.opencv.org/modules/core/doc/intro.html , I wrote a sample code as below.

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."

Any idea what I'm missing here?

EDIT:

I tried opening camera within the thread and modified capture() as below:

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. 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. It should solve your problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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