Страницы

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

воскресенье, 12 января 2020 г.

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

#c_sharp


Есть 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;
}

    


Ответы

Ответ 1



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

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

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