JPG图像转存为NV12格式

使用opencv函数 将JPG图像转存为NV12格式分为两步:

  1. 将BGR格式转为I420;
  2. 将I420格式转为NV12或NV21;

其中,I420、NV12、NV21格式如下:
I422 属于 YUV422P 格式。三个平面,分别存储 Y U V 分量;
在这里插入图片描述
NV12 属于 YUV420SP 格式。两个平面,分别存储 Y 分量 和 UV 分量。其中 UV 分量共用一个平面并且以 U, V, U, V 的顺序交错排列。每四个 Y 分量共享一组 UV 分量;
在这里插入图片描述
NV21 属于 YUV420SP,与 NV12 几乎一致,区别是 UV 平面中 U 与 V 的排列顺序颠倒,以 V, U, V, U 的顺序交错排列
在这里插入图片描述

	Y Y Y Y Y Y      Y Y Y Y Y Y      Y Y Y Y Y Y
	Y Y Y Y Y Y      Y Y Y Y Y Y      Y Y Y Y Y Y
	Y Y Y Y Y Y      Y Y Y Y Y Y      Y Y Y Y Y Y
	Y Y Y Y Y Y      Y Y Y Y Y Y      Y Y Y Y Y Y
	U U U U U U      U V U V U V      V U V U V U
	V V V V V V      U V U V U V      V U V U V U
     - I420 -          - NV12 -         - NV21 -

测试用例:

static void ConvertBGR2YUV420SP_NV12(const cv::Mat &bgr_image,
	unsigned char *buffer) {
    
    
	int bgr_width = bgr_image.cols;
	int bgr_height = bgr_image.rows;
	cv::Mat yuv_image;
	cvtColor(bgr_image, yuv_image, cv::COLOR_BGR2YUV_I420);

	int len_y = bgr_height * bgr_width;
	int len_u = len_y >> 2;
	unsigned char *pt_yuv_y = yuv_image.data;
	unsigned char *pt_yuv_u = pt_yuv_y + len_y;
	unsigned char *pt_yuv_v = pt_yuv_u + len_u;
	unsigned char *pt_dst_uv = buffer + len_y;
	int i, j;
	// copy y;
	memcpy(buffer, pt_yuv_y, len_y);
	// copy uv;
	for (i = 0, j = 0; i < len_u; i++) {
    
    
		pt_dst_uv[j++] = pt_yuv_u[i];
		pt_dst_uv[j++] = pt_yuv_v[i];
	}
}

int main()
{
    
    
	vector<cv::String> files_jpg;
	glob("D:/data/*.jpg", files_jpg);

	for (size_t i = 0; i < files_jpg.size(); i++)
	{
    
    

		cv::Mat bgr_mat = cv::imread(files_jpg[i].c_str(), cv::IMREAD_COLOR);

		int width = bgr_mat.cols;
		int height = bgr_mat.rows;
		int yuvNV12_size = width * height * 3 / 2;
		int rgb24_size = width * height;

		unsigned char *nv12_buffer = (unsigned char *)malloc(yuvNV12_size*sizeof(uchar));
		ConvertBGR2YUV420SP_NV12(bgr_mat, nv12_buffer);
		std::string savePath = files_jpg[i] + "_nv12.yuv";
		FILE *yuvFd = fopen(savePath.c_str(), "w+");
		fwrite(nv12_buffer, sizeof(uchar), yuvNV12_size, yuvFd);
		fclose(yuvFd);
		free(nv12_buffer);
	}

	return 0;
}

猜你喜欢

转载自blog.csdn.net/zfjBIT/article/details/129429444