2011-12-23 3 views
0

2 개의 이미지를 SAD (제곱 차이의 합계)라는 비교 함수로 비교하려고합니다. 각 이미지에서 블록을 가져오고 픽셀을 회색조로 변환하고 I 비교를해라. 하지만 문제는 두 개의 동일한 블록을 비교하면 슬픈 결과가 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; 

    } 

나는 경우 : = 255 대신 여기에 0

내 비교 함수의 코드 예를 들어, 검은 픽셀 내가

당신의 도움 :) 사전에 대단히 감사 재구성합니다 내 설명 그래서 말씀 해주십시오에서 명확하지 않은

+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과 같습니다.

배열을 인덱싱하려면 줄 단위로 이동하고 패딩 바이트를 무시하십시오. 각 행의 시작 부분에서 색인을 초기화해야합니다.

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 값에 액세스 할 수 있습니까? (내 코드에서 매 반복마다 3 씩 나아 간다. 테이블에 몇 개의 열이 있는지 모르면 RGB 값이 어디에 저장되어 있는지 알 수 없다) –

+0

@ GreenApple89 : 내 업데이트 된 응답보기 –

+0

죄송합니다. 이전에 여기에 올린 의견은 잘못되었습니다. 삭제했습니다.비트 맵 데이터의 각 바이트에 대해 루핑하는 대신 각 행 (y)에 대해 루프해야하고 해당 루프 내에서 각 열 (x)에 대해 다른 루프가 필요합니다. 픽셀의 위치는 R, G 또는 B의 경우 rgb [(y * bmp.Stride) + (x * 3) + c] c = 0, 1 또는 2입니다. 물론 비트 맵에서 4 바이트 이 경우 픽셀 단위로 조정해야합니다. –

관련 문제