OpenGLES 相机 LUT 滤镜

左侧为 LUT 滤镜效果,右侧为原图

什么是 LUT ? LUT 是 Look Up Table 的简称,称作颜色查找表,是一种针对色彩空间的管理和转换技术。

它可以分为一维 LUT(1D LUT) 和 三维 LUT(3D LUT),其中三维 LUT 比较常用。简单来讲,LUT 就是一个 RGB 组合到另一个 RGB 组合的映射关系表。

LUT(R, G, B) = (R1, G1, B1)

LUT 滤镜是一种比较经典的滤镜,本质上属于独立像素点替换,即根据 OpenGL 采样器对纹理进行采样得到的像素点,再基于像素点的(R,G,B)分量查表,获得 LUT 映射的(R1,G1,B1),替换原来的输出。

一般 RGB 像素占用 3 个字节,包含 3 个分量,每个分量有 256 种取值,那么三维 LUT 模板就可以包含 256 X 256 X 256 种情况,占用 48MB 内存空间。

这样一个 LUT 模板内存占用过大同时也降低了查找的效率,通常会采取下采样方式来降低数据量。

例如可以对三维 LUT 模板每个分量分别进行 64 次采样,这样就获得一个 64 X 64 X 64 大小的映射关系表,对于不在表内的颜色值可以进行插值获得其相似结果。

三维 LUT 模板,即64 X 64 X 64 大小的映射关系表,通常是用一张分辨率为 512 X 512 的二维图片表示,称为 LUT 图(模板图)。

三维 LUT 模板

LUT 图在横竖方向上被分成了 8 X 8 一共 64 个小方格,每一个小方格内的 B(Blue)分量为一个定值,64 个小方格一共表示了 B 分量的 64 种取值。

对于每一个小方格,横竖方向又各自分为 64 个小格,以左下角为原点,横向小格的 R(Red)分量依次增加,纵向小格的 G(Green)分量依次增加。

Lut 图中的一个小方格

至此,我们可以根据原始采样像素 RGB 中的 B 分量值,确定我们要选用 LUT 图中的第几个小格,然后再根据(R,G)分量值为纵横坐标,确定映射的 RGB 组合。

OpenGLES 实现 LUT 滤镜的 GLSL 脚本。

// Lut 滤镜
#version 100
precision highp float;
varying vec2 v_texcoord;//Lut 纹理
uniform sampler2D s_LutTexture;
uniform lowp sampler2D s_textureY;
uniform lowp sampler2D s_textureU;
uniform lowp sampler2D s_textureV;vec4 YuvToRgb(vec2 uv) {float y, u, v, r, g, b;y = texture2D(s_textureY, uv).r;u = texture2D(s_textureU, uv).r;v = texture2D(s_textureV, uv).r;u = u - 0.5;v = v - 0.5;r = y + 1.403 * v;g = y - 0.344 * u - 0.714 * v;b = y + 1.770 * u;return vec4(r, g, b, 1.0);
}void main()
{//原始采样像素的 RGBA 值vec4 textureColor = YuvToRgb(v_texcoord);//获取 B 分量值,确定 LUT 小方格的 index, 取值范围转为 0~63float blueColor = textureColor.b * 63.0;//取与 B 分量值最接近的 2 个小方格的坐标vec2 quad1;quad1.y = floor(floor(blueColor) / 8.0);quad1.x = floor(blueColor) - (quad1.y * 8.0);vec2 quad2;quad2.y = floor(ceil(blueColor) / 7.9999);quad2.x = ceil(blueColor) - (quad2.y * 8.0);//通过 R 和 G 分量的值确定小方格内目标映射的 RGB 组合的坐标,然后归一化,转化为纹理坐标。vec2 texPos1;texPos1.x = (quad1.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.r);texPos1.y = (quad1.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.g);vec2 texPos2;texPos2.x = (quad2.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.r);texPos2.y = (quad2.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.g);//取目标映射对应的像素值vec4 newColor1 = texture2D(s_LutTexture, texPos1);vec4 newColor2 = texture2D(s_LutTexture, texPos2);//使用 Mix 方法对 2 个边界像素值进行混合vec4 newColor = mix(newColor1, newColor2, fract(blueColor));gl_FragColor = mix(textureColor, vec4(newColor.rgb, textureColor.w), 1.0);
}

LUT 滤镜对比图

LUT 滤镜对比图

技术交流,欢迎加我微信:ezglumes ,拉你入技术交流群。

推荐阅读:

音视频面试基础题

OpenGL ES 学习资源分享

一文读懂 YUV 的采样与格式

OpenGL 之 GPUImage 源码分析

推荐几个堪称教科书级别的 Android 音视频入门项目

觉得不错,点个在看呗~

