多线程交替工作的一种简单方式,以实现RGB和YUV420的相互转换为例

本篇博文接前篇自己思考出来的一种实现多线程交替工作的方式,给出来一个关于双线程协同工作的一种实际应用场景,实现的是RGB和YUV420的相互转换。主函数启两个线程,其中,一个线程用来读取RGB形式图片,并转成YUV格式数据存到申请的内存中;另一个线程用来读取内存数据,并把YUV格式转成RGB并显示。因为需要先进行线程1的读取转换存储,再进行线程2的读取内存和转换显示,两个线程交替工作,所以用到了前篇提到的多线程协同工作方法。

代码见下:

#include <iostream> 
#include <thread>
#include <windows.h>

#include <opencv2/opencv.hpp>

using namespace std;

typedef struct frame
{
	unsigned char*			bufferData;
	int						width;
	int						height;
}frame;

cv::VideoCapture capture("<path>");

frame frame_info;

frame getYUVData()  // 模拟得到YUV数据
{
	cv::Mat orig_image;
	cv::Mat YUV_image;
	capture >> orig_image;  // 得到原始图像

	cv::cvtColor(orig_image, YUV_image, CV_BGR2YUV_I420);  // RGB转YUV

	// 把YUV图像数据拷贝到申请到的内存中
	int bufLen = orig_image.cols * orig_image.rows * 3 / 2;
	unsigned char* pYUVBuf = new unsigned char[bufLen];
	memcpy(pYUVBuf, YUV_image.data, bufLen * sizeof(unsigned char));

	return { pYUVBuf, orig_image.cols, orig_image.rows };
}

bool flag = true;  // 控制两个线程协调工作

void program1()  // YUV输入
{
	while (1)
	{
		frame_info = getYUVData();  // 把YUV数据传给全局变量以进行线程通信

		flag = false;
		while (!flag)
		{
			Sleep(1);
		}
	}
}

void program2()  //  使用YUV
{
	while (1)
	{
		while (flag)
		{
			Sleep(1);
		}

		cv::Mat dst(frame_info.height, frame_info.width, CV_8UC3);  // 创建RGB格式图片

		int bufLen = frame_info.height * frame_info.width * 3 / 2;  // 缓存区大小

		// 创建YUV格式图片并把所得的YUV数据赋值
		cv::Mat src;
		src.create(frame_info.height * 3 / 2, frame_info.width, CV_8UC1);
		memcpy(src.data, frame_info.bufferData, bufLen * sizeof(unsigned char));
		delete[] frame_info.bufferData; // 及时删除线程1申请的内存,防止内存泄漏

		cv::cvtColor(src, dst, CV_YUV2BGR_I420);  // YUV转RGB

		cv::imshow("image", dst);
		cv::waitKey(1);

		flag = true;
	}
}

int main()
{
	std::thread thread1(program1);
	std::thread thread2(program2);
	thread1.join();
	thread2.join();

	return 0;
}
发布了23 篇原创文章 · 获赞 9 · 访问量 1295

猜你喜欢

转载自blog.csdn.net/IcdKnight/article/details/104846781