2011-12-23 11 views
0

2つの画像をSAD(二乗和の和)と呼ばれる比較関数と比較しようとしていますが、各画像からブロックを取り、ピクセルをグレースケールに変換してI比較を行う。 しかし、問題は、2つの同一のブロックを比較すると、sadの結果は0ではない(したがって違いがある)ということです。私は、複数のメッセージボックスで確認してから、私はプログラムは画素に対して間違った色を返すことを見た:例えば、黒画素= 255の代わりに、0画像のピクセルの色が正しくない

ここに私の比較関数のコード:

public double SAD(bloc Bc, bloc Br) 
    { 
     double sad = 0; 
     { 
      BitmapData bmp = image1.LockBits(new Rectangle(Bc.x, Bc.y, taille_bloc, taille_bloc), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); 
      BitmapData bmp2 = image2.LockBits(new Rectangle(Br.x, Br.y, taille_bloc, taille_bloc), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); 
      IntPtr ptr2 = bmp2.Scan0; 
      IntPtr ptr = bmp.Scan0; 
      int bytes = bmp.Width * bmp.Height * 3; 
      double gris1, gris2; 
      byte[] rgb = new byte[bytes]; 
      byte[] rgb2 = new byte[bytes]; 
      System.Runtime.InteropServices.Marshal.Copy(ptr, rgb, 0, bytes); 
      System.Runtime.InteropServices.Marshal.Copy(ptr2, rgb2, 0, bytes); 
      for (int i = 0; i < rgb.Length; i += 3) 
      { 

       gris1 = rgb[i] * 0.2989 + rgb[i+1] * 0.5870 + rgb[i+2] * 0.1140; 
       gris2 = rgb2[i] * 0.2989 + rgb2[i + 1] * 0.5870 + rgb2[i + 2] * 0.1140; 

       sad = sad + Math.Abs(gris2 - gris1); 

      } 
      image2.UnlockBits(bmp2); 

      image1.UnlockBits(bmp); 
     } 

     return sad; 

    } 

をした場合、私は私は

を再定式ます教えてください私の説明で明らかにすることはなかった、あなたの助けを事前にどうもありがとうございました:)

+0

画像が同一であることを確認してください。同一の画像を比較している場合、同一の計算で同じ結果が得られるはずです。多分、共通部分を関数に抽象化して、各画像/ピクセルについてそれを呼び出すのでしょうか? – Oded

+1

短く、自己完結型のコンパイル可能なサンプル(http://sscce.org/を参照)を提供して、迅速に実行して手助けをすることができますか?入力したものには、タイプと変数がありません。 – Abbas

+0

まず、私はこれを平方差の合計を計算するものとしては見ません。差の合計を計算しているようです。 –

答えて

1

一つの可能​​性のある問題は、バイト計算のあなたの番号が間違っているということです。あなたは次のものを持っています:

int bytes = bmp.Width * bmp.Height * 3; 

しかし、ビットマップは、通常4バイト境界にパディングされています。あなたは使用する必要があります

int bytes = bmp.Stride * bmp.Height; 

Strideは、スキャンラインを表すためにかかるバイト数です。 24ビットイメージの場合、これは、0パディングに必要なバイト数プラス、3 * bmp.Widthに等しくなります。

配列をインデックス化するには、1行ずつ移動し、パディングバイトを無視します。各行の先頭にインデックスを初期化する必要があります。

for (int row = 0; row < bmp.Height; ++row) 
{ 
    int i = row * bmp.Stride; 
    for (int p = 0; p < bmp.Width; ++p) 
    { 
     // do comparisons with rgb[i], rgb[i+1], rgb[i+2] 
     i += 3; 
    } 
} 
+0

私はbmp.Strideを使用する場合、どのように私のRGB値にアクセスするのですか? (私のコードでは、テーブル内に何個の列があるのか​​わからない場合は、RGB値がどこに格納されているか分かりません) –

+0

@ GreenApple89:更新された応答を参照してください –

+0

申し訳ありませんが、私が前に投稿したコメントは間違っていました。削除しました。ビットマップデータの各バイトをループする代わりに、各行(y)ごとにループし、そのループ内で各列(x)ごとに別のループが必要です。ピクセルの位置は、R、G、またはBの場合、rgb [(y * bmp.Stride)+(x * 3)+ c] c = 0,1または2です。もちろん、ビットマップは4バイトその場合は適切に調整する必要があります。 –

関連する問題