YUV(二)-YUV格式转换缩放

本文转自:

http://blog.csdn.net/zhuweigangzwg/article/details/17222581

YUV(二)-YUV格式转换缩放

     本文主要讲解yuv各种格式相互转换的功能实现及原理,以常用的yuv420p,yuv422p,yuv444p作为转换格式比较清晰的解析各

种格式,以及用ffmpeg做转换的实现,同时有需要的朋友也可以用opencv做实现。
   (一):内存采样
    YUV码流的存储格式其实与其采样的方式密切相关,主流的采样方式有三种,YUV4:4:4,YUV4:2:2,YUV4:2:0,这里强调的

是如何根据其采样格式来从码流中还原每个像素点的YUV值,因为只有正确地还原了每个像素点的YUV值,才能通过YUV与RGB的

转换公式提取出每个像素点的RGB值,然后显示出来。
用三个图来直观地表示采集的方式吧,以黑点表示采样该像素点的Y分量,以空心圆圈表示采用该像素点的UV分量。
YUV 4:4:4采样,每一个Y对应一组UV分量。 2. 3.YUV 4:2:2采样,每两个Y共用一组UV分量。 4.5.YUV 4:2:0采样,每四个Y共

用一组UV分量。
 

   (二):内存分布
        1:YUV420
          (1):I420:
              YYYYYYYY UU VV    =>YUV420P
          (2):YV12
              YYYYYYYY VV UU    =>YUV420P
          (3):NV12
              YYYYYYYY UVUV     =>YUV420SP (dxva 输出 NV12)
          (4):NV21
              YYYYYYYY VUVU     =>YUV420SP (x264/ffmpeg 输入、输出 I420)
        2:YUV422
          (1):YUVY:(实际格式与YUY2相同)


          (2):UYVY:


          (3):YUV422P


        3:YUV444
          (1):YUV444P
              YYYYYYYY  UUUUUUUU VVVVVVVV
   (三):ffmepeg实现
          (1):AVFrame内存关联


          (2):判断输入输出格式


          (3):格式转换



   (四):扩展分析
          (1):本例只实现上述中的几种格式,还有很多格式未有实现。
          (2):内存分布中,还有不同的格式可以扩展例如:YUV444->可以扩展为:YYYYYYYY   VVVVVVVV   UUUUUUUU.等等 

