1. 程式人生 > >影象處理基礎(7):影象的灰度變換(續篇)

影象處理基礎(7):影象的灰度變換(續篇)

            灰度變換,屬於一個非常重要的概念。這裡主要參考《Digital Image Processing》 Rafael C. Gonzalez / Richard E. Woods 的第三章。書中所有的實驗與數學式都採用了8-bit 影象的灰度範圍,也就是0到255這樣一個範圍,這是本書不合理的一個地方。首先,這樣做並不泛用,圖片不一定是8-bit的。其次,在做某些變換的時候,可能會導致溢位。比如,伽馬變化,假設伽馬值為2,那麼灰度為255的畫素點,其變換之後值為65025,這裡就溢位了。當然,要是使用Matlab計算,肯定會處理的非常好,直接使用mat2gray函式就能將其壓縮回0到255。但是要是其他嵌入式平臺處理的時候,直接套用不方便不說,直接按照8-bit的圖來理解很不直觀。因此,我將數學式做了改變,讓其輸入為0到1的浮點數,其輸出也是0到1的浮點數,這樣方便理解。

      本文所使用的圖片,均來源於《Digital Image Processing》的主頁 http://www.imageprocessingplace.com/

       影象反轉

       影象反轉,這個翻譯還是很不恰當的。這裡應該理解為負片變換,負片變換如下所示。
負片變換,主要用於觀察過黑的圖片,負片變換之後,方便觀察。很簡單的變換。

       對數變換

       對數變換主要用於將影象的低灰度值部分擴充套件,將其高灰度值部分壓縮,以達到強調影象低灰度部分的目的。變換方法由下式給出。
這裡的對數變換,底數為,實際計算的時候,需要用換底公式。其輸入為,其輸出也為。對於不同的底數,其對應的變換曲線如下圖所示。
底數越大,對低灰度部分的強調就越強,對高灰度部分的壓縮也就越強。相反的,如果想強調高灰度部分,則用反對數函式就可以了。看下面的實驗就可以很直觀的理解,下圖是某影象的二維傅立葉變換影象,其為了使其灰度部分較為明顯,一般都會使用灰度變換處理一下。

       實現對數變換的Matlab程式碼如下:

    
  1. close all;
  2. clear all;
  3. %% ————-Log Transformations—————–
  4. f = imread( ’DFT_no_log.tif’);
  5. f = mat2gray(f,[ 0 255]);
  6. v = 10;
  7. g_1 = log2( 1 + v*f)/log2(v+ 1);
  8. v = 30;
  9. g_2 = log2( 1 + v*f)/log2(v+ 1);
  10. v = 200;
  11. g_3 = log2( 1 + v*f)/log2(v+ 1);
  12. figure();
  13. subplot( 1, 2, 1);
  14. imshow(f,[ 0 1]);
  15. xlabel( ’a).Original Image’);
  16. subplot( 1, 2, 2);
  17. imshow(g_1,[ 0 1]);
  18. xlabel( ’b).Log Transformations v=10’);
  19. figure();
  20. subplot( 1, 2, 1);
  21. imshow(g_2,[ 0 1]);
  22. xlabel( ’c).Log Transformations v=100’);
  23. subplot( 1, 2, 2);
  24. imshow(g_3,[ 0 1]);
  25. xlabel( ’d).Log Transformations v=200’);

       伽馬變換

       伽馬變換主要用於影象的校正,將漂白的圖片或者是過黑的圖片,進行修正。伽馬變換也常常用於顯示屏的校正,這是一個非常常用的變換。其變化所用數學式如下所示,
其輸入為,其輸出也為對於不同的伽馬值,其對應的變換曲線如下圖所示。

和對數變換一樣,伽馬變換可以強調影象的某個部分。根據下面兩個實驗,可以看出伽馬變換的作用。        實驗1:
其實現Matlab程式碼為:

    
  1. close all;
  2. clear all;
  3. %% ————-Gamma Transformations—————–
  4. f = imread( ’fractured_spine.tif’);
  5. f = mat2gray(f,[ 0 255]);
  6. C = 1;
  7. Gamma = 0.4;
  8. g2 = C*(f.^Gamma);
  9. figure();
  10. subplot( 1, 2, 1);
  11. imshow(f,[ 0 1]);
  12. xlabel( ’a).Original Image’);
  13. subplot( 1, 2, 2);
  14. imshow(g2,[ 0 1]);
  15. xlabel( ’b).Gamma Transformations \gamma = 0.4’);
       實驗2:

       灰度拉伸

       灰度拉伸也用於強調影象的某個部分,與伽馬變換與對數變換不同的是,灰度拉昇可以改善影象的動態範圍。可以將原來低對比度的影象拉伸為高對比度影象。實現灰度拉昇的方法很多,其中最簡單的一種就是線性拉伸。而這裡介紹的方法稍微複雜一些。灰度拉伸所用數學式如下所示。
