【作业】RGB/BMP转YUV格式及YUV视频拼接

这篇博客介绍了RGB和BMP文件格式,详细讲解了RGB到YUV的转换公式,并阐述了BMP文件的结构。通过实验内容,展示了如何将不同格式的图像转换为YUV格式,并进行视频拼接。提供了代码分析和测试过程。
摘要由CSDN通过智能技术生成

简介

RGB文件

RGB文件是原始的没有压缩的包含红绿蓝三种颜色的图像文件。
常见的RGB格式例如RGB24,也就是一组RGB像素中的R、G、B各占8比特,即一个字节,一组RGB一共是24个比特。
这里只以RGB24为例。

YUV文件

YUV文件是与RGB文件同样属于原始的没有压缩的图像文件,只是YUV格式存储的是亮度Y、色差信号U和V。
和YUV不同的是,由大面积着色原理,人眼对于亮度信号的敏感度远强于颜色信号的敏感度。因此色度信号可以比亮度信号取得更少,而视觉上差别不大。
因此YUV又有多种取样结构,如4:4:4、4:2:2、4:2:0等。
显然4:4:4的画面质量最好。数字演播室采用的取样结构为4:2:2。
RGB与YUV的转换公式如下:
Y = 0.299 R + 0.587 G + 0.114 B R − Y = 0.701 R − 0.587 G − 0.114 B B − Y = − 0.299 R − 0.587 G + 0.886 B U = 0.713 ∗ ( R − Y ) + 128 V = 0.713 ∗ ( B − Y ) + 128 Y = 0.299R + 0.587G + 0.114B\\ R-Y = 0.701R - 0.587G-0.114B\\ B-Y = -0.299R - 0.587G + 0.886B\\\\ U = 0.713 *(R-Y) + 128\\ V = 0.713 * (B-Y) + 128 Y=0.299R+0.587G+0.114BRY=0.701R0.587G0.114BBY=0.299R0.587G+0.886BU=0.713(RY)+128V=0.713(BY)+128
YUV的Y、U、V的信号在YUV格式中是分开存放的。

BMP文件

BMP文件有两种颜色表示方式

  1. 24bit以下,带调色板的图像,从调色板里选取颜色
  2. 24bitRGB图像
    这里只考虑后者,以后有时间的话会同时实现。
    BMP文件有文件头,带有图片的一些元信息,如图片大小、长宽、调色版数量等等。
    BMP开头是一个两字节的标识(Signature)“BM"。
    接下来是文件头信息,带有文件基本的信息:文件大小和像素数据开始位置:
typedef struct 
{
   
	Char Signature[2];
    DWORD FileSize;
    DWORD _reserved;
    DWORD DataOffset;
} BITMAPFILEHEADER;

("BM"标识也应该是BITMAPFILEHEADER的一部分,但是这样声明结构体,在C语言下会引起内存对齐的问题,不方便直接把文件头读进结构体,因此实际编码的时候没有把它放进结构体)

再接下来是文件信息头,包含了图片的元数据信息。

typedef struct
{
   
    DWORD Size;
    int Width;
    int Height;
    WORD Planes;
    WORD BitCount;
    DWORD Compression;
    DWORD ImageSize;
    DWORD XpixelsPerM;
    DWORD YpixelsPerM;
    DWORD CorlorsUsed;
    DWORD ColorsImaportant;
} BITMAPINFOHEADER;

对于24bit像素的Bitmap文件,像素以RGB的形式直接存放在文件信息头之后,也就是BITMAPFILEHEADER的DataOffset指示的地方。
需要注意的是,BMP像素排列有两种方式,

  • 从左上开始,从上到下
  • 从左下开始,从下到上

判断方法是根据BITMAPINFOHEADER中Height的正负,当Height为正时,从上到下扫描,当Height为负时,从下到上扫描。

因此Height在结构体里应该声明成有符号整型。

实验内容

在这里插入图片描述
思路很简单,首先,无论输入的是什么格式,都一律解码为RGB格式。

RGB格式的数据进行转码比YUV格式更方便。

不同BMP的大小可能不一,因此在转换成YUV前需要根据输出尺寸进行裁剪。

在最终输出阶段,全部转换成YUV格式,然后按照要求的帧数重复写入到文件。

代码分析

一些定义

这些定义是放在头文件里的

typedef unsigned char BYTE;
typedef unsigned int DWORD;
typedef unsigned short WORD;
#ifndef _YUV_H_
#define _YUV_H_
typedef struct {
   
    BYTE Y;
    BYTE U;
    BYTE V;
} YUV;

typedef struct {
   
    BYTE R;
    BYTE G;
    BYTE B;
} RGB;

typedef struct {
   
    int Y;
    int U;
    int V;
}YUV_FORMAT;

typedef enum  {
   FILE_BMP, FILE_RGB} INPUT_TYPE;

typedef struct
{
   
    FILE *fp;
    const char * file_path;
    INPUT_TYPE type;
    DWORD height;
    DWORD width;
    YUV * yuv_raw;
    DWORD yuv_size;
    RGB * rgb_raw;
    DWORD rgb_size;
    DWORD start;
    int duration;
} ImgFile;

RGB转YUV格式

void RGB2YUV(RGB * rgb_img, YUV * yuv_img, int size) {
   
    int i=0;
    for(i=0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值