opencv中的Mat转成yuv数据

1.python版本

def bgr2nv21(input_path,out_dir):
    try:
        bgr = cv2.imread(input_path)
        bgr = cv2.resize(bgr, (480, 480))
        i420 = cv2.cvtColor(bgr, cv2.COLOR_BGR2YUV_I420)
        height = bgr.shape[0]
        width = bgr.shape[1]
    
        u = i420[height: height + height // 4, :]
        u = u.reshape((1, height // 4 * width))
        v = i420[height + height // 4: height + height // 2, :]
        v = v.reshape((1, height // 4 * width))
        uv = np.zeros((1, height // 4 * width * 2))
        uv[:, 0::2] = v
        uv[:, 1::2] = u
        uv = uv.reshape((height // 2, width))
        nv21 = np.zeros((height + height // 2, width))
        nv21[0:height, :] = i420[0:height, :]
        nv21[height::, :] = uv
        #output_name = input_path.rsplit('.', 1)[0] + ".yuv"
        output_name = out_dir +input_path.split("/")[-1].rsplit('.', 1)[0] + ".yuv"
        nv21.astype("int8").tofile(output_name)
    except Exception as except_err:
        print(except_err)
        return 1
    else:
        return 0

2.C++版本

cv::Mat image = cv::imread("test.png");
int image_h = image.rows;
int image_w = image.cols;
int image_c = image.channels();
cv::imshow("image", image);
//cv::waitKey();

// 转换到I420
	cv::Mat I420;                                      // I420格式图像
	cv::cvtColor(image, I420, cv::COLOR_BGR2YUV_I420); // 转换I420格式

	uint8_t* pI420 = I420.ptr<uint8_t>();              // I420数据指针
	int32_t I420_y_s = image_h * image_w;              // I420中 Y长度
	int I420_uv_h = image_h / 2;                       // I420中UV高度
	int I420_uv_w = image_w / 2;                       // I420中UV宽度

	// 转换到NV12
	cv::Mat NV12 = cv::Mat(image_h * 3 / 2, image_w, CV_8UC1); // NV12格式图像
	uint8_t* pNV12 = NV12.ptr<uint8_t>();                      // NV12数据指针
	memcpy(pNV12, pI420, I420_y_s); // 拷贝I420中的Y数据到NV12中

	uint8_t* pI420_U = pI420 + I420_y_s;                // 移动I420中U分量指针到U数据头部
	uint8_t* pI420_V = pI420_U + I420_uv_h * I420_uv_w; // 移动I420中V分量指针到V数据头部
	pNV12 = pNV12 + I420_y_s;                           // 移动NV12指针到U数据头部
	for (int i = 0; i < I420_uv_h * I420_uv_w; i++)
    { 
        // 遍历I420中UV分量数据,复制到NV12中
		// 把I420中U数据复制到NV12中U数据对应位置
	    *pNV12 = *pI420_U;
	    pNV12++;
	    pI420_U++;

		// 把I420中V数据复制到NV12中V数据对应位置
	    *pNV12 = *pI420_V;
	    pNV12++;
	    pI420_V++;
	}

			// 保存转换图像
	FILE* fp = fopen("ocr_test.yuv", "wb");
	int image_len = image_w * image_h * 3 / 2;
	fwrite(NV12.ptr<uint8_t>(), image_len, 1, fp);
	fclose(fp);

			// 读取转换图像
	fp = fopen("ocr_test.yuv", "rb");
	unsigned char* image_buf = new unsigned char[image_len];
	fread(image_buf, image_len, 1, fp);
	fclose(fp);

			// 显示转换图像
	cv::Mat image2 = cv::Mat(image_h * 3 / 2, image_w, CV_8UC1, image_buf);
	cv::cvtColor(image2, image2, cv::COLOR_YUV2BGR_NV12);
	cv::imshow("image2", image2);
	cv::waitKey();
	return 0;

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值