Страницы

Поиск по вопросам

вторник, 5 марта 2019 г.

C# как вычислить координаты картинки в картинке

Есть 5 видов разных шахматных досок, разного размера (на разные размеры экрана).
Есть массив минимальных квадратиков каждого цвета.
Всё, получается. Но..
private void btnGetWindows_Click(object sender, System.EventArgs e) {
Bitmap bScreen = DoingScreen(); bool res = Contains(bMark, bScreen);
}
Берем делаем скриншот, проверяем с заготовлеными квадратиками. Как можно получить координаты начала маленькой картинки в большой картинке? И следующей за ней?
Например, у 1 квадратика координаты приблизительно 5х5, у второго 155х5 и т.д.
PS Много вопросов появилось. Выкладываю функцию распознавания. Как ее модифицировать, чтобы координаты находились?
private bool Contains(Bitmap smallBmp, Bitmap bigBmp, double tolerance = 0) { 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);
if (location == Rectangle.Empty) return false; return true; }


Ответ

Дык вот же они.. Всё есть.. См. функцию распознования..
if (matchFound) { location.X = x; location.Y = y; location.Width = smallBmp.Width; location.Height = smallBmp.Height; break; }

Комментариев нет:

Отправить комментарий