【问题标题】:What is the fastest way to detect a certain color on a specific pixel and send a click once detected?检测特定像素上的某种颜色并在检测到后发送点击的最快方法是什么?
【发布时间】:2019-04-10 23:34:21
【问题描述】:

不确定此代码是否已上传,因为我找不到。我阅读代码的经验比编写代码的经验要多,因此不胜感激。

【问题讨论】:

标签: c++ c c++11 visual-c++


【解决方案1】:

首先,您必须了解颜色理论以及如何检测两种颜色是“相同”还是“相似”(不同的滤镜也会产生不同的结果)。然后您必须知道您希望使用哪种图像格式解析成原始 RGB 像素。

最后,您将图像中的颜色与您想要找到的颜色进行比较..

首先.. 颜色相似度是用欧几里得距离或“毕达哥拉斯距离”来衡量的:

distance = squareRoot(of: abs(r1^2 - r2^2) + abs(g1^2 - g2^2) + abs(b1^2 - b2^2))

其中 r1g1b1 是第一种颜色,r2g2b2 是 RGB 空间中的第二种颜色。 然后你将该距离与某个容差进行比较。即某个阈值,你可以将其作为误差角度。

例如白色.. 16777215 作为 UInt 与 RGB 中的 255、255、255..

然后有 16777214 因为 UInt 与 255、255、254 相同..

这两种颜色在人眼看来是白色的,与人眼极为相似,但在计算机看来却是不同的!因此,您使用公式并将距离与某个容差进行比较,例如“10”..为什么?因为如果距离为 0,则颜色完全匹配。如果不是,那么您知道它们并不完美,但它们可能相似,具体取决于您愿意接受多少阈值。这就是距离所代表的。否则通过比较字节来比较精确匹配。

https://en.wikipedia.org/wiki/Color_difference

现在,您不必在 RGB 空间中进行操作。您可以使用 HSL、XYZ 和 CIELAB 等。最终,结果会非常相似。

我编写的代码正是这样做的:https://github.com/Brandon-T/CMML/blob/master/src/finder.c#L252

https://github.com/Brandon-T/CMML/blob/master/src/finder.c#L30

#include <stdio.h>
#include <stdlib.h>
#include "bitmap.h"
#include "finder.h"

void TestOne(CTSInfo* info)
{
    rgb32 colour = {144, 240, 255, 0};
    PointArray pts;
    initPointArray(&pts);

    if (findColours(info, &pts, &colour, 0, 0, info->targetImage->width, info->targetImage->height))
    {
        Point *p = pts.p;
        int I = 0;
        for (; I < pts.size; ++I, ++p)
            printf("Colour found at: (%d, %d)\n", p->x, p->y);
    }

    freePointArray(&pts);
}

void TestTwo(CTSInfo* info, bitmap* bmp_to_find)
{
    int x, y;

    if (findImageToleranceIn(info, bmp_to_find, &x, &y, 0, 0, info->targetImage->width, info->targetImage->height, 0))
    {
        printf("Image found at: (%d, %d)\n", x, y);
    }
}

int main()
{
    CTSInfo info = {0};
    bitmap bmp_to_find = {0};
    bitmap bmp_target = {0};

    defaultCTS(&info);
    bitmap_from_file(&bmp_to_find, "C:/Users/Brandon/Desktop/find.bmp");
    bitmap_from_file(&bmp_target, "C:/Users/Brandon/Desktop/target.bmp");
    info.targetImage = &bmp_target;



    TestOne(&info);
    printf("\n");

    TestTwo(&info, &bmp_to_find);
    printf("\n");


    freebmp(&bmp_to_find);
    freebmp(&bmp_target);
    return 0;
}

如果您打算在纯 C++ 中执行此操作,您可能会遇到困难,因为您必须学习 X11 或 WinAPI 才能从 Windows/游戏中获取屏幕截图以检测其中的颜色。我所知道的最好的程序可以做到它位于:https://villavu.com/forum,它被称为“Simba”。它是用 Pascal 编写的,用于用颜色来 bot Runescape。挺成功的,我自己也用过。

那里有人写了一篇关于CTS(色彩容差空间)的教程:https://villavu.com/forum/showthread.php?t=74908

【讨论】:

  • 非常感谢您提供这些信息。这正是我一直在寻找的,现在我可以弄清楚了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-21
  • 1970-01-01
  • 2020-09-07
  • 1970-01-01
  • 2011-06-04
  • 2019-03-05
  • 2011-11-26
相关资源
最近更新 更多