OpenGL ES 相机 LUT 滤镜相关推荐

  1. IOS – OpenGL ES 设置图像滤镜 GPUImageAmatorkaFilter

    目录 一.简介 二.效果演示 三.源码下载 四.猜你喜欢 零基础 OpenGL (ES) 学习路线推荐 : OpenGL (ES) 学习目录 >> OpenGL ES 基础 零基础 Ope ...

  2. OpenGL ES 之 LUT(滤镜基准图)

    前言 Look Up Table(简称LUT,查找表).输入一个值,然后通过查找表来得到一个输出值. 在调色领域中,称为颜色查找表,查找表的分量为R.G.B,是一种降低GPU运算量的技术,通过将颜色值 ...

  3. android opengl分屏,OpenGL ES 分屏滤镜

    想要绘制滤镜首先我们需要清楚如何绘制纹理,如果不了解的可以参考 OpenGL ES 纹理绘制. 这篇文章中绘制的图片是倒立的,我们需要将图片反转过来.方法很多,这里就简单介绍一种常用的方法,反转坐标系 ...

  4. OpenGL ES FragmentShader 常见滤镜

    转载自:https://www.jianshu.com/p/a434982f04bf 1.原图 precision highp float; varying lowp vec2 varingCoord ...

  5. OpenGL ES:视频加滤镜后导出

    视频加滤镜播放: MediaCodec解码-->OpenGL es--> GLSurfaceView 视频滤镜合成导出: MediaCodec解码-->OpenGL es--> ...

  6. IOS – OpenGL ES 图像CGA色彩滤镜 GPUImageCGAColorspaceFilter

    目录 一.简介 二.效果演示 三.源码下载 四.猜你喜欢 零基础 OpenGL (ES) 学习路线推荐 : OpenGL (ES) 学习目录 >> OpenGL ES 基础 零基础 Ope ...

  7. Android OpenGL ES 从入门到精通系统性学习教程

    1 为什么要写这个教程 目前这个 OpenGL ES 极简教程的更新暂时告一段落,在此之前,很荣幸获得了阮一峰老师的推荐. 因为在工作中频繁使用 OpenGL ES 做一些特效.滤镜之类的效果,加上平 ...

  8. IOS OpenGL ES GPUImage 滤色混合 GPUImageScreenBlendFilter

    目录 一.简介 二.效果演示 三.源码下载 四.猜你喜欢 零基础 OpenGL (ES) 学习路线推荐 : OpenGL (ES) 学习目录 >> OpenGL ES 基础 零基础 Ope ...

  9. IOS – OpenGL ES 图像柏林噪点/花边噪点 GPUImagePerlinNoiseFilter

    目录 一.简介 二.效果演示 三.源码下载 四.猜你喜欢 零基础 OpenGL (ES) 学习路线推荐 : OpenGL (ES) 学习目录 >> OpenGL ES 基础 零基础 Ope ...

最新文章

  1. Web新动力 ——Ajax
  2. 42HS48EIS步进闭环电机最大转速
  3. 百度云使用第三方工具下载文件
  4. C++ Primer 5th笔记(chap 18 大型程序工具)noexcept
  5. 使用Boost.Compute类在GPU上设置和运行简单的矢量加法内核
  6. app_offline.htm 是确有其事
  7. 用c语言编程序输入一个正整数,编写一个程序,输入一个正整数n(假设n7),求1!+2!+3!+4!+……+n!...
  8. 剑指 offer 编程题 C++ 版总结(中)
  9. Linux 基本命令不能用的解决方法
  10. python await timeout_python等待10秒执行下一命令的方法
  11. C语言程序设计 目录
  12. 随书光盘资源下载/提取码(二)
  13. 计算机重启 ie 被改,IE浏览器首页被篡改怎么办 如何重置IE还原到最初的安装状态...
  14. BLENDER快捷键(个人防止忘记的几个快捷键)
  15. 使用Syncthing文件同步工具在两台Windows server服务器实现文件同步(实战)
  16. 2019年7月4日西藏17日之旅
  17. JS 实现列表移动(JQuery实现)
  18. 高质量外链的十大特性
  19. Delphi之API函数
  20. 生产排程系统_生产计划排程APS系统中排产算法的探讨

热门文章

  1. 常用元器件使用方法35:SPI Flash芯片W25Q128JVSIQ
  2. Linux 让普通用户拥有root的权限
  3. 千万不要给手机root权限
  4. 离散型随机变量及其分布律
  5. 什么是Web开发?如何成为一个Python Web开发人员?
  6. MerkleTree
  7. JAVA链表习题---回文结构(详细图解)
  8. windows7 onekey系统还原 及 分区
  9. 网络安全学科复习知识点个人整理
  10. java高级工程师必会专业技能