Delphi影像處理 — 線性亮度/對比調整

來源:互聯網
上載者:User

閱讀提示:

    《Delphi影像處理》系列以效率為側重點,一般代碼為PASCAL,核心代碼採用BASM。

    《C++影像處理》系列以代碼清晰,可讀性為主,全部使用C++代碼。

    儘可能保持二者內容一致,可相互對照。

   本文代碼必須包括文章《Delphi影像處理 -- 資料類型及公用過程》中的ImageData.pas單元。

 

    本文代碼是在《Delphi影像處理 -- 亮度/對比調整》基礎上,通過改非亮度為線性亮度而成的。

    映像亮度調整分為非線性和線性兩種方法。

    非線性映像亮度是將映像像素的R、G、B分別加上或減去某個值,其優點是代碼簡單,亮度調整速度快;缺點是映像資訊損失較大,調整過的 映像顯得平淡,無層次感。

    線性映像亮度一般是將映像像素的RGB轉換為HSL(HSV)等色彩空間,對L(V)部分進行增減調整後,再轉換為RGB色彩空間,優點是調整過映像層次感很強;缺點是代碼較複雜,調整速度慢,而且當映像亮度增減量較大時有很大的失真。

    針對上面兩種方法的優缺點,本人蔘照Photoshop的對比、飽和度調整原理(可參見本人的有關文章),對映像亮度調整方法進行了改進,經測試,效果還不錯,主要有不失真調整範圍寬、有較好的層次感、儘可能減少映像資訊損失量等;同時,在代碼處理上,採用了灰階表尋找法,先按製造了一個256個元素大小的線性亮度/對比尋找表,然後對映像資料逐像素按R、G、B分量值在尋找表中取得調整後的資料,因此處理速度同《Delphi影像處理 -- 亮度/對比調整》中的非線性亮度/對比是基本相同的。

    原理用公式表示為:

    如果亮度增減量value範圍為 -1  --  +1,當value > 0時:

      rgb = RGB + RGB * (1 / (1 - value) - 1)

    當value < 0時:

      rgb = RGB + RGB * value

    下面是映像線性亮度/對比調整代碼:

function _CheckRgb(Rgb: Integer): Integer;asm    test    eax, eax    jge     @@1    xor     eax, eax    ret@@1:    cmp     eax, 255    jle     @@2    mov     eax, 255@@2:end;procedure ImageLineBrightContrast(var Data: TImageData; Bright, Contrast, Threshold: Integer);var  vs: TGrayTable;  cv, bv: Single;  i, v: Integer;  height, dataOffset: Integer;begin  if (Bright = 0) and (Contrast = 0) then Exit;  if Bright <= -255 then bv := -1 else bv := Bright / 255;  if (Bright > 0) and (Bright < 255) then    bv := 1 / (1 - bv) - 1;  if Contrast <= -255 then cv := -1 else cv := Contrast / 255;  if (Contrast > 0) and (Contrast < 255) then    cv := 1 / (1 - cv) - 1;  for i := 0 to 255 do  begin    if Contrast > 0 then v := _CheckRgb(i + Round(i * bv)) else v := i;    if Contrast >= 255 then    begin      if v >= Threshold then v := 255 else v := 0;    end    else      v := _CheckRgb(v + Round((v - Threshold) * cv));    if Contrast <= 0 then vs[i] := _CheckRgb(v + Round(v * bv)) else vs[i] := v;  end;  asm    mov     eax, Data    call    _SetDataRegs    mov     height, edx    mov     dataOffset, ebx    lea     esi, vs;@@yLoop:    push    ecx@@xLoop:    movzx   eax, [edi].TARGBQuad.Blue    movzx   ebx, [edi].TARGBQuad.Green    movzx   edx, [edi].TARGBQuad.Red    mov     al, [esi+eax]    mov     bl, [esi+ebx]    mov     dl, [esi+edx]    mov     [edi].TARGBQuad.Blue, al    mov     [edi].TARGBQuad.Green, bl    mov     [edi].TARGBQuad.Red, dl    add     edi, 4    loop    @@xLoop    pop     ecx    add     edi, dataOffset    dec     height    jnz     @@yLoop@@Exit:  end;end;

 

    下面是用RGB非線性亮度調整(中)、HSL線性亮度調整(右)以及本文介紹的改進線性亮度調整方法(左)對同一照片的調整結果貼圖:

                      原圖:

   

    《Delphi影像處理》系列使用GDI+單元和說明見文章《GDI+ for VCL基礎 -- GDI+ 與 VCL》。

    因水平有限,錯誤在所難免,歡迎指正和指導。郵箱地址:maozefa@hotmail.com

    這裡可訪問《Delphi影像處理 -- 文章索引》。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.