Что нового

ImageSearch, как устроено изнутри, алгоритм и работа

iltmpz

Новичок
Сообщения
23
Репутация
0
Приветствую!
Долго, но не вполне успешно пользуюсь этой dll-кой.

В моем проекте мне нужен поиск чуть-чуть различающихся картинок, приходится использовать ImageSearch.
Который почему-то в моем случае их находит при значении aVariation равным 85 и больше (при 84 и меньше он просто картинку не узнает). Картинка отличается от эталона на несколько пискелей чуть светлее или чуть темнее (сравнивал попиксельно в цикле).

Беда с ImageSearch в том, что он (с aVariation>=85) иногда неожиданно находит то, чего нет в самом неожиданном месте.
Другая беда, что иногда он не находит того, что вроде бы визуально очень похоже на эталон.
Ну и третья беда, это, конечно, производительность: то что у BmpSearch занимает 20мс, ImageSearch может искать (особенно если искать неудачно) до 3 секунд.

Это была предыстория.
Теперь что делать?
Собственно, 2 варианта:
либо доразобраться с ImageSearch, научиться с ним нормально работать, при необходимости дописать/оптимизировать его,
либо написать свой проект / найти альтернативу.

Я пока за первый вариант, благо исходники ImageSearch есть и очень неплохо документированы.

Поэтому, кое-что я вроде бы нарыл, кое в чем не разобрался, поэтому поделюсь тем что понял и спрошу тут, вдруг кто-то это все уже проделал и получил какой-нибудь результат?
1. в исходниках много написано о прозрачности. Мне кажется, это то, что мне нужно.
Правильно ли я понял, что если я в эталонном образце укажу какой-то цвет как прозрачный, то ImageSearch будет считать все пиксели этого цвета совпадающими с любым пикселем картинки, на которой ведется поиск?
В исходниках есть такая строчка:
Код:
else if (!_strnicmp(cp, "Trans", 5))
Почему-то ни в одном мануале я не нашел внятного описания, как пользоваться этим параметром.
Т.е. условно говоря, у меня эталонная картинка в .bmp, я могу передавать параметр как "*Transимя_цвета имя_файла.bmp"? И это будет работать? Или будет работать только для .png и иконок? И что за имя_цвета?
Код:
strlcpy(color_name, cp, sizeof(color_name));
Очень было бы интересно про это почитать, чтобы самому не тратить много часов на ковыряния.

2. Очень интересно узнать, какие алгоритмы используются в ImageSearch для четкого и нечеткого поиска? Есть где-нибудь описание?
Комментарии в исходниках подробнейшие, но вот про алгоритмы я там не нашел, а сам в этом (пока) не силен.
Судя по 2 вложенным for для четкого поиска, я так понял, используется простейший полный перебор вычислительной сложности O(|X||A|)?
Впрочем, существуют ли более быстрые алгоритмы для поиска с "прозрачностями"?

А нечеткий поиск это проверка цвета всех пикселей на попадание в пределы маленького кубика в RGB-пространстве? Т.е. если хотя бы 1 кубик выпадает, картинка найдена не будет?
Мне бы не помешала как раз другая функция: цвета почти всех пикселей идентичны, а вот несколько процентов пикселей отличается полностью. Как я понимаю, такого там нет?

Вот эту тему читал: http://autoit-script.ru/index.php?topic=24167.0
Писать туда не стал, создал отдельную тему.
Т.к. там - в основном как пользоваться, т.е. как вызывать и подключать ее к своим autoit-проектам, а меня autoit-часть в данном случае вообще не волнует, я ее у себя в проекте вызываю так:
Код:
Local $result = DllCall("ImageSearchDLL.dll", "str", "ImageSearch", "int", $iLeftScreen, "int", $iTopScreen, "int", $iRightScreen, "int", $iBottomScreen, "str", $findImage)


Исходники я взял с гитхаба (если здесь можно оставить внешнюю ссылку): https://github.com/MyBotRun/Libraries
 

ivanius

