Сначала вы должны знать теорию цвета и как определить, являются ли два цвета "одинаковыми" или "похожими" (разные фильтры также будут иметь разные результаты) .. тогда вам нужно будет знать, какие форматы изображений вы хотите разобрать в необработанные пиксели RGB.
Наконец, вы сравните цвета на изображении с цветами, которые хотите найти ..
Первый. Сходство цветов измеряется с помощью евклидова расстояния или «пифагорейского расстояния», заданного как:
distance = squareRoot(of: abs(r1^2 - r2^2) + abs(g1^2 - g2^2) + abs(b1^2 - b2^2))
где r1g1b1 - первые цвета, а r2g2b2 - второй цвет в пространстве RGB.
Затем вы сравниваете это расстояние с некоторым допуском. То есть с некоторым порогом, с которым у вас все в порядке как угол ошибки.
Например, белый цвет .. 16777215 в качестве UInt совпадает с 255, 255, 255 в RGB ..
Тогда есть 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, чтобы получать скриншоты из окон / игр для определения цветов внутри ... Лучшая из известных мне программ, которая это делает он расположен по адресу: https://villavu.com/forum и называется «Симба». Он написан на Паскале и используется для запуска Runescape с цветами. Это довольно успешно, и я использовал это сам.
Кто-то написал учебник по CTS (Пространство цветовой толерантности): https://villavu.com/forum/showthread.php?t=74908