22019.01.06 16:35:54字数 539阅读 400
图像查表法原理,网上有很多资料有介绍,本文主要参考了https://blog.csdn.net/danffer1985/article/details/78692992 这篇博客,本文仅做自己的知识梳理和记录。如博主有意见可留言。
lookup查表法,简而言之就是,根据原图的像素的RGB值,找到颜色表上的对应位置,然后用颜色表上的RGB值替换原图上的像素的RGB值。基本过程如下:
首先讲一下颜色表是怎么来的。 先上图
lookup.png
这张表对应的是没有经过处理的RGB色彩空间。你可以尝试下,用这张图来查表的话,输出的图像和原图是一样的。
这张表其实是标准RGB立方体色彩空间转换而来的,标准RGB空间如下:
图片来自https://www.cnblogs.com/Free-Thinker/p/5569792.html
它是把三维的色彩空间,沿着蓝色到黑色的方向,像切豆腐一样,一片一片切下来,切了64刀,每一刀得到一个正方形切面(也就是lookup图的一个小正方形),平摊到二维平面上的。所以我们看到,lookup图的左上角的小方块,对应的是RGB空间图右侧的立方体的右上侧的那一面。
我们再看lookup.png这张图,每个小正方形,沿着x轴方向是红色的渐变(从0到255),沿着y轴方向是绿色的渐变(从0到255)。而蓝色的渐变,实际上它是在第三维,经过上面说的从三维立方体切割平铺到了64个小正方形中了。整张图的分辨率是512x512,每个小正方形的分辨率就是512 / 8 = 64,那么渐变的精度就是256 / 64 = 4。
接下来我们分析一下GPUImageLookupFilter的着色器代码,看看如何查表的。代码如下:
NSString *const kGPUImageLookupFragmentShaderString = SHADER_STRING
(
varying highp vec2 textureCoordinate;
varying highp vec2 textureCoordinate2; // TODO: This is not used
uniform sampler2D inputImageTexture;
uniform sampler2D inputImageTexture2; // lookup texture
uniform lowp float intensity;
void main()
{
highp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
//蓝色通道,textureColor.b的范围为(0,1),blueColor范围为(0,63)
highp float blueColor = textureColor.b * 63.0;
//quad1为小于且最靠近要查找颜色所在位置的小正方形
highp vec2 quad1;
quad1.y = floor(floor(blueColor) / 8.0);
quad1.x = floor(blueColor) - (quad1.y * 8.0);
//quad2为大于且最靠近要查找颜色所在位置的小正方形
highp vec2 quad2;
quad2.y = floor(ceil(blueColor) / 8.0);
quad2.x = ceil(blueColor) - (quad2.y * 8.0);
highp vec2 texPos1;
//因为一行有8个小正方形,所以小正方形的边长,转换为纹理坐标时,就是0.125。quad1的位置就是quad1.x * 0.125和quad1.y * 0.125。
//后面0.5/512.0 + ((0.125 - 1.0/512.0) * r);这项,可以写成0.125*r + (0.5-r)/512,实际上就是红色通道对应的位置。绿色通道同理。
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);
highp vec2 texPos2;
//quad2和quad1差不多
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);
lowp vec4 newColor1 = texture2D(inputImageTexture2, texPos1);
lowp vec4 newColor2 = texture2D(inputImageTexture2, texPos2);
//真正的颜色在newColor1和newColor2之间。fract是取分数部分。
lowp vec4 newColor = mix(newColor1, newColor2, fract(blueColor));
gl_FragColor = mix(textureColor, vec4(newColor.rgb, textureColor.w), intensity);
}
);
注释貌似不能很好的解释清楚,再加一张图吧,别的就无能为力了...
4人点赞
GPUImage源码分析
奔向火星005
拥有110钻 (约12.93元)
关注
"小礼物走一走,来简书关注我"
赞赏
全部评论0只看作者
按时间倒序
按时间正序
推荐阅读更多精彩内容-
GPUImage源码阅读(十)
概述 GPUImage是一个著名的图像处理开源库,它让你能够在图片、视频、相机上使用GPU加速的滤镜和其它特效。与...
秦明Qinmin
-
PS快速入门?看这篇经典的万字笔记就够了!
来,这有一份PS入门速效大法。 总有人问阿随君怎么学PS,零基础、非专业、小白该怎么从零到入门,迅速成长为高手呢?...
华道长
-
移动端滤镜开发(五)普通滤镜开发
写在前面的话 上一篇文章对简单滤镜实现有一定的讲解,那么这一篇则是对图像处理更加深层次的说明,对于一张图片怎么处理...
前世小书童
-
2018-08-30
转载自VR设计云课堂Unity Shader入门精要》随书彩色插图 《Unity Shader入门精要》随书彩色插...
水月凡
-
Git理解
参考:http://www.jianshu.com/p/08ad7e427fec 集中式SVN与分布式Git 1...