程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> 由圖像的灰度化看基本圖像處理(3)

由圖像的灰度化看基本圖像處理(3)

編輯:Delphi

  [優化篇]

  還以上篇中給出的灰度化代碼為例

  procedure Grayscale(const Bitmap:TBitmap);
  var
    X: Integer;
    Y: Integer;
    PRGB: pRGBTriple;
    Gray: Byte;
  begin
    for Y := 0 to (Bitmap.Height - 1) do
    begin
      PRGB := Bitmap.ScanLine[Y];
      for X := 0 to (Bitmap.Width - 1) do
      begin
        Gray := Trunc(0.3 * PRGB^.rgbtRed + 0.59 * PRGB^.rgbtGreen + 0.11 * PRGB^.rgbtBlue);
        PRGB^.rgbtRed:=Gray;
        PRGB^.rgbtGreen:=Gray;
        PRGB^.rgbtBlue:=Gray;
        Inc(PRGB);
      end;
    end;
  end;

  實際應用中,這種方法已經很快了,但實際上還存在可以優化的余地。

  Gray := Trunc(0.3 * Red + 0.59 * Green + 0.11 * Blue);//這句用的是浮點運算

  在圖像處理中,速度就是生命,能不用浮點運算,就最好不要用!

  Gray := (30 * Red + 59 * Green + 11 * Blue) div 100;
  雖然這樣一改,運算次數多了一次,但在我的雷鳥1.1G上,處理速度大概能提高5%左右!而同主頻下(或略低,如Athlon 1600+相當於P4 1.6G)AMD的CPU浮點運算能力比Intel的較強,整數運算能力較弱,所以用Intel的CPU在這裡更能體現出優勢!

  注:x div 100 和 Trunc(x/100)的效果是相同的,但查看其匯編代碼可知一個用的指令是div,而另一個是fdiv(即進行浮點運算),還要調用函數Trunc,其處理速度差距非常大,所以能用 x div 100 的時候就不要用 Trunc(x/100)。

  但這還不是最快的,再看一個:

  Gray := HiByte(77 * Red + 151 * Green + 28 * Blue);
  即
  Gray := (77 * Red + 151 * Green + 28 * Blue) shr 8;
  (建議用後一種,不要調用函數)

  這種方法比最原始的方法快了近3/4!

  什麼意思呢?用77,151,28分別除以256試試~~~

  移位是什麼意思呢,和10進制的進位,退位聯系一下,是不是可以近似的理解為乘除2的n次方呢?當然這和真正意義的乘除法是不一樣的!比如shr(右移),和真正的除法相比,比如shr 1,只有最後一個字位為0時(既為2的倍數),它才等於除2!如二進制數110(6)右移1位變為11(3),和6/2=3結果相同。

  當然這和一開始的灰度化效果有了些誤差!

  如果允許存在更大的誤差,還可以考慮另一種方法:

  Gray := (Red shr 2) + (Red shr 4) + (Green shr 1) + (Green shr 4) + (Blue shr 3);

  連乘法都沒用,完全用移位實現,結合上面的解釋,用除法來理解該表達式,其值只是約等於(0.3125 * Red + 0.5625 * Green + 0.125 * Blue),和一開始的加權平均值有了比較大的誤差!但如果對速度有苛刻的要求的話,可以怎麼用!這比上一種方法還能再快5%!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved