图片保存为YUV格式

保存为NV12格式的yuv420,yyyuvuvuv

#include <string>
#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

int main()
{
	std::string jpgpath = "test.jpg";
	cv::Mat img = cv::imread(jpgpath);
	int w = img.cols;                 /* 宽 */
	int h = img.rows;                 /* 高 */
	int imageLength = h * w * 3 / 2;  /* 图像y、u、v个数总和 */
	
	unsigned char*yuv_nv12 = new unsigned char[imageLength]; /* 存储nv12数据 */
	
	unsigned char*yuv = new unsigned char[imageLength];      /* 存储CV_BGR2YUV_I420数据 */
	cv::cvtColor(img, img, CV_BGR2YUV_IYUV);                 /* BGR空间转换为CV_BGR2YUV_I420 */
	memcpy(yuv_nv12, img.data, imageLength*sizeof(unsigned char));  /* 此时yuv_nv12中存储的是CV_BGR2YUV_I420类型数据 */
	memcpy(yuv, img.data, imageLength*sizeof(unsigned char));       /* 此时yuv中存储的是CV_BGR2YUV_I420类型数据 */
	int num = 0;  /* 对u、v个数的计数 */
	for (int j = w * h; j != imageLength; j += 2)
	{
		yuv_nv12[j] = yuv[w * h + num];                      /* 对yuv_nv12中u分量进行赋值 */
		yuv_nv12[j + 1] = yuv[w * h + w * h / 4 + num];      /* 对yuv_nv12中v分量进行赋值 */
		++num;
	}

	/* 保存nv12格式的yuv420 */
	FILE *fp = NULL;
	std::string outpath = "test.yuv";
	fp = fopen(outpath.c_str(), "wb+");
	if (!fp)
	{
		printf("file does not exist\n");
	}
	fwrite(yuv_nv12, 1, sizeof(char)* imageLength, fp);
	fclose(fp);
	fp = NULL;

	/* 释放内存 */
	delete[]yuv_nv12;
	delete[]yuv;
	yuv_nv12 = nullptr;
	yuv = nullptr;

	system("pause");
}

保存为CV_BGR2YUV_I420(YUV420)格式的yuv420,yyyuuuvvv

#include <string>
#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

int main()
{
    std::string jpgpath = "test.jpg";
    cv::Mat img = cv::imread(jpgpath);
    cv::resize(img, img, cv::Size(img.cols/2*2,img.rows/2*2));
    int w = img.cols;
    int h = img.rows;
    int imageLength = h * w * 3 / 2;

    unsigned char*yuv = new unsigned char[imageLength];
    cv::cvtColor(img, img, CV_BGR2YUV_IYUV);  // CV_BGR2YUV_IYUV即I420: YYYYYYYY UU VV
    memcpy(yuv, img.data, imageLength * sizeof(unsigned char));

    /* 保存YUV420格式的yuv420 */
    FILE *fp = NULL;
    std::string outpath = "test.yuv";
    errno_t ret = fopen_s(&fp, outpath.c_str(), "wb+");
    if (ret)
    {
        printf("file does not exist\n");
    }
    fwrite(yuv, 1, sizeof(char)* imageLength, fp);
    fclose(fp);
    fp = NULL;

    /* 释放内存 */
    delete[]yuv;
    yuv = nullptr;

    system("pause");
}

反过来,将上面一段代码生成的yuv再转换为jpg图像:

#include <string>
#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

int main()
{
    std::string yuvpath = "test.yuv";
    FILE *fp = NULL;
    errno_t ret = fopen_s(&fp, yuvpath.c_str(),"rb");
    if (ret)
    {
        printf("file does not exist\n");
    }
    int w = 640;
    int h = 512;
    int imageLength = h * w * 3 / 2;
    cv::Mat img_yuv = cv::Mat(h * 3 / 2, w,CV_8UC1);

    fread(img_yuv.data, sizeof(unsigned char), h*w, fp);
    fread(img_yuv.data+ h*w, sizeof(unsigned char), h*w/4, fp);
    fread(img_yuv.data+ h*w*5/4, sizeof(unsigned char), h*w/4, fp);

    fclose(fp);
    fp = NULL;
    
    cv::Mat img_bgr;
    cvtColor(img_yuv, img_bgr, CV_YUV2BGR_I420); // 后缀I420代表YUV是I420格式的
    cv::imwrite("img_bgr.jpg", img_bgr);
}

所用测试图像test.jpg为:

ellipse
图1 test.jpg(640*512)
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值