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. 故四个分量如下:

  1. (s, t)
  2. (s + off, t)
  3. (s + off x 2.0f, t)
  4. (s + off x 3.0f, t)

根据四个像素的 RGBA 值计算出四个 Y 通道的数据作为这个 fragment 的输出颜色。

Luminance

仍然是一个像素四个分量,但是现在代表的是两对 UV 分量。因为根据一个 RGBA 就可以算出 YUV 值,所以此处只需要做一个偏移。

  1. (s, t)
  2. (s + off x 2, t)

这里 offset 的设置可以乘 1 或 2 或 3,我觉得都可以,我只是取中道选择了 2. 将上面两个像素的 UV 分量作为这个 fragment 的输出颜色。

readback pixel

最终用 glReadpixels() 函数,将我们输出的颜色读回来,就完成了。

补充

实际操作中遇到的一个问题是,如果设置了 GL_BLEND, 最终输出的颜色会是混合以后的颜色,记得一定要确认关闭了 blending.

Written with StackEdit.

转载于:https://www.cnblogs.com/psklf/p/8399726.html

GPU 实现 RGB -- YUV 转换 (OpenGL)相关推荐

  1. 最简单的视音频播放演示样例5:OpenGL播放RGB/YUV

    ===================================================== 最简单的视音频播放演示样例系列文章列表: 最简单的视音频播放演示样例1:总述 最简单的视音频 ...

  2. 最简单的视音频播放示例5:OpenGL播放RGB/YUV

    ===================================================== 最简单的视音频播放示例系列文章列表: 最简单的视音频播放示例1:总述 最简单的视音频播放示例 ...

  3. 【DSP开发】【VS开发】YUV与RGB格式转换

    [视频处理]YUV与RGB格式转换 YUV格式具有亮度信息和色彩信息分离的特点,但大多数图像处理操作都是基于RGB格式. 因此当要对图像进行后期处理显示时,需要把YUV格式转换成RGB格式. RGB与 ...

  4. RGB与YUV转换以及存储格式(YIQ)(信号扫描线)(内插补点算法)(紧缩格式(packed formats))(平面格式(planar formats))

    文章目录 色彩空间与色彩模型 色彩空间 色彩模型 不同色彩空间的比较 1.RGB(采集与显示) 2. YUV YCbCr的两种常用格式 1)ITU-R BT.601 conversion 2)JPEG ...

  5. yuv与rgb的转换矩阵推导过程

    文章目录 yuv与rgb的转换矩阵推导过程 yuv与rgb互转公式 yuv420p转rgb888矩阵 优化一下 参考 yuv与rgb的转换矩阵推导过程 在网上经常看到一些shader里用了矩阵就能把y ...

  6. 最简单的视音频播放示例7:SDL2播放RGB/YUV

    最简单的视音频播放示例系列文章列表: 最简单的视音频播放示例1:总述 最简单的视音频播放示例2:GDI播放YUV, RGB 最简单的视音频播放示例3:Direct3D播放YUV,RGB(通过Surfa ...

  7. RGB/YUV/YCbCr--关于显示,颜色你需要了解的一些事

    工作中常听说RGB/YUV/YCbCr 这样一些名词,概念上似乎很混淆?这里是一个简介,部分内容来自wiki,理解不对的地方欢迎指正. A:首先两个基本概念: Color model和Color Sp ...

  8. YUV420P、YUV420SP、NV12、NV21和RGB互相转换并存储为JPEG以及PNG图片

    音视频实践学习 android全平台编译ffmpeg以及x264与fdk-aac实践 ubuntu下使用nginx和nginx-rtmp-module配置直播推流服务器 android全平台编译ffm ...

  9. RGB YUV [转]

    http://jxx.sdecu.com/jpkc/dsyl/jiaoxuefangfa/wangluoketang/seven/7.htm 人类眼睛的色觉,具有特殊的特性,早在上世纪初,Young( ...

最新文章

  1. Ubuntu 组态 Tomcat而每天的错误解决
  2. 【F#2.0系列】介绍String类型
  3. bootstrap操作mysql数据库_前后端连接(BootStrap_MySQL_MyEclipse)
  4. mysql范式与反范式_给女同事讲解MySQL数据库设计范式与反范式,她夸我“技术好”...
  5. Linux-下载传输并安装启动Tomcat
  6. java postdata_java发送post请求,使用multipart form-data的方式传递参数,可实现服务器间文件上传功能...
  7. Educational Codeforces Round 80 (Rated for Div. 2) 二分 + 状压
  8. cloud一分钟 | 腾讯金融云总经理胡利明:腾讯云服务金融的“加减 乘除”法。...
  9. svd奇异值分解_传统推荐算法(一)SVD推荐(1)解读奇异值分解
  10. 【Vue US国际会议】使用Vue和NativeScript来开发吸引人的原生手机app
  11. 远看像乱序执行,近看是内存屏障的BUG是如何解决的?
  12. Android开发学习之以CameraAPI方式实现相机功能(二)——相机功能配置
  13. 语音网关典型配置实例
  14. 韩顺平_JAVA_视频教程_下载(打开迅雷,直接复制链接地址即可下载)
  15. 基于Spring+SpringMVC+Mybatis开发房屋租赁系统
  16. 情人节程序员用HTML网页表白【粉色烂漫的七夕情人节专题页面】 HTML5七夕情人节表白网页源码 HTML+CSS+JavaScript
  17. 锁仓怎么解_锁仓和解锁的方法
  18. android缓存清理代码,安卓缓存清除和计算
  19. 「深度」视觉的层次化处理过时了吗?
  20. 简单自定义协议的封包和解包

热门文章

  1. 孔子、老子、墨子,春秋时期的三位人杰,谁更厉害?
  2. Python学习---Django的request扩展[获取用户设备信息]
  3. sctp和tcp的区别
  4. 学习Mysql命令行
  5. 一个在Windows下的ping脚本(使用WMI 的Win32_PingStatus 实现)
  6. tslib 编译移植步骤
  7. RealARM 210开发板 u-boot传递mac地址到内核的方法
  8. vim语法高亮的错误解决办法
  9. html语言table,HTML table 标签
  10. php解析doc试卷,PHP试题(卷)带答案解析.doc