2016-07-12 8 views
0

イメージのスクリーンショットを比較することはできませんし、私は問題を抱えています。このプロジェクトでは、スクリーンショットとファイルの画像を比較する必要があります。私はインターネットでの比較のための良い方法があり、それは働いているようだ。例:Facebookロゴをサイトからcutedしてデスクトップに保存しました。私は自分自身でこのロゴを比較していた場合(私はロゴのスクリーンショットを作り、ロゴと、このスクリーンショットを比較するよりもしています)このメソッドは、正常に動作する(それはスクリーンショットのロゴが含まれていることを述べている)が、私はそれのサイトにスクリーンショットを作成し、比較するよりもしていたときにロゴ付き、このメソッドは、スクリーンショットにロゴが含まれていないことを示します。は、私は、Windowsフォームでの私のプロジェクトに取り組んでいます

私は、このメソッドを使用しています比較:

public static Rectangle searchBitmap(Bitmap smallBmp, Bitmap bigBmp, double tolerance) 
{ 
    BitmapData smallData = 
     smallBmp.LockBits(new Rectangle(0, 0, smallBmp.Width, smallBmp.Height), 
      System.Drawing.Imaging.ImageLockMode.ReadOnly, 
      System.Drawing.Imaging.PixelFormat.Format24bppRgb); 
    BitmapData bigData = 
    bigBmp.LockBits(new Rectangle(0, 0, bigBmp.Width, bigBmp.Height), 
      System.Drawing.Imaging.ImageLockMode.ReadOnly, 
      System.Drawing.Imaging.PixelFormat.Format24bppRgb); 

    int smallStride = smallData.Stride; 
    int bigStride = bigData.Stride; 

    int bigWidth = bigBmp.Width; 
    int bigHeight = bigBmp.Height - smallBmp.Height + 1; 
    int smallWidth = smallBmp.Width * 3; 
    int smallHeight = smallBmp.Height; 

    Rectangle location = Rectangle.Empty; 
    int margin = Convert.ToInt32(255.0 * tolerance); 

    unsafe 
    { 
     byte* pSmall = (byte*)(void*)smallData.Scan0; 
     byte* pBig = (byte*)(void*)bigData.Scan0; 

     int smallOffset = smallStride - smallBmp.Width * 3; 
     int bigOffset = bigStride - bigBmp.Width * 3; 
     bool matchFound = true; 

     for (int y = 0; y < bigHeight; y++) 
     { 
      for (int x = 0; x < bigWidth; x++) 
      { 
       byte* pBigBackup = pBig; 
       byte* pSmallBackup = pSmall; 

       //Look for the small picture. 
       for (int i = 0; i < smallHeight; i++) 
       { 
        int j = 0; 
        matchFound = true; 
        for (j = 0; j < smallWidth; j++) 
        { 
         //With tolerance: pSmall value should be between margins. 
         int inf = pBig[0] - margin; 
         int sup = pBig[0] + margin; 
         if (sup < pSmall[0] || inf > pSmall[0]) 
         { 
          matchFound = false; 
          break; 
         } 

         pBig++; 
         pSmall++; 
        } 

        if (!matchFound) break; 

        //We restore the pointers. 
        pSmall = pSmallBackup; 
        pBig = pBigBackup; 

        //Next rows of the small and big pictures. 
        pSmall += smallStride * (1 + i); 
        pBig += bigStride * (1 + i); 
       } 

       //If match found, we return. 
       if (matchFound) 
       { 
        location.X = x; 
        location.Y = y; 
        location.Width = smallBmp.Width; 
        location.Height = smallBmp.Height; 
        break; 
       } 
       //If no match found, we restore the pointers and continue. 
       else 
       { 
        pBig = pBigBackup; 
        pSmall = pSmallBackup; 
        pBig += 3; 
       } 
      } 

      if (matchFound) break; 

      pBig += bigOffset; 
     } 
    } 

    bigBmp.UnlockBits(bigData); 
    smallBmp.UnlockBits(smallData); 

    return location; 
} 

このメソッドは、四角形 "場所" を返します。 (location.Width == 0 || location.height == 0)の場合、ScreenshotにImageが含まれていないことを意味します。 どうしたのですか?

+0

一つの可能​​な理由は、スクリーンショットは、画面解像度を使用しますので、スクリーンショットのサイズは、テンプレートと異なる場合があり、ということです。あなたのコードでは、 'ロゴ'が同じサイズであると仮定しました。 – urlreader

+0

スクリーンショットのサイズは、テンプレートよりも大きいですが、スクリーンショットの画像を認識するよりも、スクリーンショット(ブラウザからではありません)を作成しています。反対側で、ブラウザでスクリーンショットを作成しているとき、彼は彼を認識できません。 –

+0

ロゴのサイズを確認する1)ブラウザからスクリーンショット。 2)ブラウザからではありません。非常に可能ですが、サイズは同じではありません(おそらく同様かもしれません)。だから、それらにマッチさせるためには、次のことを考慮する必要があります:1)ロゴの規模。 2)の代わりに、小さな閾値と一致するRGBのは、そのようなエッジなどの他の機能を使用し、... – urlreader

答えて

0

スクリーンショットが国境の周りの任意の空白が含まれている場合(スクリーンショットは、画面全体でない限り)、それが最も可能性の高い画像と一致しません。

+0

私は、このロゴは、私はすべての画面上のスクリーンショットではなく作っています表示される場所、私はデスクトップからから四角形をcutingています約知っていて、そのRectangleはスクリーンショットであり、Imageだけでなく、Backgroundまたは別のロゴも含んでいます。 –

関連する問題