内存格式。
          (3):本文采取yuv-yuv格式之间的转换,底层用到的是双三次差值算法。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: YUV是一种颜色编码格式,常用于表达视频图像。缩放YUV图像的代码可以通过以下步骤实现: 1. 读取源YUV图像数据:首先要读取源YUV图像的数据,并确定图像的宽度和高度。YUV图像的数据通常以进制文件形式存储。 2. 创建目标YUV图像:根据缩放比例计算目标图像的宽度和高度,然后创建一个新的YUV图像。 3. 缩放Y分量:将源图像的Y分量按照缩放比例进行插值计算,得到目标图像的Y分量。插值算法可以选择简单的双线性插值或更复杂的卷积插值。 4. 缩放UV分量:由于YUV图像的UV分量采样比Y分量低,所以在缩放UV分量时需要考虑到采样率。可以选择将UV分量按照与Y分量相同的缩放比例进行插值,或者采用更复杂的算法进行处理。 5. 写入目标YUV图像数据:将目标图像的YUV数据写入到一个新的进制文件中,以供后续使用。 需要注意的是,缩放YUV图像并不仅仅是对图像进行简单的拉伸或压缩,还需要考虑到YUV颜色空间的特殊性,以避免颜色失真或其他问题的出现。因此,在实际的代码实现中,还需要考虑色彩空间转换、边缘处理等问题,以保证缩放后的图像质量。 ### 回答2: 在RGB图像处理中,YUV是一种颜色编码系统,常用于视频信号的传输和显示。YUV图像缩放是指改变图像的大小,调整图像的宽度和高度。 在C语言中,可以使用图像处理库,如OpenCV来实现YUV图像的缩放。下面是一个简单的代码示例: ```c #include <opencv2/opencv.hpp> using namespace cv; int main() { // 读取YUV文件 Mat yuvImage = imread("input.yuv", IMREAD_UNCHANGED); // 设置缩放比例 double scale = 0.5; // 缩小为原来的一半,如果想放大,可以设置大于1的值 // 计算缩放后的图像尺寸 Size newSize(yuvImage.cols * scale, yuvImage.rows * scale); // 创建缩放后的图像 Mat resizedImage; // 缩放YUV图像 resize(yuvImage, resizedImage, newSize, 0, 0, INTER_LINEAR); // 保存缩放后的YUV图像 imwrite("output.yuv", resizedImage); return 0; } ``` 在上述代码中,首先使用OpenCV的`imread`函数读取YUV图像。然后,通过设置缩放比例来计算缩放后图像的尺寸。接下来,使用`resize`函数对YUV图像进行缩放操作,将结果保存到`resizedImage`中。最后,使用`imwrite`函数将缩放后的图像保存到指定的输出文件中。 需要注意的是,这只是一个简单的示例代码,实际的应用中可能还需要处理图像的颜色空间转换和数据格式转换等问题。 ### 回答3: c语言中实现yuv缩放的代码如下: ```c #include <stdio.h> #include <stdlib.h> void yuvScale(unsigned char* srcY, unsigned char* srcU, unsigned char* srcV, int srcWidth, int srcHeight, unsigned char* dstY, unsigned char* dstU, unsigned char* dstV, int dstWidth, int dstHeight) { int x, y; int ratio_w = (srcWidth << 16) / dstWidth + 1; int ratio_h = (srcHeight << 16) / dstHeight + 1; for (y = 0; y < dstHeight; y++) { for (x = 0; x < dstWidth; x++) { int px = x * ratio_w >> 16; // 计算源图像的坐标 int py = y * ratio_h >> 16; dstY[y * dstWidth + x] = srcY[py * srcWidth + px]; if (x % 2 == 0 && y % 2 == 0) { // 同时对U和V进行缩放计算 int uIndex = (y >> 1) * (dstWidth >> 1) + (x >> 1); int vIndex = (y >> 1) * (dstWidth >> 1) + (x >> 1); dstU[uIndex] = srcU[(py >> 1) * (srcWidth >> 1) + (px >> 1)]; dstV[vIndex] = srcV[(py >> 1) * (srcWidth >> 1) + (px >> 1)]; } } } } int main() { int srcWidth = 640; int srcHeight = 480; int dstWidth = 320; int dstHeight = 240; unsigned char* srcY = (unsigned char*)malloc(srcWidth * srcHeight * sizeof(unsigned char)); unsigned char* srcU = (unsigned char*)malloc(srcWidth * srcHeight / 4 * sizeof(unsigned char)); unsigned char* srcV = (unsigned char*)malloc(srcWidth * srcHeight / 4 * sizeof(unsigned char)); unsigned char* dstY = (unsigned char*)malloc(dstWidth * dstHeight * sizeof(unsigned char)); unsigned char* dstU = (unsigned char*)malloc(dstWidth * dstHeight / 4 * sizeof(unsigned char)); unsigned char* dstV = (unsigned char*)malloc(dstWidth * dstHeight / 4 * sizeof(unsigned char)); // 将原始YUV数据填充,此处仅为示例,实际应按实际需求填充数据 yuvScale(srcY, srcU, srcV, srcWidth, srcHeight, dstY, dstU, dstV, dstWidth, dstHeight); // 处理缩放后的YUV数据,此处仅为示例,实际应按实际需求处理数据 free(srcY); free(srcU); free(srcV); free(dstY); free(dstU); free(dstV); return 0; } ``` 该代码使用了双重循环,分别对Y、U、V进行缩放计算。首先根据目标图像的宽高和源图像的宽高计算出宽高缩放比,然后通过双重循环遍历目标图像的每个像素点,通过缩放比计算出源图像的坐标,然后将对应位置的Y、U、V分量值赋给目标图像的相应位置。在对U和V分量进行缩放计算时,由于U和V的像素数目是Y的四分之一,所以要对坐标进行相应的位移和缩放。最后,可以根据实际需求对缩放后的YUV数据进行处理。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值