C++11 thread类实现OpenCV多线程开启摄像头

       刚接触C++多线程编程,好在C++11提供了官方的多线程库thead,比较容易上手而且最重要的是作为官方标准库保证了可移植性,于是试试能不能使用thread类实现OpenCV中多线程同时打开两个摄像头并读取图像。

       VS2017 + OpenCV 3.4.0

#include "stdafx.h"
#include "opencv2/opencv.hpp"
#include "stdio.h"
#include "iostream"
#include "thread"

std::thread::id main_thread_id = std::this_thread::get_id();  // 获取主线程ID

bool openCamera(cv::VideoCapture &cap, const int cameraDrive)
{
	cap.open(cameraDrive);
	if (!cap.isOpened()) {
		printf("The camera is not opened.\n");
		return false;
	}
	else {
		printf("The %dth camera is opened.\n", cameraDrive + 1);
		
		// 判断当前线程是否为主线程
		if (main_thread_id == std::this_thread::get_id())
			printf("This is the main thread.\n");
		else
			printf("This is not the main thread.\n");
		
		// 设置相机捕获画面尺寸大小
		cap.set(cv::CAP_PROP_FRAME_WIDTH, 640);
		cap.set(cv::CAP_PROP_FRAME_HEIGHT, 480);

		// 曝光   min:-8  max:0
		cap.set(CV_CAP_PROP_EXPOSURE, (-4));
		// 帧数   30 60
		cap.set(CV_CAP_PROP_FPS, 60);
		// 亮度    min:-64  max:-60
		//cap.set(CV_CAP_PROP_BRIGHTNESS, (-brightness));  
		// 对比度  min:0  max:100
		//cap.set(CV_CAP_PROP_CONTRAST, 60);
		// 饱和度  min:0  max:128
		//cap.set(CV_CAP_PROP_SATURATION, 50);
		// 色调   min:-180  max:180
		//cap.set(CV_CAP_PROP_HUE, hue); 
		
		return true;
	}
}

bool readCamera(cv::VideoCapture &cap, cv::Mat &src)
{
	cap.read(src);
	if (src.empty()) {
		printf("The frame is empty.\n");
		return false;
	}
	return true;
}

int main(void)
{
	cv::Mat frame_1, frame_2;
	cv::VideoCapture capture_1, capture_2;
	const int cameraDrive1 = 0;
	const int cameraDrive2 = 1;

	std::thread extraT(openCamera, std::ref(capture_2), cameraDrive2);  // 创建线程extraT,调用openCamera()函数

	// 开启摄像头并初始化参数
	if (!openCamera(capture_1, cameraDrive1))
		return EXIT_FAILURE;
	
	extraT.detach();  // 启动线程extraT,且分离主线程和子线程
	
	for (;;)
	{
		// 摄像头读取图像
		if (!readCamera(capture_1, frame_1))
			break;
		if (!readCamera(capture_2, frame_2))
			break;

		cv::imshow("frame_1", frame_1);
		cv::imshow("frame_2", frame_2);
		if ((cv::waitKey(25) & 0XFF) == 27) {
			printf("You have exit this program.\n");
			break;
		}
	}
	cv::destroyAllWindows();
	capture_1.release();
	capture_2.release();
	
	return EXIT_SUCCESS;
}

       说起来也是坑的不行,主要是使用std::thread()构造函数创建线程传参时,直接传递引用各种报错,必须要使用std::ref()函数传递引用,具体什么原因也不是很懂,反正加了std::ref()后程序就能跑了 = = ... 还是等大神前来解答吧...

参考文章 :https://blog.csdn.net/th_num/article/details/81385917       

 

你可能感兴趣的:(opencv,c++)