图片保存为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)
  • 9
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
下面是将NV12格式的图像数据保存YUV格式文件的C语言算法: ```c #include <stdio.h> // 定义NV12格式图像的宽和高 #define WIDTH 640 #define HEIGHT 480 // 将NV12格式的图像数据保存YUV格式文件 void nv12_to_yuv(unsigned char* nv12_data, int nv12_size, const char* yuv_filename) { // 打开YUV格式文件 FILE* yuv_file = fopen(yuv_filename, "wb"); if (yuv_file == NULL) { printf("Error: Failed to open YUV file\n"); return; } // 计算Y分量和UV分量的大小 int y_size = WIDTH * HEIGHT; int uv_size = y_size / 2; // 写入Y分量到YUV文件 fwrite(nv12_data, 1, y_size, yuv_file); // 将UV分量写入到YUV文件 unsigned char* uv_data = nv12_data + y_size; for (int i = 0; i < uv_size; i += 2) { fwrite(&uv_data[i + 1], 1, 1, yuv_file); fwrite(&uv_data[i], 1, 1, yuv_file); } // 关闭YUV文件 fclose(yuv_file); } int main() { // 读取NV12格式的图像数据 FILE* nv12_file = fopen("input.nv12", "rb"); if (nv12_file == NULL) { printf("Error: Failed to open NV12 file\n"); return 1; } fseek(nv12_file, 0, SEEK_END); int nv12_size = ftell(nv12_file); fseek(nv12_file, 0, SEEK_SET); unsigned char* nv12_data = (unsigned char*)malloc(nv12_size); fread(nv12_data, 1, nv12_size, nv12_file); fclose(nv12_file); // 将NV12格式的图像数据保存YUV格式文件 nv12_to_yuv(nv12_data, nv12_size, "output.yuv"); // 释放内存 free(nv12_data); return 0; } ``` 上述代码中,`nv12_data` 表示NV12格式的图像数据,`nv12_size` 表示数据大小,`yuv_filename` 表示保存YUV格式文件名。函数 `nv12_to_yuv` 将NV12格式的图像数据转换为YUV格式保存到文件中。在主函数中,先读取NV12格式的图像数据,然后调用 `nv12_to_yuv` 函数将NV12格式的数据转换为YUV格式保存到文件中。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值