Delphi画像処理--輝度/コントラスト調整


ヒントを読む:
「Delphi画像処理」シリーズは効率に重点を置き、一般コードはPASCAL、コアコードはBASMを採用している.
「C++画像処理」シリーズはコードがはっきりしていて、可読性が主で、すべてC++コードを使用しています.
できるだけ両者の内容を一致させ、互いに対照することができる.
本明細書のコードは、文書「Delphi画像処理--データ型および共通プロセス」のImageDataを含む必要がある.pasユニット.
  
本人は輝度調整に関する文章を何編か書いたことがあるが、画像のコントラスト調整の過程と文章はずっと書いていない.その原因はずっと良いアルゴリズムが見つからなかったからだ.画像の明るさ、コントラストの調整は最も簡単なグラフィック操作だと言う人もいるかもしれませんが、そのアルゴリズムはネット上では大きな検索と言えます.確かにそうですが、この最も簡単な操作です.ネット上の文章はいろいろあります.私はいくつか選んでみましたが、理想的ではないようです.肝心なのはアルゴリズムが簡単すぎて、実際の操作効果が悪いと思っています.Photoshopのコントラストは比較的に良くて、その上通用して、しかしあいにくネット上でそのアルゴリズムを紹介していないで、半日の時間を使って研究して、更に1時間ぐらいDelphiの過程を書いて、試してみて、意外にもPhotoshopのコントラストと完全に同じ効果を調整します!そこで真剣にテストプログラムを書いて、明るさとコントラストを一緒に調整しました(明るさとコントラストの処理過程はそれぞれ独立していて、その中の明るさの過程は基本的に本BLOGの文章《GDI+Delphiプログラムの応用--画像の明るさを調整する》のコードです)が、効果はPhotoshopと大きく異なりました.Photoshopの輝度調整アルゴリズムは最も簡単なもので、私の輝度過程と同じように作られています(効果比較図は『GDI+Delphiプログラムでの応用--線形調整画像輝度』を参照).前述したように、コントラストプロセスアルゴリズムもPhotoshopと同じで、一緒に調整してはいけません.まず輝度を調整しても、やはりコントラストを調整してみましょう.後で詳しく分析すると、Photoshopは輝度/コントラストを1つの関数で処理し、輝度調整はコントラストの正負でそれぞれ処理され、以下は実装コード(簡単な例を含む):
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 ImageBrightContrast(var Data: TImageData; Bright, Contrast, Threshold: Integer);
var
  vs: TGrayTable;
  cv: Single;
  i, v: Integer;
  height, dataOffset: Integer;
begin
  if (Bright = 0) and (Contrast = 0) then Exit;
  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 + bright) 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 + bright) 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;

procedure TForm1.Button3Click(Sender: TObject);
var
  bmp: TGpBitmap;
  g: TGpGraphics;
  data: TImageData;
begin
  bmp := TGpBitmap.Create('..\media\source1.jpg');
  g := TGpGraphics.Create(Canvas.Handle);
  g.DrawImage(bmp, 0, 0);
  data := LockGpBitmap(bmp);
  ImageBrightContrast(data, 50, 0, 121);
  UnlockGpBitmap(bmp, data);
  g.DrawImage(bmp, data.Width, 0);
  g.Free;
  bmp.Free;
end;

 
輝度/コントラストの原理を簡単にご紹介します.
一、Photoshopコントラストアルゴリズム.次の式で表すことができます.
    (1)、nRGB = RGB + (RGB - Threshold) * Contrast/255
式中、nRGBは画像画素の新しいR、G、B成分を表し、RGBは画像画素R、G、B成分を表し、Thresholdは所定の閾値であり、Contrastは処理済みのコントラスト増分である.
Photoshopは、コントラスト増分に対して、所与の値の正負でそれぞれ処理されます.
増分が-255に等しい場合は、画像コントラストの下端限界であり、この場合、画像RGBの各成分は閾値に等しく、画像は全グレーであり、階調マップには1本の線、すなわち閾値階調しかない.
増分が−255より大きく、0より小さい場合、画像画素の各成分を上記の式で直接計算する.
増分が255に等しい場合、画像コントラストの上端限界であり、実際には画像閾値を設定することに等しく、画像は最大8色からなり、階調図上で最大8本の線、すなわち赤、黄、緑、青、青、紫、黒と白である.
増分が0より大きく255より小さい場合は、増分を次の式(2)で処理してから、上記式(1)でコントラストを計算します.
    (2)、nContrast = 255 * 255/(255 - Contrast) - 255
式中のnContrastは処理後のコントラスト増分であり、Contrastは所与のコントラスト増分である.
二、画像の明るさ調整.本明細書では、最も一般的な非線形輝度調整(Phoposhop CS 3以下のバージョンもこのような輝度調整方式であり、CS 3以上のバージョンもこの輝度調整方式のオプションを保持している)を採用する.
三、画像輝度/コントラスト総合調整アルゴリズム.これは簡単で、輝度、コントラストが同時に調整されると、コントラストが0より大きい場合は、輝度を調整し、コントラストを調整します.コントラストが0より小さい場合は、逆にコントラストを調整してから輝度を調整します.
輝度・コントラスト調整関数ImageBrightContrastでは、まず前述の原理に従って256個の要素サイズのルックアップテーブルを作成し、次に画像データに対してR、G、B成分値毎にルックアップテーブルで調整後のデータを取得するので、処理速度が速い.
次に、コントラスト255の実行ショットを示します.
 
「Delphi画像処理」シリーズはGDI+ユニットを使用してアドレスをダウンロードし、説明は文章「GDI+for VCL基礎--GDI+とVCL」を参照してください.
レベルが限られているため、間違いは避けられないので、指摘と指導を歓迎します.メールアドレス:[email protected]
ここでは『Delphi画像処理--記事インデックス』にアクセスできます.