GPUImage源码分析(五):GPUImageLookupFilter

GPUImage源码分析(五):GPUImageLookupFilter

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空间如下:

扫描二维码关注公众号,回复: 11427266 查看本文章

图片来自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只看作者

按时间倒序

按时间正序

推荐阅读更多精彩内容

猜你喜欢

转载自blog.csdn.net/qq_21743659/article/details/107506197