【音视频数据数据处理 6】【RGB篇】将RGB24图片转为YUV420格式图片
【音视频数据数据处理 6】【RGB篇】将RGB24图片转为YUV420格式图片
- 一、RGB24 理论知识
- 二、YUV420 理论知识
- 三、RGB24_to_YUV420_I420 代码实现
本文主要内容为,实现将 RGB24图片转为YUV420格式,
写代码之前,我们分别来分析下RGB24和YUV420各自的理论知识。
本文地址:《【音视频数据数据处理 6】【RGB篇】将RGB24图片转为YUV420格式图片》
一、RGB24 理论知识
参考《 【音视频数据数据处理 4】【RGB篇】分离RGB图片的R、G、B分量》
RGB24图像每个像素用8比特位表示,占1个字节,
注意:在内存中RGB各分量的排列顺序为:BGR BGR BGR ......
。
因此在大端存储的机器环境上(高位存在低位,低位存在高位),RGB排列顺序为(低->高):BGR BGR BGR ......
。
而在小端存储的机器环境上(高位存在高位,低位存在低位),RGB排列顺序为(低->高):RGB RGB RGB
。
因此,到时读取RGB24数据时,根据具体情况来选择RGB的读取顺序。
分辨大端小端代码如下:
//判断不前环境是大端还是小端
int checkCPU()
{union w{int a;char b;}c;c.a = 1;return (c.b == 1); //小端返回true,大端返回false
}
二、YUV420 理论知识
参考前面《【音视频数据数据处理 1】【YUV篇】分离YUV420P像素数据中的Y、U、V分量》。
I420: YYYYYYYY UU VV =>YUV420P
YV12: YYYYYYYY VV UU =>YUV420P
NV12: YYYYYYYY UV UV =>YUV420SP
NV21: YYYYYYYY VU VU =>YUV420SPYV12 : 亮度(行×列) + U(行×列/4) + V(行×列/4)
I420 : 亮度(行×列) + V(行×列/4) + U(行×列/4)
上面写好了YUV420各格式的数据排列顺序,前面的都是下planar格式。
如果要转YUV420P的话,要注意 packed格式中每个像素的的YUV是连续存储的。
即:yuv420p:Y1 U1 V1 Y2 U2 V2 Y3 U3 V3 …
YUV 格式有两大类:planar 和 packed
对于planar 的YUV格式,先连续存储所有像素点的Y,紧接着存储所有像素点的U,随后是所有像素点的V。
对于packed 的YUV格式,每个像素点的Y,U,V是连续交叉存储的。
我们百度下RGB和YUV的转换公式,结果如下:
RGB转YUV 公式:
Y= 0.299*R+0.587*G+0.114*B
U=-0.147*R-0.289*G+0.463*B
V= 0.615*R-0.515*G-0.100*B
或
y = (unsigned char)( ( 66 * r + 129 * g + 25 * b + 128) >> 8) + 16 ;
u = (unsigned char)( ( -38 * r - 74 * g + 112 * b + 128) >> 8) + 128 ;
v = (unsigned char)( ( 112 * r - 94 * g - 18 * b + 128) >> 8) + 128 ;YUV转RGB 公式:R = y + 1.4022 * (v - 128)G = y - 0.3456 * (u - 128) - 0.7145 * (v - 128)B = y + 1.771 * (u - 128)
好,有了这些理论知识后, 我们开始写代码吧。
三、RGB24_to_YUV420_I420 代码实现
本代码中数据格式分别为:RGB24 及 YUV420 I420。
#include <stdio.h>
#include <stdlib.h>//判断不前环境是大端还是小端
int checkCPU()
{union w{int a;char b;}c;c.a = 1;return (c.b == 1); //小端返回true,大端返回false
}int RGB24_to_I420()
{int Width=720, Height=480; // 设置图片宽高 int i, j, k, cpu=checkCPU(); // 获取当前CPU是大端还是小端 unsigned char r, g, b;//打开RGB24 源图 及 创建YUV420 I420图片文件FILE *fp_s = fopen("XueNv.rgb", "rb+");FILE *fp_d = fopen("XueNv_YUV420_I420.yuv", "wb+");//分配内存并读取 rgb24 图片数据unsigned char *b_s = (unsigned char *)malloc(sizeof(char)*Width*Height*3);unsigned char *b_d_y = (unsigned char *)malloc(sizeof(char)*Width*Height), *p_y=b_d_y;unsigned char *b_d_u = (unsigned char *)malloc(sizeof(char)*Width*Height/4), *p_u=b_d_u;unsigned char *b_d_v = (unsigned char *)malloc(sizeof(char)*Width*Height/4), *p_v=b_d_v;i = fread(b_s, 1, Width*Height*3, fp_s);printf("读取了%d个字节\n", i);printf("当前是CPU是%s存储模式,开始转换数据\n", cpu==1?"小端":"大端");// 开始数据转换for(i = 0; i<Height; i++){for(j = 0; j<Width; j++){if(cpu){ // 小端时,数据存储为 RGB RGB RGB r = b_s[3*(i*Width + j) + 0];g = b_s[3*(i*Width + j) + 1];b = b_s[3*(i*Width + j) + 2]; }else{ // 大端时,数据存储为 BGR BGR BGR r = b_s[3*(i*Width + j) + 2];g = b_s[3*(i*Width + j) + 1];b = b_s[3*(i*Width + j) + 0]; }*p_y++= (unsigned char)( ( 66 * r + 129 * g + 25 * b + 128) >> 8) + 16;// 每 4 个Y,取一个U ,一个V if(j%2==0 && i%2==0){ *p_u++= (unsigned char)( ( -38 * r - 74 * g + 112 * b + 128) >> 8) + 128 ; *p_v++= (unsigned char)( ( 112 * r - 94 * g - 18 * b + 128) >> 8) + 128 ;} }}printf("\n数据转换完毕\n");// 保存YUV图片i = fwrite(b_d_y, 1, Width*Height, fp_d);printf("写入了%d个字节\n", i); i = fwrite(b_d_u, 1, Width*Height/4, fp_d); printf("写入了%d个字节\n", i);i = fwrite(b_d_v, 1, Width*Height/4, fp_d); printf("写入了%d个字节\n", i);// 释放内存,关闭文件free(b_s);free(b_d_y);free(b_d_u);free(b_d_v); fclose(fp_s);fclose(fp_d);
} int main(void)
{RGB24_to_I420();printf("\n\n");return 0;
}
运行结果如下:
《视音频数据处理入门:RGB、YUV像素数据处理》
【音视频数据数据处理 6】【RGB篇】将RGB24图片转为YUV420格式图片相关推荐
- 【音视频数据数据处理 7】【RGB/BMP篇】生成24色 RGB24图 和 BMP图
[音视频数据数据处理 7][RGB篇]生成一张24色 RGB24图 和 BMP图 一.生成24色 RGB24图代码实现 二.生成24色 BMP图代码实现 先上24色图,及其对应的RGB值. 本文地址: ...
- 【音视频数据数据处理 1】【YUV篇】分离YUV420P像素数据中的Y、U、V分量
[音视频数据数据处理 1][YUV篇]分离YUV420P像素数据中的Y.U.V分量 一.YUV420P 数据格式介绍 二.分离YUV420P像素数据中的Y.U.V分量 - 代码实现 三.查看生成的YU ...
- 【音视频数据数据处理 12】【H.264篇】解析H.264原始码流中的I帧 / P帧 / B帧数据(暂未解决,本文先放着,来日更新)
[音视频数据数据处理 12][H.264篇]解析H.264原始码流中的I帧 / P帧 / B帧数据 一.如何判断是 I帧 / P帧 / B帧 1.1 slice_type 1.2 slice_head ...
- 【音视频数据数据处理 10】【PCM篇】将PCM转为WAV格式音频
[音视频数据数据处理 10][PCM篇]将PCM转为WAV格式音频 一.WAV头信息 1.1 RIFF区块 1.2 FORMAT区块 1.3 DATA区块 二.PCM 转 WAV 代码实现 PCM转为 ...
- 【音视频数据数据处理 14】【FLV篇】解析FLV视频码流,并分离FLV中的视频及MP3音频文件
[音视频数据数据处理 14][FLV篇]解析FLV视频码流,并分离FLV中的视频及MP3音频文件 一.FLV封装原理 1.1 Tag Data 1.1.1 Audio Tag Data结构(音频Tag ...
- 音视频方案,音视频扩展内容- 音视频数据解析,码流分析及质量评价(笔记)3
-- 音视频编解码流程如下图: -- 关于音频各种参数: freq:音频数据的采样率.常用的有48000,44100等. format:音频数据的格式.举例几种格式: AUDIO_U16SYS:Uns ...
- 1小时学会:最简单的iOS直播推流(三)使用系统接口捕获音视频数据
最简单的iOS 推流代码,视频捕获,软编码(faac,x264),硬编码(aac,h264),美颜,flv编码,rtmp协议,陆续更新代码解析,你想学的知识这里都有,愿意懂直播技术的同学快来看!! 源 ...
- WebRTC系列-RTCDataChannel发送非音视频数据
文章目录 1. RTCDataChannel基本介绍 2. RTCDataChannel实战 2.1 negotiated=false 创建及事件处理 2.2 negotiated= true 创建及 ...
- vlc-android对于通过Live555接收到音视频数据包后的处理分析
转载地址:https://blog.csdn.net/c_m_deng/article/details/8487456 通过ndk-gdb跟踪调试vlc-android来分析从连接到RTSP服务器并接 ...
- AVI文件的音视频数据简析
AVI文件的音视频数据 如图是使用AtomicBrowser2(AVI)打开的一个AVI文件: AVI文件从其RIFF标识符后跟的'AVI'开始. 其数据格式如下: 视频音频的放置方式 其中LIST ...
最新文章
- 基于 CNN 特征区域进行目标检测
- AI算法透明不是必须,黑箱和可解释性可简化为优化问题
- Android 4.0 Notification
- SAP ABAP实用技巧介绍系列之 快速找出function module的帮助文档
- 将Vue+Nodejs项目部署到阿里云服务器
- plotplay恢复默认设置_手把手解答win10系统potplayer经常弹出自动更新提示的还原技巧...
- 在64位操作系统上使用FlashDevelop的Debug功能
- Android自动调整TextView的大小
- 百度开源深度学习框架【飞桨——PaddlePaddle】学习实践一
- pytorch ocr_使用PyTorch解决CAPTCHA(不使用OCR)
- springmvc 表单中文乱码解决方案
- 【原型设计】第一节:Axure RP9 下载安装、汉化和激活使用的方法教程
- WEB入门.九 导航菜单
- 怎么查询电脑mac地址
- Redis学习(二):redis集群之cluster模式下的跨节点的批量操作 I
- 503错误的原因和解决方法
- MySQL必知必会(1)
- 从0到1:微信小程序自选股项目回忆录
- Jacoco-报告改造实践
- 【minimal problem】资料整理
热门文章
- cmd下载ftp文件
- 【Android安全】ActivityManager.isUserAMonkey API
- EnableViewState详细分析
- 三星手机刷机后显示无服务器,三星Odin刷机工具连接不上_Odin工具识别不了手机的问题...
- 使用ZUNE从marketplace安装wp7 app的方法
- Django logging日志模块详解(日志记录模板配置)
- LoadRunner教程01:性能测试常见用语
- 【简约美女win7主题】_8.4
- 四川大学转专业到计算机学院面试,2016年本科生转专业工作面试通知
- 周育如的音标口诀大全_音标记忆顺口溜(48个),快速记忆音标口诀!