图像滤镜研究——基础概念

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_36391075/article/details/82888477

最近写自己的个人项目,是用OpenGL去实现一个拍视频的应用,可以在写滤镜这一块,遇到了麻烦,对于图像方面的知识不足,导致自己理解不了那些滤镜的编写,现在先补充一下基本知识。

图像中基本概念:色调,色相,饱和度,对比度,亮度

对比度:

对比度值不同颜色之间的差别。对比度越大,不同颜色之间的反差越大,即所谓黑白分明,对比度过大,图像就会显得很刺眼。对比度越小,不同颜色之间的反差就越小。

亮度:

亮度指照射在景物或图像上光线的明暗程度。图像亮度增加时,就会显得耀眼或刺眼。亮度越小时,图像就会显得灰暗。

色调:

色调是各种图像色彩模式下原色的明暗程度,级别范围从0到255,共256级色调。例如灰度图像,当色调级别为255时,就是白色,当级别为0时,就是黑色,中间是各种程度不同的灰色。在RGB模式中,色调代表红,绿,蓝三种原色的明暗程度,对绿色就有淡绿,深绿,深绿等不同的色调。
色调是指色彩外观基本倾向。在明度,纯度,色相这三个要素中,某种因素起主导作用,可以称为某种色调。

色相:

色相就是颜色,调整色相就是调整景物的颜色,例如,彩虹由红、橙、黄、绿、青、蓝、紫七色组成,那么它就有七种色相。顾名思义即各类色彩的相貌称谓,如大红,普蓝等。色相是色彩的首要特征,是区别不同色彩的最准确的标准,事实上任何黑白灰以外的颜色都有色相的属性,而色相也就是由原色(三原色),间色(由三原色调配出来的颜色)和复色(复色是用原色与间色相调或用间色与间色相调而成的“三次色”)来构成的。

饱和度:

饱和度是指图像颜色的浓度。饱和度越高,颜色越饱满,即所谓的青翠欲滴的感觉。饱和度越低,颜色就会显得越怀旧,惨淡。饱和度越0时,图像就为灰度图像。


在图像处理中,常见的颜色模型包括HSB(色相、饱和度、亮度)、RGB(红色、绿色、蓝色)、CMYK(青色、品红、黄色、黑色)和CIE Lab*等,因此,相应的颜色模式也就有RGB、CMYK、Lab等。在HSB颜色模型中,色相、饱和度、亮度是对图像属性的基本描述。

色相或者色调(Hue)是从物体反射或透过物体传播的颜色。在0°到360°的标准色轮上,按位置度量色相。通常情况下,色相由颜色名称标识,如红色、橙色或绿色。

亮度(Brightness或者intensity)是颜色的相对明暗程度,通常使用从0%(黑色)至100%(白色)的百分比来度量

图像的色调通常是指图像的整体明暗度,例如,如果图像亮部像素较多的话,则图像整体上看起来较为明快。反之,如果图像中暗部像素较多的话,则图像整体上看起来较为昏暗。对于彩色图像而言,图像具有多个色调。通过调整不同颜色通道的色调,可对图像进行细微的调整。

在图像处理的各种颜色模型中,HSB模型以人类对颜色的感觉为基础,描述了颜色的3种基本特性。


下面是我用Android中的ColorMatrix做的:

  1. 把红色的饱和度增加了50:
    在这里插入图片描述

代码如下:

 ColorMatrix matrix = new ColorMatrix();
        Bitmap bitmap =mBitmap.copy(Bitmap.Config.ARGB_8888,true);
        Paint paint = new Paint();
        Canvas canvas = new Canvas(bitmap);
        matrix.set(new float[]{
                1.0f,0.0f,0.0f,0,50,
                0.0f,1.0f,0.0f,0,0,
                0.0f,0.0f,1.0f,0,0,
                0,0,0,1,0
        });
        paint.setColorFilter(new ColorMatrixColorFilter(matrix));
        canvas.drawBitmap(bitmap,0,0,paint);
        mImage.setImageBitmap(bitmap);
  1. 把RGB的饱和度都增加了50:

    在这里插入图片描述

