多线程交替工作的一种简单方式,以实现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;
}
标签:info,为例,frame,YUV,YUV420,cv,线程,多线程,image 来源: https://blog.csdn.net/IcdKnight/article/details/104846781