
前回に引き続き、Turbo Delphi で Rinkaku Application をつくる、の6回目。
今回は、Rinkaku() の結果をコントラストを調整して、ノイズを除去する
Contrast8() フィルタをつくる。
すでに Delphi のここでやった Contrast() と同じ論理で、今回のは
グレースケール専用で、中央値を設定できるフィルタをつくる。
論理は同じなので原理は説明しないが、中央値からの輝度の違いに
比例して、白黒の両端に追いやって、二値化にちかい画像にして、
相対的にノイズを低減させる。
それでは、実装してテストしてみよう。
前々回につくった RinkakuUtils.pas に以下の関数を追加する。
function Contrast8(var bmp: TBitmap; midValue, factor: double): Boolean; var w, h, x, y, i: integer; value: double; src: TBmpData8; d: array[0..255] of byte; begin result := false; if bmp.PixelFormat <> pf8bit then exit; if (factor > 1) or (factor < 0) then exit; if (midValue < 50) or (midValue > 200) then exit; w := bmp.Width; h := bmp.Height; value := (1.0 + factor) * (1.0 + factor); for i := 0 to 255 do d[i] := AdjustByte((i - midValue) * value + midValue); src := TBmpData8.Create(bmp); for y := 0 to h-1 do for x := 0 to w-1 do src[x,y]^ := d[ src[x,y]^]; src.Free; result := true; end;
テスト結果をしめす。
Rinkaku(bmp, 15) and Contrast8(bmp, 100, 0.00)

Rinkaku(bmp, 15) and Contrast8(bmp, 100, 0.02)

Rinkaku(bmp, 15) and Contrast8(bmp, 100, 0.04)

Rinkaku(bmp, 15) and Contrast8(bmp, 100, 0.06)

ご覧のように、コントラスト調整でもかなりノイズを低減できるが
やはり失う情報もある。前回のS字型ノイズ除去とあわせ、適切な
パラメータの選択が必要だ。
テストコードをしめす。
uses VCLImageUtils, RinkakuUtils, Clipbrd; procedure TForm1.Button1Click(Sender: TObject); var bmp: TBitmap; begin bmp := LoadPng('C:\Home\ImgWork\RaceQueen.png'); if not Assigned(bmp) then exit; bmp.PixelFormat := pf24bit; //Median(bmp); if Rinkaku(bmp, 15) and Contrast8(bmp, 100, 0.06) then begin Canvas.Draw(5, 35, bmp); Clipboard.Assign(bmp); end; bmp.Free; end;
今回はここまで。
ある程度ノイズ除去に成功したとしても、髪が白髪のままでは
あまり美しくない。次回は、元画像の濃淡を利用して、線画の
上から塗りつぶす AntiBlackOut() フィルタをつくる。