ColorMatrix matrix = new ColorMatrix();
        Bitmap bitmap =mBitmap.copy(Bitmap.Config.ARGB_8888,true);
        Paint paint = new Paint();
        Canvas canvas = new Canvas(bitmap);
        matrix.set(new float[]{
                1.0f,0.0f,0.0f,0,50,
                0.0f,1.0f,0.0f,0,50,
                0.0f,0.0f,1.0f,0,50,
                0,0,0,1,0
        });
        paint.setColorFilter(new ColorMatrixColorFilter(matrix));
        canvas.drawBitmap(bitmap,0,0,paint);
        mImage.setImageBitmap(bitmap);
  1. 怀旧效果:

在这里插入图片描述

 ColorMatrix matrix = new ColorMatrix();
        Bitmap bitmap =mBitmap.copy(Bitmap.Config.ARGB_8888,true);
        Paint paint = new Paint();
        Canvas canvas = new Canvas(bitmap);
        matrix.set(new float[]{
                0.393f,0.769f,0.189f,0,0,
                0.349f,0.686f,0.168f,0,0,
                0.272f,0.534f,0.131f,0,0,
                0,0,0,1,0
        });
        paint.setColorFilter(new ColorMatrixColorFilter(matrix));
        canvas.drawBitmap(bitmap,0,0,paint);
        mImage.setImageBitmap(bitmap);

其实就是降低饱和度

  1. 浮雕效果:

在这里插入图片描述

浮雕的算法就是这一个像素点rgb减去上一个像素点的rgb

   Bitmap bitmap =mBitmap.copy(Bitmap.Config.ARGB_8888,true);

       int[] newP = new int[bitmap.getWidth()*bitmap.getHeight()];
        int[] old = new  int[bitmap.getWidth()*bitmap.getHeight()];

        bitmap.getPixels(old,0,bitmap.getWidth(),0,0,bitmap.getWidth(),bitmap.getHeight());

        for(int i = 1;i<old.length;i++){
            int oldcolor = old[i-1];
            int r0 = Color.red(oldcolor);
            int g0 = Color.green(oldcolor);
            int b0 = Color.blue(oldcolor);
            int a0 = Color.alpha(oldcolor);

            int color = old[i];
            int r = Color.red(color);
            int g = Color.green(color);
            int b = Color.blue(color);
            int a = Color.alpha(color);

            int r1 = r-r0+128;
            if(r1<0){
                r1 = 0;
            }else if(r1>255){
                r1 = 255;
            }

            int g1 = g-g0+128;
            if(g1<0){
                g1 = 0;
            }else if(g1>255){
                g1 = 255;
            }


            int b1 = b-b0+128;
            if(b1<0){
                b1 = 0;
            }else if(b1>255){
                b1 = 255;
            }

            newP[i] = Color.argb(a,r1,g1,b1);

        }

       // paint.setColorFilter(new ColorMatrixColorFilter(matrix));
       // canvas.drawBitmap(bitmap,0,0,paint);
        bitmap.setPixels(newP,0,bitmap.getWidth(),0,0,
                bitmap.getWidth(),bitmap.getHeight());
        mImage.setImageBitmap(bitmap);
  1. 黑白
    在这里插入图片描述
 ColorMatrix matrix = new ColorMatrix();
        Bitmap bitmap =mBitmap.copy(Bitmap.Config.ARGB_8888,true);
        Paint paint = new Paint();
        Canvas canvas = new Canvas(bitmap);
        matrix.set(new float[]{
                0.213f,0.715f,0.072f,0,0,
                0.213f,0.715f,0.072f,0,0,
                0.213f,0.715f,0.072f,0,0,
                0,0,0,1,0
        });
        paint.setColorFilter(new ColorMatrixColorFilter(matrix));
        canvas.drawBitmap(bitmap,0,0,paint);
        mImage.setImageBitmap(bitmap);

黑白的滤镜,主要是灰度图片的去色原理:只要把RGB的三色通道的数值设置为一样,即R=G=B,那么图像就变成了灰色,同时为了保证图像的亮度,需要使同一个通道中的R+G+B的结果接近1

关于colorMatrix可以参考:https://blog.csdn.net/harvic880925/article/details/51187277

图层混合模式

PS中,混合图层是制作滤镜的必需品。

1.正常(Normal)模式:

