写在前面
现在车上有7个相机,如果想要用OpenCV同时读取这些相机的画面的话,实例化7个 VideoCapture
是没有问题的,虽然会涉及到多线程的问题,但是多线程我还不会(ciao,是反废话)。直接实例化多个 VideoCapture
未免有些显得技术力过低,因此使用 vector
容器来存放读取的相机数据。
单线程版
#include <opencv2/opencv.hpp>
#include <vector>
int main() {
std::vector<cv::VideoCapture> captures;
const int num_cams = 7;
for (int i = 0; i < num_cams; ++i) {
captures.emplace_back(i);
}
// captures[0] represents the first camera (index 0)
// captures[1] represents the second camera (index 1)
// and so on...
// Use the captures instances to read frames from the cameras
// ...
return 0;
}
emplace_back
是C++ STL vector
的成员函数,用于在 vector
末尾插入一个元素。相比于 push_back
, emplace_back
可避免不必要的拷贝操作,即可以直接在 vector
内部创建新元素。
多线程版
#include <opencv2/opencv.hpp>
#include <thread>
using namespace cv;
void showCamera(int index) {
VideoCapture cap(index);
if (!cap.isOpened()) {
return;
}
while (true) {
Mat frame;
cap >> frame;
imshow("Camera " + std::to_string(index), frame);
if (waitKey(30) == 27) {
break;
}
}
}
int main() {
std::thread t1(showCamera, 0);
std::thread t2(showCamera, 1);
t1.join();
t2.join();
return 0;
}
多线程,即两个及以上的线程并发运行,可能出现以下三种情况:
- 主线程先运行结束
- 子线程先运行结束
- 主子线程同时结束
一般子线程结束后,主县城才能结束。但是并不是主线程结束,子线程会立刻停止,因为子线程可能会进入后台运行。
join()
函数是一个等待线程完成函数,主线程需要等待子线程运行结束了才可以结束。整个过程可以理解为:新线程创建->新线程执行完->新线程被销毁,若过程中使用了共享变量,由于线程被销毁所以不会产生异常。不过可能会有性能损失
detach()
称为分离线程函数,会让线程在后台运行,即说明主线程不会等待子线程运行结束才结束。https://blog.csdn.net/qq_36784975/article/details/87699113 这篇文章中后面的例程可以看出,使用 detach()
函数时,如果主线程结束过快,可能来不及运行子线程或者子线程不能完整运行(不过会在后台运行完)。
参考文章
[1] https://blog.csdn.net/qq_41452267/article/details/105439084
[2] https://blog.csdn.net/qq_36784975/article/details/87699113