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