[BlueLeaf1336]> PROBLEMS> パターン認識への長い道のり>
| history | TOP |
2006/04/24:作成
| 2006/04/24 | TOP |
前回は完全に同じサイズの画像を比較して「似ている度」を評価するために、同じ位置にあるピクセルの階調値の差分の合計を計算し、合計値が小さいほうがより似ている、としていました。が、この方法では1ピクセルずれているだけでぜんぜん違うものとして判定されてしまう可能性があります。でも、多分、現実の写真とかならその程度のズレでどうこうなるようなものでもないとは思いますが。
そこで、画像を平滑化(ぼかし?)して、近くのピクセル(厳密にはあるピクセルの周囲8ピクセル)の階調値を反映させて、少々のズレなら吸収できるように(と勝手にいってますが実際にそういう意図かどうかは知りません)しました。
結論からいうと、単純に平均点があがっただけのような気が...。また、周囲1ピクセルは範囲外処理をサボってそのまま(平滑化処理をしていない)です。
| 線形平滑化フィルタを行うクラス | TOP |
//-----------------------------------------------------------------------------
// 線形平滑化フィルタを行うクラス
type
TTest = class
protected
FWork: TBitmap;
FImage: TBitmap;
public
constructor Create();
destructor Destroy(); override;
procedure LinearSmoothingGrayScaleImage(Source: TBitmap);
public
property Image: TBitmap read FImage;
end;
//-----------------------------------------------------------------------------
// コンストラクタ
constructor TTest.Create();
var
i: Integer;
LogPalette: TMaxLogPalette;
begin
FWork := TBitmap.Create();
FImage := TBitmap.Create();
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)^);
FImage.PixelFormat := pf8bit;
end;
//-----------------------------------------------------------------------------
// デストラクタ
destructor TTest.Destroy();
begin
DeleteObject(FWork.Palette);
DeleteObject(FImage.Palette);
FWork.Free();
FImage.Free();
end;
//-----------------------------------------------------------------------------
// 256色グレースケール画像限定線形平滑化フィルタ
procedure TTest.LinearSmoothingGrayScaleImage(Source: TBitmap);
const
WEIGHT: array[0..2] of array[0..2] of Byte
= ((1, 1, 1), (1, 2, 1), (1, 1, 1));
DIVVAL = 10;
var
x, y: Integer;
pSource: array[0..2] of PByteArray;
pDest: PByteArray;
begin
// 加工のためにイメージを転記
FWork.Assign(Source);
FWork.PixelFormat := pf8bit;
// 最終イメージを設定
FImage.Assign(FWork);
// 画像の端っこ1ピクセルは放置する(問題がおきたら対処する)
// フィルター処理
for y := 1 to FWork.Height - 2 do
begin
pSource[0] := FWork.ScanLine[y - 1];
pSource[1] := FWork.ScanLine[y];
pSource[2] := FWork.ScanLine[y + 1];
pDest := FImage.ScanLine[y];
for x := 1 to FWork.Width - 2 do
begin
pDest[x] := Trunc(( WEIGHT[0][0] * pSource[0][x - 1]
+ WEIGHT[0][1] * pSource[0][x]
+ WEIGHT[0][2] * pSource[0][x + 1]
+ WEIGHT[1][0] * pSource[1][x - 1]
+ WEIGHT[1][1] * pSource[1][x]
+ WEIGHT[1][2] * pSource[1][x + 1]
+ WEIGHT[2][0] * pSource[2][x - 1]
+ WEIGHT[2][1] * pSource[2][x]
+ WEIGHT[2][2] * pSource[2][x + 1]) / DIVVAL);
end;
end;
end;
| 実行結果 | TOP |
TestMatch2.zip(223,255Bytes) ソースコードと実行ファイルです。いつものとおり画像ファイルをフォームに抱え込んでいるので、えらくサイズがでかくなってますが、中身のほうはサイズに比例してません。
ベースは、前回のプログラムですが、原画像とテンプレート画像に平滑化処理を行ってから「似ている度」の評価を行うようにしました。前述したとおり、単に平均点があがっただけのような気がします。
左側がその平滑化処理を施したもので、右側が前回の結果です。実際には、図の左に前回使用したものと同じマインスイーパのキャプチャ画像をグレースケール変換したものがあります。
| EOF | TOP |