なんとなく、ふわっと・・

写真と画像処理関係とひとりごとをなんとなく書き溜めていきたい

Y

2007-10-09 00:27:32 | rinkaku




Comment

いそがしい

2007-10-09 00:13:31 | 写真




若栗、つくば市


Comment

Delphi で Rinkaku Application その5

2007-10-09 00:06:11 | Delphi

前回に引き続き、Turbo Delphi で Rinkaku Application をつくる、の5回目。

今回は、一次微分と二次微分によるエッジ検出フィルタを組み合わせ、
このアプリの中心となる Rinkaku() フィルタをつくる。

Rinkaku() フィルタは、一次微分と二次微分によるエッジ検出結果の
相乗平均によってつくる。これまでに、一次微分として

Contour3()
Contour4()
SobelInvert()

二次微分として

Edge3()
Edge4()

をつくった。したがって、組み合わせの数は6通りある。いろいろ試して、
微妙な違いから、今回は SobelInvert() と Edge4() の組み合わせを採用
することにした。

前回つくった RinkakuUtils.pas に以下の関数を追加する。

function Rinkaku(var bmp: TBitmap; factor: double): Boolean;
var
  tmp:TBitmap;
  w, h, x, y,i: integer;
  src, dst: TBmpData8;
  ct, ed, v: double;
  ff: array[0..255] of double;
begin
  result := false;
  if bmp.PixelFormat <> pf24bit then exit;

  w := bmp.Width;
  h := bmp.Height;

  for i := 0 to 255 do
    ff[i] := factor * Sin(i * PI / 160.0);

  tmp := BmpClone(bmp);

  //Edge3(tmp, true);
  Edge4(tmp, true);

  HistoStretch(tmp);

  //Contour3(bmp, true);
  //Contour4(bmp, true);
  SobelInvert(bmp, true);

  src := TBmpData8.Create(tmp);
  dst := TBmpData8.Create(bmp);

  for y := 0 to h-1 do
    for x := 0 to w-1 do
    begin
      ed := 255 - src[x, y]^;
      ct := 255 - dst[x, y]^;
      v := Sqrt(ed * ct);
      v := v - ff[Trunc(v)];
      dst[x, y]^ := AdjustByte(255 - v);
    end;

  dst.Free;
  src.Free;

  tmp.Free;

  result := true;
end;


ここで、二番目の引数 factor は、Sine 関数をつかった S 字型のノイズ除去
フィルタの強度であり、0から40までの値を設定できる。実際に、この factor を
変えてみた結果を以下にしめす。なお、以下の結果は同じだけコントラストを調整
したものだ。

factor = 0 (S字型ノイズ除去なし)


factor = 10


factor = 20


factor = 30


S字型ノイズ除去は強力である。しかし、髪のディテールなど、失う情報もある。
元画像の質に依存して、factor を試行錯誤で決めなくてはならない。


テストコードを以下にしめす。

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, 30) then
  begin
    Canvas.Draw(5, 35, bmp);
    Clipboard.Assign(bmp);
  end;

  bmp.Free;
end;


かなり、それらしくなってきた。しかし、まだノイズの除去は十分ではない。
これ以降は、ノイズとの戦いである。次回では、まず最初にコントラスト調整
を行うフィルタを作成する。


Comment