2013-04-26 13 views
1

두 이미지가 거의 동일하고 서로의 차이점을 찾아서 diff 이미지를 만들고 싶다고 가정 해 보겠습니다. 루틴은 작동하지만이 루틴은 내가 원하지 않는 색상을 제공하도록 요청합니다. 여기 내 코드가있다.이미지 사이의 차이 찾기

public class ImageTool 
{ 
    public static unsafe Bitmap GetDifferenceImage(Bitmap image1, Bitmap image2, Color matchColor) 
    { 
     if (image1 == null | image2 == null) 
      return null; 

     if (image1.Height != image2.Height || image1.Width != image2.Width) 
      return null; 

     Bitmap diffImage = image2.Clone() as Bitmap; 

     int height = image1.Height; 
     int width = image1.Width; 

     BitmapData data1 = image1.LockBits(new Rectangle(0, 0, width, height), 
              ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); 
     BitmapData data2 = image2.LockBits(new Rectangle(0, 0, width, height), 
              ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); 
     BitmapData diffData = diffImage.LockBits(new Rectangle(0, 0, width, height), 
               ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb); 

     byte* data1Ptr = (byte*)data1.Scan0; 
     byte* data2Ptr = (byte*)data2.Scan0; 
     byte* diffPtr = (byte*)diffData.Scan0; 

     byte[] swapColor = new byte[3]; 
     swapColor[0] = matchColor.B; 
     swapColor[1] = matchColor.G; 
     swapColor[2] = matchColor.R; 

     int rowPadding = data1.Stride - (image1.Width * 3); 

     // iterate over height (rows) 
     for (int i = 0; i < height; i++) 
     { 
      // iterate over width (columns) 
      for (int j = 0; j < width; j++) 
      { 
       int same = 0; 

       byte[] tmp = new byte[3]; 

       // compare pixels and copy new values into temporary array 
       for (int x = 0; x < 3; x++) 
       { 
        tmp[x] = data2Ptr[0]; 
        if (data1Ptr[0] == data2Ptr[0]) 
        { 
         same++; 
        } 
        data1Ptr++; // advance image1 ptr 
        data2Ptr++; // advance image2 ptr 
       } 

       // swap color or add new values 
       for (int x = 0; x < 3; x++) 
       { 
        diffPtr[0] = (same == 3) ? swapColor[x] : tmp[x]; 
        diffPtr++; // advance diff image ptr 
       } 
      } 

      // at the end of each column, skip extra padding 
      if (rowPadding > 0) 
      { 
       data1Ptr += rowPadding; 
       data2Ptr += rowPadding; 
       diffPtr += rowPadding; 
      } 
     } 

     image1.UnlockBits(data1); 
     image2.UnlockBits(data2); 
     diffImage.UnlockBits(diffData); 

     return diffImage; 
    } 
} 

이 방법처럼 전화 :

Bitmap diff = ImageTool.GetDifferenceImage(image1, image2, Color.Pink); 
diff.MakeTransparent(Color.Pink); 
diff.Save("C:\\test-diff.png",ImageFormat.Png); 
  1. 몇 가지 중 하나는 우리가 어떻게 내가 GetDifferenceImage() 메소드를 호출 할 때 색상을 통과하지 않아도 결과로이 루틴을 변경하는 저를 안내합니다.

  2. 이 방법으로 이미지를 비교하는 것이 최상의 방법이라면 diff 이미지를 얻는 것이 더 빠를 수있는 루틴을 개발하는 방법을 안내해야합니다.

  3. diff 이미지를 가져온 후 어떻게 diff 이미지를 image1과 병합 할 수 있습니까? 빠른 병합 루틴을 개발하는 데 도움이됩니다.

+0

질문이 너무 많지만 명확하지 않습니다. 함수를 전달하는 대신 함수 내부에서 색상을 하드 코딩합니까? – Egor4eg

+0

나는 이미지 비교를 위해 색상에 의존하지 않는 루틴을 변경하기 위해 색상이나 하드 코드를 전달하고 싶지 않습니다. 내가 알 겠어? – Mou

+0

코드에서 두 이미지를 비교하여 모든 차이점이 강조 표시된 결과 이미지를 생성합니다. 강조 표시 할 색상이 메서드로 전송됩니다. 색상을 전달하거나 하드 코드하지 않은 경우 어떤 방법으로 어떤 색상을 사용해야하는지 알 수 있습니까? – Egor4eg

답변

5

두 이미지가 동일하고 차이가 더 큰 픽셀의 밝기가 증가하면 diff 이미지가 검은 색이됩니다. 픽셀을 스왑 색으로 지정하는 대신 두 색상의 차이점을 할당하도록 알고리즘을 변경할 수 있습니다.

// iterate over height (rows) 
    for (int i = 0; i < height; i++) 
    { 
     // iterate over width (columns) 
     for (int j = 0; j < width; j++) 
     { 
      // for each channel 
      for (int x=0; x<3; x++) 
      { 
       diffPtr[0] = Abs(data1Ptr[0]-data2Ptr[0]); 
       data1Ptr++; // advance image1 ptr 
       data2Ptr++; // advance image2 ptr 
       diffPtr++; // advance diff image ptr 
      } 
     } 

     // at the end of each column, skip extra padding 
     if (rowPadding > 0) 
     { 
      data1Ptr += rowPadding; 
      data2Ptr += rowPadding; 
      diffPtr += rowPadding; 
     } 
    } 

diff를 표시/병합하는 방법은 사용자가 수행 할 작업에 따라 다릅니다.

+0

내가 UR 코드로 바꾸길 바래요. 귀하의 방식에 따라 GetDifferenceImage()라는 내 루틴에 대한 전체 코드를 작성할 수 있습니다. thanks – Mou

+0

@Mou 위 코드로 for 루프를 대체하고 matchColor 인수를 제거하고 더 이상 필요없는 swapColor 변수를 삭제하십시오. – denver

+0

매우 유감스럽게도 ur 코드가 도움이되지 않습니다. 더 나은 당신의 코드를 실행합니다. 두 개의 매우 가까운 동일한 PNG 그림을 가져 와서 두 개의 이미지를 UR 코드와 비교하여 결과 이미지가 어떤 것인지 확인하십시오. – Mou