Windows Forms에서 프로젝트를 작업하고 있는데 문제가 있습니다. 이 프로젝트에서는 스크린 샷과 파일의 이미지를 비교해야합니다. 나는 인터넷에서 비교를위한 좋은 방법을 발견하고 그것이 작동하는 것 같다. 예 : Facebook 로고를 사이트에서 cuted했고 데스크톱에 저장했습니다. 이 로고를 그 자체와 비교할 때 (이 스크린 샷을 로고와 비교하는 것보다)이 방법은 올바르게 작동합니다 (스크린 샷에는 로고가 포함되어 있다고 표시되지만 사이트에서 스크린 샷을 만들고 비교할 때 로고가 붙은이 스크린 샷에는 로고가 포함되어 있지 않습니다.스크린 샷과 이미지를 비교할 수 없습니다
것은 나는이 방법을 비교하여 사용하고 있습니다 :
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)
인 경우 스크린 샷에 이미지가 포함되지 않았다는 의미입니다. 무엇이 문제입니까?
하나의 가능한 이유는 스크린 샷이 화면 해상도를 사용하기 때문에 스크린 샷 크기가 템플릿과 다를 수 있습니다. 코드에서 '로고'크기가 동일한 것으로 가정했습니다. – urlreader
스크린 샷 크기는 템플릿보다 크지 만, 스크린 샷의 이미지를 인식 할 때보 다 (브라우저가 아닌) 이미지의 스크린 샷을 만들 때 있습니다. 반대편에서 브라우저에서 스크린 샷을 만들 때, 그를 인식 할 수 없습니다. –
로고 크기 확인 1) 브라우저에서 스크린 샷; 2) 브라우저가 아닙니다. 매우 가능합니다. 크기는 같지 않습니다 (유사 할 수도 있음). 그래서 그들을 맞추기 위해서는 다음을 고려해야합니다. 1) 로고의 크기. 2) 작은 임계 값이있는 RGB와 일치하는 대신 가장자리와 같은 다른 기능을 사용하십시오 ... – urlreader