1. 程式人生 > >影象濾鏡研究——基礎概念

影象濾鏡研究——基礎概念

最近寫自己的個人專案,是用OpenGL去實現一個拍視訊的應用,可以在寫濾鏡這一塊,遇到了麻煩,對於影象方面的知識不足,導致自己理解不了那些濾鏡的編寫,現在先補充一下基本知識。

影象中基本概念:色調,色相,飽和度,對比度,亮度

對比度:

對比度值不同顏色之間的差別。對比度越大,不同顏色之間的反差越大,即所謂黑白分明,對比度過大,影象就會顯得很刺眼。對比度越小,不同顏色之間的反差就越小。

亮度:

亮度指照射在景物或影象上光線的明暗程度。影象亮度增加時,就會顯得耀眼或刺眼。亮度越小時,影象就會顯得灰暗。

色調:

色調是各種影象色彩模式下原色的明暗程度,級別範圍從0到255,共256級色調。例如灰度影象,當色調級別為255時,就是白色,當級別為0時,就是黑色,中間是各種程度不同的灰色。在RGB模式中,色調代表紅,綠,藍三種原色的明暗程度,對綠色就有淡綠,深綠,深綠等不同的色調。
色調是指色彩外觀基本傾向。在明度,純度,色相這三個要素中,某種因素起主導作用,可以稱為某種色調。

色相:

色相就是顏色,調整色相就是調整景物的顏色,例如,彩虹由紅、橙、黃、綠、青、藍、紫七色組成,那麼它就有七種色相。顧名思義即各類色彩的相貌稱謂,如大紅,普藍等。色相是色彩的首要特徵,是區別不同色彩的最準確的標準,事實上任何黑白灰以外的顏色都有色相的屬性,而色相也就是由原色(三原色),間色(由三原色調配出來的顏色)和複色(複色是用原色與間色相調或用間色與間色相調而成的“三次色”)來構成的。

飽和度:

飽和度是指影象顏色的濃度。飽和度越高,顏色越飽滿,即所謂的青翠欲滴的感覺。飽和度越低,顏色就會顯得越懷舊,慘淡。飽和度越0時,影象就為灰度影象。


在影象處理中,常見的顏色模型包括HSB(色相、飽和度、亮度)、RGB(紅色、綠色、藍色)、CMYK(青色、品紅、黃色、黑色)和CIE La

b*等,因此,相應的顏色模式也就有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