【问题标题】:Make this simple c# image searching code quicker?让这个简单的 c# 图片搜索代码更快?
【发布时间】:2019-03-26 14:30:50
【问题描述】:

我正在使用下面的代码扫描屏幕以查找要单击的按钮。

我传入了两张位图,一张是按钮的图片,一张是截图。

有没有我可以加快这个基本方法的速度?

private PositionToClick IsInCapture(Bitmap searchFor, Bitmap searchIn)
{
    for (int x = 0; x < searchIn.Width; x++)
    {
        for (int y = 0; y < searchIn.Height; y++)
        {
            bool invalid = false;
            int k = x, l = y;
            for (int a = 0; a < searchFor.Width; a++)
            {
                l = y;
                for (int b = 0; b < searchFor.Height; b++)
                {
                    if (searchFor.GetPixel(a, b) != searchIn.GetPixel(k, l))
                    {
                        invalid = true;
                        break;
                    }
                    else
                        l++;
                }
                if (invalid)
                    break;
                else
                    k++;
            }

            if (!invalid)
                return new PositionToClick() { X = x, Y = y, found = true };
        }
    }

    return new PositionToClick();
}

【问题讨论】:

  • 似乎在codereview上会更好。
  • 避免使用 GetPixel 进行此类操作。而是寻找如何复制视频内存块并进行比较。
  • 尝试使用this question中描述的方法;使用标准位图对每个可能的 X/Y 偏移量扫描主题位图的一部分。我强烈建议您考虑启发式方法 - 可能只先查找按钮的左边缘,然后再查找其他功能。
  • 如果有人偶然发现这正是我所需要的。很快。 codereview.stackexchange.com/questions/138011/…

标签: c# image-processing


【解决方案1】:

您可以先将位图转换为字节数组,然后再比较这些数组。 此外,您可以通过减去您正在搜索的图像的宽度和高度来限制您的搜索区域。 下面的代码我没有测试,只是说明我的意思。

private PositionToClick IsInCapture(Bitmap searchFor, Bitmap searchIn)
{
    var searchForArray = ImageToByte2(searchFor);
    var searchInArray = ImageToByte2(searchIn);
    for (int x = 0; x <= searchIn.Width - searchFor.Width; x++)
    {
        for (int y = 0; y <= searchIn.Height - searchFor.Height; y++)
        {
            bool invalid = false;
            int k = x, l = y;
            for (int a = 0; a < searchFor.Width; a++)
            {
                l = y;
                for (int b = 0; b < searchFor.Height; b++)
                {
                    var pixelFor = searchForArray[a * searchFor.Width + b];
                    var pixelIn = searchInArray[k + searchIn.Width + l];
                    if (pixelIn != pixelFor)
                    {
                        invalid = true;
                        break;
                    }
                    else
                        l++;
                }
                if (invalid)
                    break;
                else
                    k++;
            }

            if (!invalid)
                return new PositionToClick() { X = x, Y = y, found = true };
        }
    }
    return new PositionToClick();
}

public static byte[] ImageToByte2(Image img)
{
    using (var stream = new MemoryStream())
    {
        img.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
        return stream.ToArray();
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-03
    • 2012-05-01
    • 1970-01-01
    • 2021-11-03
    • 1970-01-01
    • 2014-11-10
    • 2012-05-19
    • 1970-01-01
    相关资源
    最近更新 更多