使用OpenCV的VideoCapture的实例化vector读取多个相机

FunnyWii
FunnyWii
发布于 2023-08-14 / 25 阅读
0
0

使用OpenCV的VideoCapture的实例化vector读取多个相机

写在前面

现在车上有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_backemplace_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


评论