RGBとYUV 420の相互変換を実現する例として、マルチスレッドが交互に動作する簡単な方法

12174 ワード

本編の博文は前編の自分で考えた1種のマルチスレッドの交互の仕事を実現する方式に続いて、1種のダブルスレッドの協同の仕事についての1種の実際の応用シーンをあげて、実現したのはRGBとYUV 420の相互変換です.主関数は2つのスレッドを開始し、1つのスレッドはRGB形式のピクチャを読み出し、YUV形式のデータに変換して申請のメモリに格納する.もう1つのスレッドはメモリデータを読み取り、YUV形式をRGBに変換して表示するために使用されます.スレッド1の読み出し変換記憶を先に行い,スレッド2の読み出しメモリと変換表示を行い,2つのスレッドが交互に動作する必要があるため,前編で述べたマルチスレッド連携動作手法を用いた.
コードは次のとおりです.
#include  
#include 
#include 

#include 

using namespace std;

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

cv::VideoCapture capture("");

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;
}