Skycrew |
Отправлено: 11 Ноября, 2019 - 23:12:33
|
Мастер
Покинул форум
Сообщений всего: 123
Дата рег-ции: Июль 2014
Репутация: 0
|
В соавторстве с Zireael, который помог разобраться с цветами, замутил такой скриптик.
К сожалению, запрет поиска в области, где было уже найдено по-красоте сделать не получилось. Может будут у кого идеи?
Мне же в голову приходит только "закрашивание" пикселей найденной области в массиве где ищем, однако это не позволит нам дальше нормально искать в этом-же массиве, что-то другое, не захватив снова экран, а это доп-время. Как вариант можно использовать вспомогательный массив копировать из первого в него и в нем уже искать и после закрашивать - как по мне корявое решение, к тому-же существенно увеличивает время поиска(
И еще мой вариант ищет по заданному разбросу сразу всех компонент цвета в обе стороны, но это можно добавить если будет нужно.
В целом-же dll-ка работает весьма быстро, что не может не радовать. Вот бы еще ускорить захват с экран каким-нибудь аналогом функции screen () - было бы вообще огонь! =)
Код DLL (C++):
CODE:#include <iostream>
using namespace std;
extern "C" __declspec(dllexport) int FindIMG(int Колво, int Фон, int* ГдеИскать, int* Искомое, int* x, int* y, int ОбрШир, int ОбрВыс, int ЭкрШир, int ЭкрВыс, int Разброс)
{
int kol = ЭкрШир * ЭкрВыс, kol2 = ОбрШир * ОбрВыс; // Длины, разложенных в 1-мерные массивов ГдеИскать[] и Искомое[]
int i, ii, Индекс, Найдено = 0, Начало = 0, КраОбраз, ЗелОбраз, СинОбраз;
// Пропускаем пиксели в начале искомого изображения, если они = цвет фона
for (Начало = 0; Начало < kol2; Начало++)
{
if (Искомое[Начало] != Фон) break;
}
// Опредеяем компоненты первого пикселя искомого изображения
КраОбраз = Искомое[Начало] & 255;
ЗелОбраз = (Искомое[Начало] >> 8) & 255;
СинОбраз = Искомое[Начало] >> 16;
// Прогоняем по всему массиву ГдеИскать[] чтоб найти совпадение первого пикселя
for (i = 0; i < kol; i++)
{
if ( (ГдеИскать[i] & 255) >= КраОбраз - Разброс && (ГдеИскать[i] & 255) <= КраОбраз + Разброс &&
((ГдеИскать[i] >> 8) & 255) >= ЗелОбраз - Разброс && ((ГдеИскать[i] >> 8) & 255) <= ЗелОбраз + Разброс &&
(ГдеИскать[i] >> 16) >= СинОбраз - Разброс && (ГдеИскать[i] >> 16) <= СинОбраз + Разброс) //)
{
// Найдя первый пиксель, прогоняем уже по массиву Искомое[], чтобы установить совпадение всех его пикселей
for (ii = Начало; ii < kol2; ii++)
{
// Вычисляем место в 1-мерном массиве ГдеИскать[] которое соответствует месту Искомое[ii]
Индекс = i + (ii / ОбрВыс) * ЭкрВыс + ii % ОбрВыс;
if ( Фон != Искомое[ii] && ((ГдеИскать[Индекс] & 255) < (Искомое[ii] & 255) - Разброс || (ГдеИскать[Индекс] & 255) > (Искомое[ii] & 255) + Разброс ||
((ГдеИскать[Индекс] >> 8) & 255) < ((Искомое[ii] >> 8) & 255) - Разброс || ((ГдеИскать[Индекс] >> 8) & 255) > ((Искомое[ii] >> 8) & 255) + Разброс ||
(ГдеИскать[Индекс] >> 16) < (Искомое[ii] >> 16) - Разброс || (ГдеИскать[Индекс] >> 16) > (Искомое[ii] >> 16) + Разброс))
{
break;
}
}
// Опредляем, что в цикле выше совпали все пиксели массива Искомое[]
if (ii == kol2)
{
// "Закрасим" зону где было найдено цветом "-1", если мы не хотим больше искать в той-же области
// for (ii = 0; ii < kol2; ii++) //
// {
// Индекс = i + (ii / ОбрВыс) * ЭкрВыс + ii % ОбрВыс;
// ГдеИскать[Индекс] = -1;
// }
// Закидываем координаты найденого фрагмента в массивы x[] и y[]
x[Найдено] = i / ЭкрВыс;
y[Найдено] = i % ЭкрВыс;
Найдено++;
}
// и продолжаем цикл по массиву ГдеИскать[] с того места, где остановились ранее
// пока не пробежим весь массив или не упремся в ограничение:
if (Найдено == Колво) return Найдено;
}
}
return Найдено;
}
Код Кибора:
CODE:external(INT, "FindIMG", "FindIMG", "Project7.dll");
int x[99], y[99], Кол, ОбрШир = 5, ОбрВыс = 5, time, ОбщВрем = 0;
int Экр[2560][1440], ЭкрШир = 2560, ЭкрВыс = 1440; // Указываем разрешение монитора
int Искомое[5][5]; loadimage (#Искомое[0][0], "Искомое.bmp");
screen (#Экр[0][0], 0, 0, 2560, 1440, -1);
loop(1) // Можно повторить поиск несколько раз, чтобы лучше сравнить разницу
{
time = gettime();
Кол = FindIMG(1, 0, address(#Экр[0][0]), address(#Искомое[0][0]), address(#x[0]), address(#y[0]), ОбрШир, ОбрВыс, ЭкрШир, ЭкрВыс, 15);
//Кол = findimage(1, #Искомое[0][0], 0, #x[0], #y[0], 0, 0, 2560, 1440, 15,15,15,15,15,15, 100, 1, #Экр[0][0]); // Поиск средствами Кибор для сравнения
if(Кол > 0) { ОбщВрем = ОбщВрем + (gettime() - time); pause(500); }
else { messagebox("Не нашёл"); close(); }
}
messagebox("Найдено: "+format(Кол)+" за время: "+format(ОбщВрем)+" мс.");
// Подвигать мышкой по найденым местам, если нужно
// pause(999); for(int i=0;i<Кол;i++) { mousemove(x[i], y[i]); pause(999); } (Отредактировано автором: 11 Ноября, 2019 - 23:23:41) |
|
|
Skycrew |
Отправлено: 12 Ноября, 2019 - 11:47:47
|
Мастер
Покинул форум
Сообщений всего: 123
Дата рег-ции: Июль 2014
Репутация: 0
|
Zireael пишет: Цитата: Вот бы еще ускорить захват с экран
Разве что разработчики винды что-нибудь придумают.
Быстрее захват не с экрана, а с окна.
Может быть, ну там в любом случае 50-100 мс получается только один захват занимает у меня(
Проявляется когда много всего нужно захватить, хочется побыстрее... |
|
|
|