將BGR轉換成為YUV420SP影像格式

水木清扬發表於2024-04-02

//BGR2YUV(YUV420SP_NV21)
void enCodeYUV420SP(unsigned  char* yuv420sp, unsigned char* rgb, int width, int height)
{
	if (yuv420sp == NULL || rgb == NULL)
		return;
	int frameSize = width*height;
	int yIndex = 0;
	int uvIndex = frameSize;
 
	int R, G, B, Y, U, V;
	for (int i = 0; i < height; i++)
	{
		for (int j = 0; j < width; j++)
		{
			B = rgb[(i * width + j) * 3 + 0];
			G = rgb[(i * width + j) * 3 + 1];
			R = rgb[(i * width + j) * 3 + 2];
 
			//RGB to YUV
			Y = ((66 * R + 129 * G + 25 * B + 128) >> 8) + 16;
			U = ((-38 * R - 74 * G + 112 * B + 128) >> 8) + 128;
			V = ((112 * R - 94 * G - 18 * B + 128) >> 8) + 128;
 
			yuv420sp[yIndex++] = (unsigned char)((Y < 0) ? 0 : ((Y > 255) ? 255 : Y));
			if (i % 2 == 0 && j % 2 == 0)
			{
				yuv420sp[uvIndex++] = (unsigned char)((V < 0) ? 0 : ((V > 255) ? 255 : V));//UV交替排列
				yuv420sp[uvIndex++] = (unsigned char)((U < 0) ? 0 : ((U > 255) ? 255 : U));
			}
		}
	}
}
 

 

 cv::Mat img = cv::imread(imgPath);
		
 
		int height = img.rows;
		int width = img.cols;
	 
		unsigned char* img_bgr_data = (unsigned char*)malloc(height*width * 3 * sizeof(unsigned char));
		for (int i = 0; i < height; i++)
		{
			unsigned char* current_row = img.ptr<uchar>(i);
			for (int j = 0; j < width; j++)
			{
				img_bgr_data[(i * width + j) * 3 + 0] = current_row[j * 3 + 0];//B
				img_bgr_data[(i * width + j) * 3 + 1] = current_row[j * 3 + 1];//G
				img_bgr_data[(i * width + j) * 3 + 2] = current_row[j * 3 + 2];//R
			}
		}
	 
		//RGB->NV21(YUV420SP)
		unsigned char* img_nv21_data = (unsigned char*)malloc(height*width * 3 / 2 * sizeof(unsigned char));
		
		

		
		enCodeYUV420SP(img_nv21_data, img_bgr_data, width, height);
//Mat img_BGR(height, width, CV_8UC3);
		//cvtColor(img_nv21, img_BGR, CV_YUV2BGR_NV21);//YUV420sp->BGR
		//cv::cvtColor(img_nv21, img_BGR, cv::COLOR_YUV420sp2BGR);
		//cv::imwrite("./img_BGR.jpg", img_BGR);		

  

 

相關文章