[BlueLeaf1336]> PROBLEMS> パターン認識への長い道のり>
history | TOP |
2006/04/17:作成
2006/04/17 | TOP |
いきなりですが、パターン認識をやりたいと考えています。どんなパターンかというと顔です。画像の中の顔を見つけ出したいと、そう考えています。なぜか。それは、今オフラインなんでリンクを示せないのでまた別の時に書きます。
そこで、グレースケール変換です。カラー画像を直接扱うパターン認識処理って、勝手に思ってるだけですが、ないんじゃないかと。多分処理が重たいだけじゃないかと。ひょっとしたら2値画像で認識してしまうのかもしれませんが、とりあえず256色のグレースケールでやってみます。
とっかかりにふさわしく、完全無欠にパクってきました。
ソースコード | TOP |
//----------------------------------------------------------------------------- // グレースケール変換を行うクラス type TTest = class protected FWork: TBitmap; FImage: TBitmap; public constructor Create(); destructor Destroy(); override; procedure SetImage(Source: TBitmap); public property Image: TBitmap read FImage; end; //----------------------------------------------------------------------------- // コンストラクタ constructor TTest.Create(); begin FWork := TBitmap.Create(); FImage := TBitmap.Create(); end; //----------------------------------------------------------------------------- // デストラクタ destructor TTest.Destroy(); begin FWork.Free(); FImage.Free(); end; //----------------------------------------------------------------------------- type TTriple = packed record B, G, R: Byte; end; PTriple = ^TTriple; //----------------------------------------------------------------------------- // 原画像セット // Subject: [Delphi:48275] Re: はじめまして // NTSC 加重平均法 最も品質が良さそう procedure TTest.SetImage(Source: TBitmap); var x, y, i: Integer; LogPalette: TMaxLogPalette; pSource: PTriple; pDest: PByte; begin // 加工のためにイメージを転記 FWork.Assign(Source); FWork.PixelFormat := pf24bit; // 最終イメージを設定 FImage.PixelFormat := pf8Bit; FImage.Width := FWork.Width; FImage.Height := FWork.Height; with LogPalette do begin palNumEntries := 256; palVersion := $0300; for i := 0 to 255 do begin palPalEntry[i].peRed := 255 - i; palPalEntry[i].peGreen := 255 - i; palPalEntry[i].peBlue := 255 - i; end; end; FImage.Palette := CreatePalette(PLogPalette(@LogPalette)^); for y := 0 to FWork.Height - 1 do begin pSource := FWork.ScanLine[y]; pDest := FImage.ScanLine[y]; for x := 0 to FWork.Width - 1 do begin pDest^ := Round(255 - pSource.R * 0.298912 - pSource.G * 0.586611 - pSource.B * 0.114478); Inc(pSource); Inc(pDest); end; end; // イメージを解放(2006.04.24 したらだめ?) // FWork.FreeImage(); // FWork.ReleaseHandle(); end; //----------------------------------------------------------------------------- // 1000回変換してその平均時間を表示するテスト関数 procedure TForm1.Button1Click(Sender: TObject); var Test: TTest; Tick: Cardinal; i: Integer; begin Test := TTest.Create(); Tick := GetTickCount(); for i := 0 to 999 do begin Test.SetImage(Image1.Picture.Bitmap); end; Label1.Caption := FormatFloat('0.00[msec]', (GetTickCount() - Tick) / 1000); Image2.Picture.Bitmap.Assign(Test.Image); Test.Free(); end;
実行結果 | TOP |
その前に、上のコードでは、グレースケール変換を行うだけのクラスを何の脈絡もなく作ってますが、将来的にはパターン認識を行うクラスに画像を渡して、その時点で必要ならグレースケール変換を行うような感じで考えているので、こんな妙な事になってます。
ですが、今のところメインの処理は SetImage メソッドであり、そのメソッドになんらオリジナルなところはありません。
300pixel x 400pixel のフルカラー画像ですが、多分 13msec というのは、画像処理にかかる時間としては破格に長いような気がします。多分ですけど。でも、この時間が問題になるのは、まだまだ先のことだろうと思いますので、とりあえずこれで良しとします。それに、どこをチューニングできるかもわかりませんし。
EOF | TOP |