Знающий
Сообщения
74
Репутация
5
Если еще нужно:
Если искать нужно изображение на всем приложении и может появится в любом месте -
1)можно попробовать уникальными пикселями (UniqueColorsSearch поможет)
2)самому вызывать виндовые функции получения 4-8-16 и т.д. пикселей на изображении в определенных местах всегда с равным смещением, и сравнения с твоим эталонным по алгоритму нашел первый совпавший - следующий через 10 пикселей допустим - совпал еще следующий ниже на 5 пикселей и т.д., если нет ищеш дальше первый пиксель.
3)для этого есть библиотека FastFind ищет на изображении "споты" пикселей может с отклонением (исходники на С++), для автоита достаточно быстро 25-50мс максиму что я видел, если уметь пользоватся.

Ну и последний вопрос почему автоит?
 
Автор
I

iltmpz

Новичок
Сообщения
23
Репутация
0
ivanius сказал(а):
Если еще нужно:
Если искать нужно изображение на всем приложении и может появится в любом месте -
1)можно попробовать уникальными пикселями (UniqueColorsSearch поможет)
2)самому вызывать виндовые функции получения 4-8-16 и т.д. пикселей на изображении в определенных местах всегда с равным смещением, и сравнения с твоим эталонным по алгоритму нашел первый совпавший - следующий через 10 пикселей допустим - совпал еще следующий ниже на 5 пикселей и т.д., если нет ищеш дальше первый пиксель.
3)для этого есть библиотека FastFind ищет на изображении "споты" пикселей может с отклонением (исходники на С++), для AutoIt'а достаточно быстро 25-50мс максиму что я видел, если уметь пользоватся.

Ну и последний вопрос почему AutoIt?
Идея с уникальными пискелями мне не нравится отсутствием наглядности. Т.е. если писать код вида: if pic[25][33]="0x00ff00" and pic[48][91]='0x33aa11', то это я утону в коде. Хочу именно именно хранить картинку и сравнивать на if picFound("MyIconToClick.bmp").
Еще проблема в том, что поиск нужен именно нечеткий, т.е. я не могу узнать заранее, что именно определенные пиксели будут определенного цвета.
FastFind не видел, спасибо за ссылку, посмотрю.

Почему autoit? Хороший вопрос, наверно потому что он умеет практически "из коробки" основные требуемые мне вещи, либо имеет UDF на вещи специфические. Конечно, большой минус это отсутствие нормальной ООП-модели и даже какого-то подобия областей видимости переменных, но писать что-то подобное на C++ - пришлось бы страшно подумать насколько дольше...

По поводу ImageSearch и решения моей задачи поставленной в этой теме:
я вижу решение в дописывании ImageSearch. Можно очень неплохо дописать разные варианты, отвечающие за разные типы поиска. Уже реализовал поиск картинки, каждая строка которой имеет не более N различий с оригиналом и убедился, что мне этого недостаточно.
Буду смотреть в сторону одновременно поиска пикселей с цветом в определенном радиусе V и плюс не более N различий, попробую подобрать для каждой картинки те или иные значения этих параметров.
Если получится супер-система, которая решит мою проблему - выложу исходники сюда.

По моим вопросам:
1. Trans - я решил не использовать, много возни с предварительной обработкой картинок.
Хотя да, можно указать прозрачный цвет, выбрав его из списка заранее заданных цветов. Список есть в исходниках.
2. Алгоритмы там тупейшие: полным перебором и вычислительной сложности O(|X||A|).
При этом даже такой тупой полный поиск иногда работает довольно быстро.
Есть желание переписать четкий поиск чтобы использовать его вместо BmpSearch. Отказавшись от прозрачностей. Может быть будет быстрее. Потому что есть смутное подозрение, что BmpSearch тоже использует алгоритм вычислительной сложности O(|X||A|), что для четкого поиска неприемлемо.
Для нечеткого поиска действительно используется "радиус" каждой составляющей цвета по RGB. Если хотя бы 1 пиксель из этого радиуса выходит - картинка не будет найдена.
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
967
iltmpz

Предупреждение За нарушение общих правил (пункт В.2):
Старайтесь избегать “Over quoting” (преувеличенное цитирование) - цитируйте только необходимую часть сообщения, которая наилучшим образом подчеркнёт суть цитируемого.


С уважением, ваш Глобальный модератор.
 
Верх