GPU 实现 RGB -- YUV 转换 (OpenGL)
GPU 实现 RGB -- YUV 转换
前言
RGB --> YUV 转换的公式是现成的,直接在 CPU 端转换的话,只需要遍历每个像素,得到新的 YUV 值,根据其内存分布规律,合理安排分布即可。然而在 CPU 端进行转换,存在的问题运行效率太低,无法满足高效转换的需求。我们将目光投向拥有流水线体系的支持高速浮点数计算的硬件——GPU.
转换公式如下:
GPU 上面的实现
考虑在 GPU 上执行 RGB --> YUV 转换。GPU 的流水线操作:
vertices
----> Pipeline ----> Out color
texture
所以将 RGB 图像作为纹理输入,流水线输出我们需要的 YUV 数据。前面一部分很好理解,图像作为唯一的纹理输入,没有别的选项。后面一部分的话,需要在输出的时候输出我们需要的 YUV 数据即可,在 fragment shader 中的输出按常理就是每一个 fragment 的颜色,为实现读取像素是 YUV 的目标,要调整输出的数据。
考虑 YUV 格式内存分布,以 NV12 为例,一张图片占用内存大小为:width x height * 3 / 2
(我们认为图像的宽为 width 高为 height). 如果是 RGBA 的格式存储的话,占用的内存空间大小是:width x height x 4
(因为 RGBA 一共4个通道)。如果我们把 OpenGL renderbuffer 大小设置成等于图像的大小,那输出的大小就是 RGBA 那一种的大小,和 YUV 格式的是对不上的。考虑 YUV 的分布特点,设计输出的宽高为 (width / 4, height * 3 / 2)
. 示意图如下:
Memory of a frame (yuv format)
width / 4
|-------------|
| |
| | h
| chrominance |
| |
|-------------|
| |
| luminance | h / 2
|-------------|
因为每一个 out color 含有四个分量 RGBA 所以将宽度设为 width / 4, 那么正好每一行的像素就是原来 width 的数量。在 fragment shader 内部计算的时候,需要考虑当前处理的单个 fragment 是属于 chrominance OR luminance, 可以用纹理坐标的 t 值的大小来判断。
Chrominance
所谓的 RGBA 四个分量实际上代表四个不同的像素的 chrominance 值,也就是说需要做一定的 offset, 来获取到当前像素附近的像素的值,我先假定 offset 为 1.0f / width. 故四个分量如下:
- (s, t)
- (s + off, t)
- (s + off x 2.0f, t)
- (s + off x 3.0f, t)
根据四个像素的 RGBA 值计算出四个 Y 通道的数据作为这个 fragment 的输出颜色。
Luminance
仍然是一个像素四个分量,但是现在代表的是两对 UV 分量。因为根据一个 RGBA 就可以算出 YUV 值,所以此处只需要做一个偏移。
- (s, t)
- (s + off x 2, t)
这里 offset 的设置可以乘 1 或 2 或 3,我觉得都可以,我只是取中道选择了 2. 将上面两个像素的 UV 分量作为这个 fragment 的输出颜色。
readback pixel
最终用 glReadpixels()
函数,将我们输出的颜色读回来,就完成了。
补充
实际操作中遇到的一个问题是,如果设置了 GL_BLEND
, 最终输出的颜色会是混合以后的颜色,记得一定要确认关闭了 blending.
Written with StackEdit.
GPU 实现 RGB -- YUV 转换 (OpenGL)的更多相关文章
- 最简单的视音频播放示例5:OpenGL播放RGB/YUV
本文记录OpenGL播放视频的技术.OpenGL是一个和Direct3D同一层面的技术.相比于Direct3D,OpenGL具有跨平台的优势.尽管在游戏领域,DirectX的影响力已渐渐超越OpenG ...
- 最简单的视音频播放演示样例5:OpenGL播放RGB/YUV
===================================================== 最简单的视音频播放演示样例系列文章列表: 最简单的视音频播放演示样例1:总述 最简单的视音频 ...
- 【视频处理】YUV与RGB格式转换
YUV格式具有亮度信息和色彩信息分离的特点,但大多数图像处理操作都是基于RGB格式. 因此当要对图像进行后期处理显示时,需要把YUV格式转换成RGB格式. RGB与YUV的变换公式如下: YUV(25 ...
- YUV转换成RGB算法
YUV转换成RGB void yuvtorgb ( double *rgb,unsigned char *yuv) { int i; rgb[] = ] + + ] - ); // r rgb[] = ...
- YUV与RGB格式转换
YUV格式具有亮度信息和色彩信息分离的特点,但大多数图像处理操作都是基于RGB格式. 因此当要对图像进行后期处理显示时,需要把YUV格式转换成RGB格式. RGB与YUV的变换公式如下: YUV(25 ...
- YUV RGB 格式转换
第一个公式是RGB转YUV(范围0-255)时用的,第二个公式是用在YUV转换RGB(范围0-255)时用的.1. Y = ; U = -; V = ; 黑色:Y=16 ,U= V =128 红色:Y ...
- 【图像处理与医学图像处理】YUV与RGB格式转换速度几种方法对比
[视频处理]YUV与RGB格式转换 YUV格式具有亮度信息和色彩信息分离的特点,但大多数图像处理操作都是基于RGB格式. 因此当要对图像进行后期处理显示时,需要把YUV格式转换成RGB格式. RGB与 ...
- 【DSP开发】【VS开发】YUV与RGB格式转换
[视频处理]YUV与RGB格式转换 YUV格式具有亮度信息和色彩信息分离的特点,但大多数图像处理操作都是基于RGB格式. 因此当要对图像进行后期处理显示时,需要把YUV格式转换成RGB格式. RGB与 ...
- Android平台Camera实时滤镜实现方法探讨(三)--通过Shader实现YUV转换RBG
http://blog.csdn.net/oshunz/article/details/50055057 文章例如该链接通过将YUV分成三个纹理,在shader中取出并且经过公式变换,转换成RGB.我 ...
随机推荐
- Hive Getting Started补充
配置管理概述 Hive从<install-dir>/conf/hive-default.xml中读取它的默认配置 Hive配置目录的位置可以通过设置HIVE_CONF_DIR环境变量的值来 ...
- 使用腾讯云无服务器云函数(SCF)分析天气数据
欢迎大家前往云+社区,获取更多腾讯海量技术实践干货哦~ 作者:李想 无服务器云函数(SCF)是腾讯云提供的Serverless执行环境,也是国内首款FaaS(Function as a Service ...
- 记录一次APP的转让流程
由于业务需要,需要将开发的App从一个账号(A账号)转移到另一个账号(B账号),这里简单介绍一下转让流程.主要包括两大步骤: 转让方(A账号)提出转让申请 接收方(B账号)接受转让App 如果不想看这 ...
- jsp基础了解
1.什么是动态页面: 所谓的动态网页,是指跟静态网页相对的一种网页编程技术.静态网页,随着html代码的生成,页面的内容和显示效果就基本上不会发生变化了--除非你修改页面代码.而动态网页则不然, ...
- mongodb 的基本函数语法封装
//这个模块里面封装了所有对数据库的常用操作 var MongoClient = require('mongodb').MongoClient; var config = require(" ...
- mwValidate.js验证插件
这段时间在公司一直做项目的同时,也学了下js,感觉有必要做一些什么东西出来.思来想去就做了最简单的一个验证插件.我很清楚这个东西市面上已经很多了,但我的目的也很清楚,检验我的学习成果.所以也就无所谓了 ...
- RabbitMQ入门HelloWorld(C#)(翻译)
介绍 先决条件 本教程假定RabbitMQ已安装并在标准端口(5672)上的本地主机上运行.如果您使用不同的主机,端口或凭据,连接设置将需要调整. 在哪里得到帮助 如果您在阅读本教程时遇到困难,可以 ...
- 前端 IoC 理念入门
背景 近几年,前端应用(WebApp)正朝着大规模方向发展,在这个过程中我们会对项目拆解成多个模块/组件来组合使用,以此提高我们代码的复用性,最终提高研发效率. 在编写一个复杂组件的时候,总会依赖其他 ...
- 【Java学习笔记之八】JavaBean中布尔类型使用注意事项
JavaBean是一个标准,遵循标准的Bean是一个带有属性和getters/setters方法的Java类. JavaBean的定义很简单,但是还有有一些地方需要注意,例如Bean中含有boolea ...
- 哈密顿绕行世界问题(dfs+记录路径)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2181 哈密顿绕行世界问题 Time Limit: 3000/1000 MS (Java/Others) ...