在“正常模式下”,“混合色”的显示与不透明度的设置有关。当“不透明度”为100%,“结果色”的像素将完全由“混合色”代替;当不透明度小于100%时,混合色的像素会透过所用的颜色显示出来,显示的程度取决于不透明度的设置与“基色”的颜色。如果在处理“位图”颜色模式图像或“索引颜色”颜色模式图像时,正常模式就改称为阀值模式了,不过功能时一样的。

混合色*不透明度+(100%-混合色不透明度)*基色

2.溶解模式(Dissolve)

溶解模式下混合色的不透明度及填充都是100%的话,我们就看不到基色图层。降低混合色图层的不透明度后,我们就会发送结果色中出现了很多细小的颗粒。这些颗粒会随着混合色的不透明度变化。不透明度越低,混合色图层就被溶解的越多。剩下的部分就越少。不透明度越高,混合色图层被溶解的部分就越少,剩下的部分就越多,结果色也就越接近混合色。

3.变暗模式

变暗混合模式下,会把混合色和基色进行对比,分别选择R,G,B三组数值中最小的数值,也就是最暗的颜色作为结果色的数值。这样整个画面就会变暗,如果是彩色图像,颜色也会发生很大的改变。

4.正片叠底:

按照混合色与基色中的各R,G,B值计算,计算公式:结果色R=混合色R * 基色R / 255,G值与B值相同。由于各通道的最大值是255,因此结果色的数值比混合色即基色的数值都要小,也就是结果色要暗。

5.颜色加深

颜色加深可以快速增加图片的暗部。计算公式:(基色 + 混合色 - 255)* 255 /混合色,如果(基色 + 混合色 - 255)出现负数,就直接归0.因此在基色和混合色都较暗时就直接变成黑色了。这样结果色的暗部就会增加。整体效果看上去对比较为强烈。

6.线性加深:

线性加深的计算公式是:结果色 =基色 +混合色 - 255,如果基色 +混合色的数值小于255,结果色就为0。由这个公式可以看出,画面暗部会直接变成黑色。因此画面整体会更暗。白色与基色混合得到基色,黑色与基色混合得到黑色。

7.深色模式:

它是通过计算混合色与基色的所有通道的数值,然后选择数值较小的作为结果色。因此结果色只跟混合色或基色相同,不会产生出另外的颜色。白色与基色混合色得到基色,黑色与基色混合得到黑色。深色模式中,混合色与基色的数值是固定的,我们颠倒位置后,混合色出来的结果色是没有变化的。

8.变凉模式:

变亮混合模式跟变暗模式是相对的,通过混合色与基色的相关数值进行比较,选择较大的数值作为结果色。因此结果色会更亮,同时颜色也会变化。

9.滤色模式:

滤色模式与正片叠底模式相对。她的计算公式是用:255 -混合色的补色* 基色补色 / 255。得到的数据会比混合及基色更大,因此结果色会更亮。从计算公式也可以看出基色或混合色任何一项为255也就是白色,结果色数值就是255为白色。任何一项数值为0,也就是为黑色的话,结果色就跟数值不为0的一致。

10.颜色减淡:

颜色减淡是通过混合色及基色的各通道颜色值进行对比,减少二者的对比度使基色的变亮来反映混合色。
她的计算公式:结果色 = 基色 + (混合色 * 基色) / (255 - 混合色)。混合色为黑色,结果色就等于基色,混合色为白色结果色就为白色。基色为黑色结果色就为黑色。

11. 柔光模式:

柔光模式是较为常用的模式,她是根据混合色的通道数值选择不同的公式计算混合色。数值大于128的时候,结果色就比基色稍亮;数值小于或等于128,结果色就比基色稍暗。柔光模式是以基色为主导,混合色只相应改变局部明暗。其中混合色为黑色,结果色不会为黑色,只比结果色稍暗,混合色为中性色,结果色跟基色一样。
计算公式:
混合色 <=128:结果色 =基色 + (2 混合色 - 255) * (基色 -基色基色 / 255) / 255;
混合色 >128:结果色= 基色 + (2 *混合色 - 255) * (Sqrt(基色/255)*255-基色)/255。

更多的模式参考:https://blog.csdn.net/trent1985/article/details/40891661

猜你喜欢

转载自blog.csdn.net/qq_36391075/article/details/82888477