同樣的,其輸入為,其輸出也為。這個式子再熟悉不過了,跟巴特沃斯高通濾波器像極了,其輸入輸出關係也大致能猜到是個什麼形狀的。但是,這裡就出現一個問題了,輸入為0時候,式子無意義了。所以,在用Matlab計算的時候,將其變為如下形式。
這裡的eps,就是Matlab裡面,一個很小數。如此做的話,式子變得有意義了。但是,其輸入範圍為的時候,其輸出範圍變為了。輸出範圍大致為,為了精確起見,使用mat2gray函式將其擴充套件到精確的。呼叫格式如下。
g = mat2gray(g,[1/(1+(m/eps)^E) 1/(1+(m/1+eps)^E)]);
       輸入輸出問題解決了,還有一個問題,引數的決定。這裡有兩個引數,一個是m(相對於巴特沃斯高通濾波器而言,這個是截止頻率),一個是E(相對於 巴特沃斯高通濾波器而言,這個是濾波器次數)。m可以控制變換曲線的重心,E則可以控制曲線的斜率,如下圖所示。
m值的可取影象灰度分佈的中央值,如下式所示,
       決定m之後,接下來就只剩E了。灰度拉昇的目的就是擴充套件圖片的動態範圍,我們想將原本灰度範圍是的影象變換到內。那麼,就直接取最大值與最小值,帶入式子,解出E就可以了。但是,如之前所說的,我們所用的式子的的輸出範圍達不到,而且,直接取的範圍,會造成E非常大,從而變換曲線的斜率非常大,灰度擴充套件的結果並不是很好。所以,這裡退一步,取的輸出範圍是。E的取值,如下所示。
       實驗:
       從直方圖看,原圖的灰度範圍確實被拉伸了。用上面所說的方法,確定的灰度拉伸的輸入輸出曲線如下圖所示。
      其Matlab程式碼如下:

    
  1. close all;
  2. clear all;
  3. %% ————-Contrast Stretching—————–
  4. f = imread( ’washed_out_pollen_image.tif’);
  5. %f = imread( ’einstein_orig.tif’);
  6. f = mat2gray(f,[0 255]);
  7. [M,N] = size(f);
  8. g = zeros(M,N);
  9. Min_f = min(min(f));
  10. Max_f = max(max(f));
  11. m = (Min_f + Max_f)/2;
  12. Out_put_min = 0.05;
  13. Out_put_max = 0.95;
  14. E_1 = log(1/Out_put_min - 1)/ log(m/(Min_f+eps));
  15. E_2 = log(1/Out_put_max - 1)/ log(m/(Max_f+eps));
  16. E = ceil(min(E_1,E_2)-1);
  17. g = 1 ./(1 + (m ./ (f+ eps)).^E);
  18. g = mat2gray(g,[1/(1+(m/eps)^E) 1/(1+(m/1+eps)^E)]);
  19. figure();
  20. subplot(2,2,1);
  21. imshow(f,[0 1]);
  22. xlabel( ’a).Original Image’);
  23. subplot(2,2,2);
  24. r = imhist(f)/(M*N);
  25. bar(0:1/255:1,r);
  26. axis([0 1 0 max(r)]);
  27. xlabel( ’b).The Histogram of a’);
  28. ylabel( ’Number of pixels’);
  29. subplot(2,2,3);
  30. imshow(g,[0 1]);
  31. xlabel( ’c).Results of Contrast stretching’);
  32. subplot(2,2,4);
  33. s = imhist(g)/(M*N);
  34. bar(0:1/255:1,s);
  35. axis([0 1 0 max(s)]);
  36. xlabel( ’b).The Histogram of a’);
  37. ylabel( ’Number of pixels’);
  38. in_put = 0:1/255:1;
  39. Out_put1 = 1 ./(1 + (m ./ (double(in_put)+ eps)).^E);
  40. Out_put1 = mat2gray(Out_put1,[1/(1+(m/eps)^E) 1/(1+(m/1+eps)^E)]);
  41. figure();
  42. plot(in_put,Out_put1);
  43. axis([0,1,0,1]),grid;
  44. axis square;
  45. xlabel( ’Input intensity level’);
  46. ylabel( ’Onput intensity level’);

       灰度切割

       灰度切割也是一個很簡單,但也很實用的變換。灰度切割,主要用於強調影象的某一部份,將這個部分賦為一個較高的灰度值,其變換對應關係如下所示。
灰度切割有以上兩種方法,一種是特定灰度值的部分賦值為一個較高的灰度值,其餘部分為一個較低的灰度值。這樣的方法,得到的結果是一個二值化影象。另外一種方法,則是僅僅強調部分賦值為一個較高的灰度值,其餘的部分不變。        實驗:

       點陣圖切割

       點陣圖切割,就是按照影象的位,將影象分層處理。若影象的某個畫素,其bit7為1,則在位面7這個畫素值為1,反之則為0。
       實驗:
       由點陣圖切割的結果,影象的主要資訊包含在了高4位。僅僅靠高4位,還原的影象更原圖基本差不多。由此可見,點陣圖切割主要用於影象壓縮。