过采样将YUV420P图像展宽一倍

过采样将YUV420P图像展宽一倍


    想要完成平面纹理与球面纹理的映射,平面纹理图像比例必须是width:height=2:1,因为这个比例的全景图片刚好可以还原成一张球形全景图。如果拿到的图像源宽高比是1:1,需要将其过采样到宽高比2:1才能完成映射。

YUV420P的数据格式

    YUV由Y、U、V这三个分量组成,Y分量主管亮度的(其实就是灰度图),U和V分量主管色彩的。所以即使没有U和V分量,一样可以看到图像,只是没有颜色罢了。
YUV420P数据格式如下图:
在这里插入图片描述
    由图可见,YUV420P数据的三个分量Y/U/V被分离在了3个连续的内存块中,而每个Y都会对应一个像素,每4个像素共用一组UV。所以一张 s = width x height 的图片,就会有 s 个像素,s 个Y,s / 4 个U和V。这张图片占用的内存 m = width * height * 1.5 byte 。
    对YUV420P数据正确的采样应该是如上图中相同颜色的Y和U/V。如 Y1 Y2 Y7 Y8 对应 U1 V1,而不是 Y1 Y2 Y3 Y4 对应 U1 V1。不正确的采样会导致不正确的渲染结果。

完整代码

#include <stdio.h>
#include<stdlib.h>
#include<malloc.h>
void separate(char* url, int w, int h, int num)
{
	int k = 0, count = 0, double_count=0;
	int frame, size;
	FILE* fp1 = fopen(url, "rb+");
	FILE* fp2 = fopen("double_DownSample_420p_d.yuv", "wb+");
	FILE* in = fopen(url, "rb+");

	fseek(in, 0, SEEK_END);   //将文件指针移到文件末尾
	size = ftell(in);     //得到文件尾相对于文件首的位移,即文件的总字节数
	rewind(in);       //重置文件指针指向文件头部
	frame = size / (w * h *3 / 2); //得到原始视频文件的总帧数



	char* p1 = (char*)malloc(w * h * 3 * frame / 2);
	char* p2 = (char*)malloc(w * h * 3 * frame );
	char* pg = (char*)malloc(w * h * 3 * frame );
	for (int i = 0; i < num; i++)
	{
		fread(p1, 1, w * h * frame*3/2 , fp1);
	}
	//先处理Y分量
	for (int n = 0; n < frame; n++)
	{
		count = 0;
		double_count = 0;
		for (k = w * h * n *3 / 2 ; k < w * h * n * 3 / 2  + w * h ; k++)
		{
			pg[double_count] = p1[count];
			//进行复制
			double_count++;
			pg[double_count] = p1[count];
			double_count++;
			count++;
		}
	}

	
	//再处理UV分量
	for (int n = 0; n < frame; n++)
	{
		count = 0;
		double_count = 0;
		for (k = w * h * n * 3 / 2; k < w * h * n * 3 / 2 + w * h / 4; k++)
		{
			pg[double_count + w*h * 2] = p1[count + w*h];
			pg[double_count + w*h * 5 / 2] = p1[count + w * h * 5 / 4];
			//进行复制
			double_count++;
			pg[double_count + w*h * 2] = p1[count + w*h];
			pg[double_count + w*h * 5 / 2] = p1[count + w * h * 5 / 4];
			double_count++;
			count++;
		}
	}
	
	//system("pause");

	fwrite(pg, 1, w * h * frame * 3 , fp2);
	free(p1);
	free(p2);
	free(pg);
	fclose(fp1);
	fclose(fp2);
	fclose(in);

}

int main()
{
	separate("DownSample_420p_d.yuv", 2048, 2048, 1);
}

实现效果

将2048 * 2048的YUV420图像过采样成了4096 * 2048的YUV420图像

在这里插入图片描述

参考链接

https://blog.csdn.net/akak2010110/article/details/95811058
https://blog.csdn.net/lin5165352/article/details/82871849
https://blog.csdn.net/leixiaohua1020/article/details/50534150

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值