Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

UoKit.com Форумы _ UO Pilot _ Поиск числа с помощью Findimage

Автор: cirus 14.12.2016, 13:25

Данный скрипт предназначен для распознавания чисел, текста и различных символов (например, значков серебра, голда).
Есть 2 версии скрипта: одна на языке пилота, вторая на языке lua.

Версия 1 (на языке пилота):

Минимальная версия пилота 2.39. Запускать от администратора.

Поиск числа с помощью Findimage 4.0 (на языке пилота)
Код
// Поиск числа с помощью FindImage
init_arr %GetImage (1) 0 0 245, 98      // координаты для поиска, StartX StartY EndX EndY

set linedelay 0
init_arr %picture 0 1 2 3 4 5 6 7 8 9     // имена картинок (0.bmp, 1.bmp и т. д.)
init_arr %symbol 0 1 2 3 4 5 6 7 8 9    // символ соответствующий имени, т. е. картинка 0.bmp соответствует 0
set $path "C:\Image3"                     // папка с картинками
set $bmp "*.bmp*"                           // формат картинок
set #deltaY 8                               // расстояние между строками (можно указать высоту картинок)
set #deltaspace 12                          // допустимое расстояние между цифрами, иначе будет считаться что это не одно число
set #accuracy 90                            // точность поиска для Findimage
set #deviation 3                            // погрешность оттенка  для Findimage
set #wait 2                                 // пауза между поиском картинок, если указать меньше искать будет быстрее, но нагрузит процессор
set #timeproc 2000                          // время (в мсек) для поиска картинок, если 0 не выйдет из процедуры пока не найдётся хотя бы 1 картинка
set #repeatimage 2                          // допустимое смещение координат, если используется несколько видов одной картинки

dir (%path $path $bmp)
set delimiter '   '
while 1 = 1
    set size(%result)                        // уничтожить массив с предыдущими результатами
    set size(%coord)                         // уничтожить массив с предыдущими координатами
    call test %picture %symbol %GetImage %path #deltaY #deltaspace #accuracy #deviation #wait #timeproc #repeatimage    // процедура поиска
//     save_array %result C:\Users\abc\Desktop\result111.txt     // массив с результатами поиска
//     save_array %coord C:\Users\abc\Desktop\coord111.txt     // массив с координатами чисел
    if  size(%result) > 0         // если размер массива больше 0
        // ТУТ НУЖНЫЕ ДЕЙСТВИЯ
        ///////////// для примера вывод в hint того что нашлось (можно убрать)
        set $str
        set %z [1] \n
        for #i 1 size(%result)
            set $str $str%result[#i]
            if  #i != size(%result)
                set $str $str%z [1]
            end_if
        end_for
        hint (14 clBlue 409, 265 ($str))
        /////////////
    else
        hint Картинки не найдены
    end_if
end_while

// процедура поиска и сортировки
proc test %picture %symbol %GetImage %path #deltaY #deltaspace #accuracy #deviation #wait #timeproc #repeatimage
    set #GetStartX %GetImage [1 1]
    set #GetStartY %GetImage [1 2]
    set #GetEndX %GetImage [1 3]
    set #GetEndY %GetImage [1 4]
    set #current_script current_script
    // загрузка картинок в память
    if  size(%path) > 0                  // если картинки найдены
        for #i 1 size(%path)
            for #j 1 size(%picture)
                if  %path [#i 3] = %picture [#j]
                    set #n #n + 1
                    set %image [#n] LoadImage(%path [#i 1])
                    set %number [#n] %symbol [#j]
                    break
                end_if
            end_for
        end_for
    else
        log Картинки в: $path   не найдены
        log Скрипт остановлен
        stop_script #current_script
    end_if
    // поиск картинок и их сортировка
    set size(%result1)
    set size(%coord_tmp)
    while size(%result1) = 0 and (#timeproc > timer or #timeproc = 0)
        set #z 0
        set %get GetImage(#GetStartX #GetStartY #GetEndX #GetEndY)      // сохранить часть экрана в память
        set #v %get [1 1]
        for #i 1 size(%number)
            set #a Findimage(0 0 %get [1 2] %get [1 3] (%image[#i 1]) %a #v #accuracy -1 #deviation)   // поиск
            if  #a < 0
                log Ошибка поиска картинки. Код ошибки: #a
                log Скрипт остановлен
                stop_script #current_script
            end_if
            if  #a > 0
                for #j 1 size(%a)
                    set #z #z + 1
                    init_arr %result1 (1 1 #z) %number[#i] %a[#j 1] %a[#j 2]   // запись результатов поиска в массив
                end_for
            end_if
            wait #wait
        end_for
        if  size(%result1) > 0
            gosub sortY        // сортировка по Y и X
        end_if
        set $b DeleteImage(%get[1 1])    // удалить изображение, полученное GetImage
    end_while
    goto end                 // выйти из процедуры

    :sortY
    ///// удаление повторных координат, если используется несколько видов одной картинки
        set #size 0
        set %tmp %result1
        set size(%result1)
        for #i 1 size(%tmp[1])
            set #break 0
            for #n 1 #size
                set #xrepeat %tmp[2 #i] - %result1[2 #n]
                set #yrepeat %tmp[3 #i] - %result1[3 #n]
                if  abs(#xrepeat) <= #repeatimage and abs(#yrepeat) <= #repeatimage
                    set #break 1
                    break
                end_if
            end_for
            if  #break = 0
                set #size #size + 1
                init_arr %result1 (1 1 #size) %tmp [1 #i]  %tmp [2 #i] %tmp [3 #i]
            end_if
        end_for
     ///////

        set #z 0
        set #z1 0
        set #z2 1
        set #z4 0
        sort_array %result1 -3
        while 1 = 1
            set #z 0
            set size(%tmp)
            for #i #z2 eval(size(%result1 [1]) - 1)
                set #j #i + 1
                set #x %result1 [3 #i] - %result1 [3 #j]
                if  abs(#x) < #deltaY
                    set #z #z + 1
                    init_arr %tmp (1 1 #z) %result1 [1 #i]  %result1 [2 #i] %result1 [3 #i]
                else
                    set #z #z + 1
                    init_arr %tmp (1 1 #z) %result1 [1 #i]  %result1 [2 #i] %result1 [3 #i]
                    break
                end_if
            end_for
            set #z2 #z2 + #z
            if  #z2 = size(%result1[])
                set #x %result1 [3 #i] - %result1 [3 #j]
                if  abs(#x) > #deltaY
                    set #jj #j
                    sort_array %tmp -2
                    set #z1 #z1 + 1
                    init_arr %result (#z1) %tmp [1]
                    set %coord_tmp [#z1] %tmp [2 1], %tmp [3 1]
                    set %coord.#current_script [#z1] %tmp [2 #z], %tmp [3 #z]
                    gosub space
                    set size(%tmp)
                    set #z #z + 1
                    init_arr %tmp (1 1 #z) %result1 [1 #jj]  %result1 [2 #jj] %result1 [3 #jj]
                    set #z1 #z1 + 1
                    set %result.#current_script [#z1] %tmp [1]
                    set %coord.#current_script [#z1] %tmp [2 #z], %tmp [3 #z]
                    gosub end
                end_if
                set #z #z + 1
                init_arr %tmp (1 1 #z) %result1 [1 #j]  %result1 [2 #j] %result1 [3 #j]
                sort_array %tmp -2
                set #z1 #z1 + 1
                init_arr %result (#z1) %tmp [1]
                set %coord_tmp [#z1] %tmp [2 1], %tmp [3 1]
                gosub space
                break
            else
                sort_array %tmp -2
                set #z1 #z1 + 1
                init_arr %result (#z1) %tmp [1]
                set %coord_tmp [#z1] %tmp [2 1], %tmp [3 1]
                gosub space
            end_if
        end_while
    return

    :space
        set #z3 0
        set size(%space)
        set #z4 #z4 + 1
        //посчитать где нужны пробелы
        for #i 1 eval(size(%tmp[]) - 1)
            set #j #i + 1
            set #space  %tmp [2 #i] - %tmp [2 #j]
            if  abs(#space) > #deltaspace
                set #z3 #z3 + 1
                set %space[#z3] #j
                set #size_coord 1
                while %coord_tmp[#z1 #size_coord] != ""
                    set #size_coord #size_coord + 1
                end_while
                set %coord_tmp [#z1 #size_coord] %tmp [2 #j], %tmp [3 #j]
            end_if
        end_for
        // вставить пробелы
        for #i 1 size(%space)
            set $str %result [#z4]
            set $str insert(" " $str %space[#i])
            set #j #i + 1
            set %space[#j] %space[#j] + #i
            set %result [#z4] $str
        end_for
        // сохранение массива в основном скрипте
        for #i 1 size(%result)
            set size(%tmp1)
            init_arr %tmp1 (1) %result [#i]
            for #j 1 size(%tmp1[1])
                set %result.#current_script [#i #j] %tmp1 [1 #j]
                set %coord.#current_script [#i #j] %coord_tmp [#i #j]
            end_for
        end_for
    return

    :end
end_proc

Результат поиска
Код
%result [1 1] - первая строка, первое число    %coord [1 1] - координаты числа
%result [1 2] - первая строка, второе число    %coord [1 2] - координаты числа
%result [2 1] - вторая строка, первое число    %coord [2 1] - координаты числа

Видео работы скрипта
https://youtu.be/pxPEjszKvK4


Версия 2 (на языке lua):

Функция
Прикрепленный файл  FindString.lua ( 45,96 килобайт ) Кол-во скачиваний: 791

Мануал
Автор скрипта DarkMaster.
Вопросы, баги, предложения на форум
в специальную тему по этому скрипту
https://forum.uokit.com/index.php?showtopic=30000

Мануал по использованию:

Данный скрипт предназначен для распознавания чисел,
текста и различных символов (например, значков серебра, голда).
Скрипт учитывает возможные пробелы и переносы строк.
Параметры в квадратных [] скобках являются не обязательными,
параметры в угловых скобках <> указываются всегда.
Квадратные и фигурные скобки при вызове функций не пишутся,
они лишь указывают на возможность не задавать параметр.
Фигурные {} и круглые () скобки пишутся там, где указаны.
Символ '|' означает исключающее или, например, sub=0|1 означает,
что значение sub может быть равно либо 0, либо 1.

Для удобства использования необходимо
сохранить скрипт в отдельный файл
и подгружать в начале вашего скрипта:
imageToString = require("luaPlugins\\FindString")
Вызов данной команды загрузит модуль
FindString.lua из папки luaPlugins,
расположенной рядом с пилотом.
Т.е. "luaPlugins\FindString.lua"


Скрипт включает в себя следующие функции:

Управление буфером:
Добавление изображения в буфер (вернет адрес):
imageToString.bufferAdd(<путь>,

Получение адреса в памяти загруженного в буфер изображения:
imageToString.bufferGet(<путь>)[адрес])

Удаление изображения из буфера:
imageToString.bufferDelete(<путь>)

Полная очистка буфера:
imageToString.bufferFlush()


Получение текста из изображения:
t = imageToString.get{[parms],[parms],[parms],...}
Внимание! Скобки фигурные!
Указывается либо папка либо набор символов!
[loadFolder] | [[symbols],[path],[ext]]

Полный синтаксис:
t = imageToString.get{

Параметр(все необязательные) Значение по умолчанию
window=<хендл|метод> -- workwindow()
loadFolder={<path="путь">, [mask="маска"], [sub=0|1]} -- nil
symbols={"0", "1", ["2"] = {"two", "second"}, "3"} -- {["1"]={"1"}, ["2"]={"2"}, ["3"]={"3"}, ["4"]={"4"}, ["5"]={"5"},
-- ["6"]={"6"}, ["7"]={"7"}, ["8"]={"8"}, ["9"]={"9"}, ["0"]={"0"}}
path=<"путь"> -- "images\\"
ext=<"расширение"> -- "*.bmp"
crds={<xStart>, <yStart>, <xEnd>, <yEnd>, [abs=0|1]} -- размер окна (workwindow(), если окно явно не указано), если не задано - рабочего стола.
accuracy=<число> -- 95
deviation=<число> -- 2
deltaSpace=<число> -- 2
deltaY=<число> -- 8
dupImage=<число> -- 3
toNumber=<0|1> -- 1
source={<address>, <width>, <height>} -- nil
saveImage=<"путь"> -- nil
wait=<число> -- 2
durationMax=<число> -- 0
secondFrame=<число> -- 0
bufferAddNew=<0|1> -- 1
bufferUpdate=<0|1> -- 0
bufferIgnore=<0|1> -- 0
}


Результат при поиске текста:

t = imageToString.get{[parms],[parms],[parms],...}
Функция возвращает двумерную таблицу,
где первый индекс является номером строки,
второй номером слова.
Если ничего не найдет, вернет nil.
Например, при распознавании текста:

Съешь еще
этих
мягких французских булок.

Массив будет содержать следующие значения:
t[1][1] -- Съешь
t[1][2] -- еще
t[2][1] -- этих
t[3][1] -- мягких
t[3][2] -- французских
t[3][3] -- булок


Параметры при поиске текста:

Данный оператор имеет большое количество возможных параметров,
все они являются необязательными.
В теле скрипта есть блок значений
параметров, используемых по умолчанию,
которые вы при желании можете изменить (таблица default).

window=<хендл|метод>
Хендл окна в котором происходит поиск либо метод 1|2.
Поиск в перекрытых окнах происходит только при указании хендла.
При указании хендла для корректного считывания изображения может
понадобиться указывать хендл родительского окна.
Значение по умолчанию: workwindow().

loadFolder={<path="путь">, [mask="маска"], [sub=0|1]}
Загрузка всех изображений из указанной папки.
Имена файлов должны соответствовать символу
который они означают (расширение не учитывается).
Допускаются файлы с одинаковым именем в разных папках.
<path="путь"> - абсолютный путь по которому находится папка.
Для преобразования относительного пути в абсолютный можно
использовать конструкцию: path=homepath() .. "относительный путь".
[mask="маска"] - маска по которой будут загружены файлы.
Допускается использование символов '?' и '*'.
? - означает один любой символ,
* - любое количество неизвестных символов.
Обратите внимание, что mask=".bmp" означает
точное совпадение полного имени файла с указанной маской,
т.к. символы подстановки не использованы.
Если же указать mask="*.bmp",
то будут загружены все файлы, заканчивающиеся сочетанием ".bmp".
Значение по умолчанию: "*.bmp".
[sub=0|1] - флаг, указывающий на загрузку изображений,
в том числе из подпапок.
При указании loadFolder будут проигнорированы параметры:
symbols, path, ext.
Значение по умолчанию: nil.

symbols={}
Символы для поиска.
Набор символов возможно указать в двух вариантах синтаксиса:
упрощенном и полном.
Упрощенный вариант синтаксиса допускает не указывать
соответствие имен файлов и строке/символу,
который они обозначают: считается, что они идентичны.
Пример упрощенного синтаксиса:
symbols = {"0", "1", "2", "3", "a", "b", "c", "test"}
Полный синтаксис бывает необходим при использовании нескольких
изображений, соответствующих одной и той же строке/символу.
Допускаются переносы строк:
symbols = {
["0"] = {"zero1", "zero2"},
["1"] = {"1a", "1b"},
["2"] = {"two", "second"}
}
Оба варианта синтаксиса можно сочетать:
symbols = {"0", "1", ["2"] = {"two", "second"}, "3"}
Данный параметр игнорируется,
если указана загрузка папки (loadFolder).
Значение по умолчанию:
{["1"]={"1"}, ["2"]={"2"}, ["3"]={"3"}, ["4"]={"4"}, ["5"]={"5"},
["6"]={"6"}, ["7"]={"7"}, ["8"]={"8"}, ["9"]={"9"}, ["0"]={"0"}}

path=<"путь">
Путь, по которому находятся изображения, указанные в symbols.
Путь может быть задан относительным или абсолютным.
Данный параметр игнорируется,
если указана загрузка папки (loadFolder).
Все символы '\' должны быть удвоены (escape-последовательность).
Пример:
path="c:\\image.bmp"
Если путь будет начинаться с символа '\',
то он будет восприниматься относительно корня диска.
Пример:
Если пилот находится по адресу d:\uopilot\uopilot.exe,
то параметр path="\\myFolder"
будет указывать на папку d:\myFolder.
Значение по умолчанию: "images\\".
Это относительный путь, указывающий на папку images,
которая находится рядом с .exe пилота (создается пользователем).

ext=<"расширение">
Расширение картинок, указанных в symbols.
Данный параметр игнорируется,
если указана загрузка папки (loadFolder).
Значение по умолчанию: ".bmp".

crds={<xStart>, <yStart>, <xEnd>, <yEnd>, [abs=0|1]}
Координаты, в которых необходимо производить поиск.
При указании флага abs=1 координаты будут считаться
относительно левого верхнего угла экрана,
в противном случае координаты рассчитываются
относительно левого верхнего угла приложения.
Значение по умолчанию:
размер окна с которым работает функция и относитльные координаты,
если окно не указано и привязка плиота отсутствует, то
используется разрешение рабочего стола и абсолютные координаты.

accuracy=<число>
Точность поиска изображений.
Для текста рекомендуется указывать 95-100.
Значение по умолчанию: 95.

deviation=<число>
Допустимое отклонение оттенка в процентах (255/100*deviation).
Если цвет 50 100 150, то при указании deviation=2
допустимыми значениями будут являться 44-55 94-105 144-155.
Дробная часть при вычислении диапазона
не округляется, а отбрасывается.
Значение по умолчанию: 2.

deltaSpace=<число>
Допустимое расстояние по горизонтали между изображениями.
Если значение превышено считается,
что началось новое слово (присутствует пробел).
Значение по умолчанию: 2.

deltaY=<число>
Смещение по высоте при превышении которого считается,
что символы принадлежат к разным строкам.
Значение по умолчанию: 5.

dupImage=<число>
Смещение, при котором два найденных изображения
будут считаться дубликатом одного.
Значение по умолчанию: 3.

symbolPrio={symbol_1, symbol_2, symbol_3, ...}
Устатнавливает приоритет удаления дублей.
Часть симоволов может содержаться в других символах.
Например при распозновании "Q" очень велика вероятность,
что будет надена буква Q и буква O, аналогично в парах:
7 и 1, 4 и 1 и т.д.
Приоритет определяется позицией символа в массиве,
чем меньше индекс, тем выше приоритет.
Например: {"q", "o", "7", "4", "1"}
заменит О на Q, 1 на 4, 4 на 7 и т.д.,
если они обнаружены в пределах области
считающейся дублями.
Для выключения использовать: {}
Значение по умолчанию: {"q", "o", "7", "4", "1"}

toNumber=<0|1>
Флаг, при котором слова, состоящие только из цифр
будут преобразованы из строки в числовой тип данных.
Это необходимо для арифметических действий, а также
для сравнения чисел.
Значение по умолчанию: 1.

source={<address>, <width>, <height>}
Источник загруженного в память изображения
в котором производить поиск.
<address> - адрес в памяти
<width> - ширина изображения
<height> - высота изображения
Изображение возможно загрузить в память при помощи
getimage() или loadimage().
Значение по умолчанию: nil.

saveImage=<"путь">
Путь, по которому будет сохранено изображение
в котором происходил поиск.
Значение по умолчанию: nil.

wait=<число>
Пауза в миллисекундах (1000мс=1сек) между поиском изображений.
Используется для снижения нагрузки на процессор
ценой увеличения времени поиска.
Значение по умолчанию: 2.

durationMax=<число>
Время в течении которого будут происходить
повторные попытки найти изображение.
Значение может быть дробным, например:
durationMax=2.5.
При указании durationMax=-1 поиск будет происходить
бесконечно до тех пор, пока изображение не будет найдено.
Если первое изображение было найдено,
то остальные будут обработаны полностью
вне зависимости от таймера,
т.е. вы не получите обрезанный текст.
При первом успешном распознавании текста функция завершит работу
и передаст результат, не дожидаясь окончания таймера.
Значение по умолчанию: 0.

secondFrame=<число>
Параметр позволяет задать паузу между
первым нахождением изображения и началом
считывания изображений для распознавания текста.
Позволяет дождаться полной прогрузки
текста перед обработкой.
Обратите внимание, что параметр durationMax учитывает значение
secondFrame и не позволит функции работать дольше,
чем указано в durationMax. Значение по умолчанию:0.

bufferAddNew=<0|1>
Флаг разрешающий добавлять в память буфера изображения,
которые отсутствовали в буфере и были считаны с диска.
Данный параметр игнорируется,
если указан bufferIgnore=1.
Значение по умолчанию: 1.

bufferUpdate=<0|1>
Флаг указывающий на то,
что изображения в буфере должны быть обновлены.
Они будут считаны с диска заново.
Обновятся только те изображения,
которые будут участвовать в поиске.
Данный параметр игнорируется, если указан bufferIgnore=1.
Значение по умолчанию: 0.

bufferIgnore=<0|1>
Флаг, запрещающий работать с буфером.
Данный из буфера считаны не будут,
загрузка искомых изображений произойдет с диска.
Никаких данных в буфер не сохраняется.
Значение по умолчанию: 0.


Пример вызова:
local cell = fs.get{
loadFolder = {path = "image\\comeback", mask="*"},
crds ={x*254, y*36, 108+x*254, 17+y*36},
deltaSpace = 10
}

Если в области для распознования содержатся посторонние данные,
то может быть полезено вызвать функцию несколько раз с областями
непосредственно содержащими данные.
Пример функции для сбора значений представленных в виде таблицы:
get_prices = function(offset_x, offset_y)
local img, w, h, l = getimage(offset_x, offset_y,
410+offset_x, 340+offset_y)
local price = {}
for x = 0, 1 do
for y = 0, 9 do
local cell = fs.get{
loadFolder = {path = "image\\comeback", mask="*"},
source = {img, w, h},
crds ={x*254, y*36, 108+x*254, 17+y*36},
deltaSpace = 10
}
if cell then
price[#price+1] = cell[1][1]
end
end
end
deleteimage(img)
return price
end

Changelog

История изменений:

1.0.9
Добавлено: установление приоритетов символов при удалении дублей. 4 и 1 - будет удалено 1, O и Q удалено O и т.д.
Добавлено: пример вызова, пример для сбора табличных данных.
Фикс: исправлены проблемы findimage пилота при поиске в уже загруженном изображении (getimage/loadimage)

1.0.8
Фикс: Убраны кавычки из пути при loadFolder. В связи с апдейтом пилота и фиксом функции dir этого более не требуется(приводит к битым путям).
Фикс: В связи с отправкой в мусорку crystalLua убраны костыли в виде доп параметра в управлении буфером. Приветствуем luajit!
Фикс: При одновременном использовании secondFrame и абсолютных координат область поиска предварительного обнаружения изображения могла быть искажена.
Фикс: В связи с правками в пилоте убран старый синтаксис передачи параметров в findimage стрингом. Теперь параметры передаются без дополнительных конвертаций и вынужденных глобальных переменных. Небольшое увеличение производительности.
Фикс: В связи с правками в пилоте убрано преобразование возвращаемых координат из строки в число. Небольшое увеличение производительности.
Фикс: В связи с правками в пилоте окно по умолчанию теперь задается функций workwindow(), а не строкой и не зарезервированной переменной.
Фикс: Исправлено описание функций. workwindow и homepath в пилоте теперь функции - workwindow() и homepath().
Добавлено: Значение по умолчанию теперь изменено с фиксированного 0, 0, 1919, 1079, abs=0 на динамическое: используется размер окна с которым идет работа(по умолчанию workwinodow()), если окно не указано и привязка пилота отсутствует, то используется разрешение рабочего стола и абсолютные координаты.
Изменено: значение по умолчанию deltaY с 8 до 5.
Рефакторинг: В связи с правками в пилоте убраны костыли для обхода бага с координатами поиска (начальные нельзя было задать отличные от нуля, после поиска происходил отсев). Небольшое повышение производительности.
Рефакторинг: В связи с правками в пилоте убрано добавление пробела перед флгом рекурсии при получении списка файлов для loadFolder. Переработана инициализация параметра. Синтаксис и результат не изменился.
Рефакторинг: переработана инициализация параметра symbols. Синтаксис и результат не изменился.
Рефакторинг: переработана инициализация параметра crds.abs. Синтаксис и результат не изменился.

1.0.7
Фикс: убрано принудительное преобразование строк в числа - игнорировалась опция toNumber=<0|1>.

1.0.6
Правки орфографии, пунктуации в описании.

1.0.5
Фикс: убраны сообщения отладки в лог.
Добавлено: imageToString.buffer.add теперь возвращает адрес загруженного изображения.

1.0.4
Фикс: добавлен набор костылей для адекватной передачи параметров при вызове функций буфера.
Добавлено: опция toNumber для преобразования строк в числа.

1.0
Фикс: при передаче источника изображения (source) игнорировались координаты поиска.
Изменено: timeProc переименован в durationMax.
Изменено: глобальная переменная, которую необходимо использовать из-за проблем финдимиджа переименована из tmp в tmpOtNiAotNiaorNCOsnaOT.

Фикс: загрузка файлов из папки теперь различает папки и файлы и больше не пытается загрузить папку, как изображение.
Изменено: конечные координаты области поиска равняются (ширина - 1) и (высота - 1) от забранного изображения. (отсчет с нуля)

Фикс: имена функций буфера.
Добавлено: возможность помещать в буфер изображения с диска.
Добавлено: возможность считать адрес в памяти буферизированного изображения.
Изменено: параметр abs теперь задается внутри crds{}

Фикс: символы по умолчанию больше не переписываются, сделано корректное копирование массива.

Фикс: флаг чтения подпапок был инвертирован.
Фикс: secondFrameTimeout больше не глобальная и используется по назначению.
Фикс: При default.durationMax = -1 и default.secondFrame > 0 не выходит преждевременно из функции.
Фикс: Почистил отладочные выводы в лог.
Добавлено: сохранение изображение в котором происходил поиск.

Баг: из-за особенностей костыля финдимиджа создается НЕ локальная переменная tmp.
Фикс: изображение не добавлялось в буфер.
Фикс: расчет пробела от конечной х координаты.
Фикс: очистка буфера после захвата изображения.
Фикс: область поиска при источнике из getimage должна быть с нуля.
Фикс: искалось только одно изображение из-за недостающего вложенного цикла.
Фикс: буфер теперь действительно буферизует.
Переработано преобразование из упрощенного синтаксиса в полноценный. Добавлена защита от дурака (типы данных).
Добавлено: загрузка папки с изображениями.
Добавлено: ожидание прогрузки изображений (options.secondFrame).
Добавлено: чтение из буфера.

Автор: DarkMaster 15.12.2016, 18:53

версию лучше прилепить.

Автор: cirus 30.12.2016, 23:05

Добавил в первый пост вторую версию скрипта.

Автор: dron4938 26.3.2017, 15:58

Ух ты, а какие примерно картинки должны быть? Что в них нарисовано? Просто цифры на белом фоне?

Автор: cirus 26.3.2017, 16:11

Цитата
а какие примерно картинки должны быть? Что в них нарисовано? Просто цифры на белом фоне?

Просто картинки циферок вырезаете. Я тестил скрипт в блокноте, лучше сделать свои картинки, эти могут не находится: Прикрепленный файл  ЧислаИзБлокнотаWin10.zip ( 2,57 килобайт ) Кол-во скачиваний: 4961

Для l2 нужно было фон закрашивать, т. к. он не статичен: Прикрепленный файл  l2.zip ( 4,57 килобайт ) Кол-во скачиваний: 5008

Автор: dron4938 26.3.2017, 16:17

Цитата(cirus @ 26.3.2017, 16:11) *

Просто картинки циферок вырезаете. Я тестил скрипт в блокноте, лучше сделать свои картинки, эти могут не находится: Прикрепленный файл  ЧислаИзБлокнотаWin10.zip ( 2,57 килобайт ) Кол-во скачиваний: 4961

Для l2 нужно было фон закрашивать, т. к. он не статичен: Прикрепленный файл  l2.zip ( 4,57 килобайт ) Кол-во скачиваний: 5008



Фон на картинке важен?
Просто в справке пилота:
Формат картинки должен быть: bmp 24 бита.
Цвет крайнего пикселя в левом верхнем углу изображения считается "цветом фона", и при поиске картинки на экране не учитывается.

Автор: DarkMaster 26.3.2017, 16:19

Цитата
Ух ты, а какие примерно картинки должны быть? Что в них нарисовано? Просто цифры на белом фоне?

Зависит от того нужно ли вам учитывать фон. Если числа будут на прозрачном фоне, то нужно будет сделать доп обработку изображения закрасив весь фон и левый верхний пиксель в один цвет(любой не совпадающий с цветом цифры). Если фон статичен, то достаточно просто перекрасить левый верхний пиксель.

Автор: dron4938 26.3.2017, 17:26

Спасибо суперский скрипт, работает отлично.
Только как сделать чтобы результат найденный был таким, что если найдена 0, то она заменялась на 00.
Если найдена 1, то заменить на 01.
0=00
1=01
2=02
3=03
4=04
5=05
6=06
7=07
8=08
9=09

допустим число результата
0 2 70
нужно чтобы преобразовалось в
00 02 70
и потом нужно чтобы преобразовалось в
000270

Автор: cirus 26.3.2017, 17:53

код
Код
///////// начало скрипта  //////////
init_arr %GetImage (1) 0 0 129, 78     // координаты для поиска, StartX StartY EndX EndY

set linedelay 0
init_arr %picture 0 1 2 3 4 5 6 7 8 9       // имена картинок (0.bmp, 1.bmp и т. д.)
init_arr %symbol 0 1 2 3 4 5 6 7 8 9        // символ соответствующий имени, т. е. картинка 0.bmp соответствует 0
set $path "C:\Number"                     // папка с картинками
set $bmp "*.bmp*"                           // формат картинок
set #deltaY 8                               // расстояние между строками (можно указать высоту картинок)
set #deltaspace 12                          // допустимое расстояние между цифрами, иначе будет считаться что это не одно число
set #accuracy 90                            // точность поиска для Findimage
set #deviation 3                            // погрешность оттенка  для Findimage
set #wait 2                                 // пауза между поиском картинок, если указать меньше искать будет быстрее, но нагрузит процессор
set #timeproc 2000                          // время (в мсек) для поиска картинок, если 0 не выйдет из процедуры пока не найдётся хотя бы 1 картинка

dir (%path $path $bmp)
////////////////////


// тут нужные действия

// поиск чисел
set size(%result)                        // уничтожить массив с предыдущими результатами
call test %picture %symbol %GetImage %path #deltaY #deltaspace #accuracy #deviation #wait #timeproc     // процедура поиска
if  size(%result) > 0         // если число найдено

    ///// замена 0,1,2...на 00,01,02..
    for #i 1 3
        for #j 0 eval(size(%symbol) - 1)
            if  %result [1 #i] = #j
                set %result [1 #i] 0#j
            end_if
        end_for
    end_for
    /////

end_if
log %result [1]

// тут нужные действия
end_script


// саму процедуру в конец скрипта
proc test %picture %symbol %GetImage %path #deltaY #deltaspace #accuracy #deviation #wait #timeproc
    set #GetStartX %GetImage [1 1]
    set #GetStartY %GetImage [1 2]
    set #GetEndX %GetImage [1 3]
    set #GetEndY %GetImage [1 4]
    set #current_script current_script
    // загрузка картинок в память
    if  size(%path) > 0                  // если картинки найдены
        for #i 1 size(%path)
            for #j 1 size(%picture)
                if  %path [#i 3] = %picture [#j]
                    set #n #n + 1
                    set %image [#n] LoadImage(%path [#i 1])
                    set %number [#n] %symbol [#j]
                    break
                end_if
            end_for
        end_for
    else
        log Картинки в: $path   не найдены
        log Скрипт остановлен
        stop_script #current_script
    end_if
    // поиск картинок и их сортировка
    set size(%result1)
    while size(%result1) = 0 and (#timeproc > timer or #timeproc = 0)
        set #z 0
        set %get GetImage(#GetStartX #GetStartY #GetEndX #GetEndY)      // сохранить часть экрана в память
        set #v %get [1 1]
        for #i 1 size(%number)
            set #a Findimage(0 0 %get [1 2] %get [1 3] (%image[#i 1]) %a #v #accuracy -1 #deviation)   // поиск
            if  #a < 0
                log Ошибка поиска картинки. Код ошибки: #a
                log Скрипт остановлен
                stop_script #current_script
            end_if
            if  #a > 0
                for #j 1 size(%a)
                    set #z #z + 1
                    init_arr %result1 (1 1 #z) %number[#i] %a[#j 1] %a[#j 2]   // запись результатов поиска в массив
                end_for
            end_if
            wait #wait
        end_for
        if  size(%result1) > 0
            gosub sortY        // сортировка по Y и X
        end_if
        set $b DeleteImage(%get[1 1])    // удалить изображение, полученное GetImage
    end_while
    goto end                 // выйти из процедуры

    :sortY
        set #z 0
        set #z1 0
        set #z2 1
        set #z4 0
        sort_array %result1 -3
        while 1 = 1
            set #z 0
            set size(%tmp)
            for #i #z2 eval(size(%result1 [1]) - 1)
                set #j #i + 1
                set #x %result1 [3 #i] - %result1 [3 #j]
                if  abs(#x) < #deltaY
                    set #z #z + 1
                    init_arr %tmp (1 1 #z) %result1 [1 #i]  %result1 [2 #i] %result1 [3 #i]
                else
                    set #z #z + 1
                    init_arr %tmp (1 1 #z) %result1 [1 #i]  %result1 [2 #i] %result1 [3 #i]
                    break
                end_if
            end_for
            set #z2 #z2 + #z
            if  #z2 = size(%result1[])
                set #x %result1 [3 #i] - %result1 [3 #j]
                if  abs(#x) > #deltaY
                    set #jj #j
                    sort_array %tmp -2
                    set #z1 #z1 + 1
                    init_arr %result (#z1) %tmp [1]
                    gosub space
                    set size(%tmp)
                    set #z #z + 1
                    init_arr %tmp (1 1 #z) %result1 [1 #jj]  %result1 [2 #jj] %result1 [3 #jj]
                    set #z1 #z1 + 1
                    set %result.#current_script [#z1] %tmp [1]
                    gosub end
                end_if
                set #z #z + 1
                init_arr %tmp (1 1 #z) %result1 [1 #j]  %result1 [2 #j] %result1 [3 #j]
                sort_array %tmp -2
                set #z1 #z1 + 1
                init_arr %result (#z1) %tmp [1]
                gosub space
                break
            else
                sort_array %tmp -2
                set #z1 #z1 + 1
                init_arr %result (#z1) %tmp [1]
                gosub space
            end_if
        end_while
    return

    :space
        set #z3 0
        set size(%space)
        set #z4 #z4 + 1
        //посчитать где нужны пробелы
        for #i 1 eval(size(%tmp[]) - 1)
            set #j #i + 1
            set #space  %tmp [2 #i] - %tmp [2 #j]
            if  abs(#space) > #deltaspace
                set #z3 #z3 + 1
                set %space[#z3] #j
            end_if
        end_for
        // вставить пробелы
        for #i 1 size(%space)
            set $str %result [#z4]
            set $str insert(" " $str %space[#i])
            set #j #i + 1
            set %space[#j] %space[#j] + #i
            set %result [#z4] $str
        end_for
        // сохранение массива в основном скрипте
        for #i 1 size(%result)
            set size(%tmp1)
            init_arr %tmp1 (1) %result [#i]
            for #j 1 size(%tmp1[1])
                set %result.#current_script [#i #j] %tmp1 [1 #j]
            end_for
        end_for
    return

    :end
end_proc

Автор: dron4938 26.3.2017, 18:42

Спасибо всё получилось smile.gif

А есть ли в пилоте команда- возврат на предыдущий цикл или перепрыгнуть 1 цикл

:aaa
главный скрипт


goto bbb


:bbb
:ccc
:ddd
goto aaa (после прыжка на ааа, нужно вернуться на ddd)

Возможно такое?
-----------------------------------------
Либо:

:aaa
Главный скрипт
:bbb
простой скрипт 1
:ccc ----------------------- (перед началом действия скрипта ccc, нужно выполнить скрипт aaa, и снова вернуться на ccc минуя bbb)
простой скрипт 2
:ddd ------------------------- (перед началом действия скрипта ddd, нужно выполнить скрипт aaa, и снова вернуться на ddd минуя bbb и ccc)
простой скрипт 3

Автор: cirus 26.3.2017, 19:20

Вопросы, не касающиеся скрипта для поиска числа, задавайте в другой теме, чтобы не засорять эту.
Используйте gosub: http://uopilot.tati.pro/index.php?title=Gosub

Автор: dron4938 6.4.2017, 15:07

Привет, есть такая картинка Изображение
как видно золото серебро и медь, цифры разными цветами.
Как реализовать максимально быстрый поиск? Чтобы в итоге пилот выдал число 012665.
Может ли пилот определять цифры, если они разными цветами? или же для каждого цвета придется делать 3 отдельных поочередных поиска?

Еще проблема число бывает таким Изображение
т.е. отсутствует число серебра например если оно равно нулю,
тут нужно чтобы пилот выдал результат 020046, вместо отсутствующего цвета числа подставлялось 00.

В итоге нужно делать 3 отдельных поиска выходит?




Автор: cirus 6.4.2017, 15:41

Цитата
Может ли пилот определять цифры, если они разными цветами?

Нет.
Цитата
В итоге нужно делать 3 отдельных поиска выходит?

Вообще можно искать сразу все.
Код
init_arr %picture 0 1 2 3 4 5 6 7 8 9   10 11 12 13 14 15 16 17 18 19      // имена картинок (0.bmp, 1.bmp и т. д.)
init_arr %symbol 0 1 2 3 4 5 6 7 8 9   0 1 2 3 4 5 6 7 8 9     // символ соответствующий имени, т. е. картинка 0.bmp соответствует 0

Картинки 0.bmp-9.bmp для золота.
10.bmp-19.bmp для серебра.
Цитата
Еще проблема число бывает таким

В таком случае проще сделать 3 поиска. Если искать всё сразу придётся дописывать условия, что картинки серебра или ещё чего-то не найдены.

Автор: dron4938 6.4.2017, 16:17

как правильнее реализовать 3 поиска подряд, чтоб быстрее работало?

// все в 1 массиве и папке?
// a- золто, b- серебро, c- медь

_arr %picture a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 c0 c1 c2 c3 c4 c5 c6 c7 c8 c9
_init_arr %symbol 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
set $path "C:\Number"

call test %picture %symbol %GetImage %path #deltaY #deltaspace #accuracy #deviation #wait #timeproc // процедура поиска
----------------------------------------------------------------------------

или же перед каждым поиском менять папку с картинками?

_arr %picture 0 1 2 3 4 5 6 7 8 9
_init_arr %symbol 0 1 2 3 4 5 6 7 8 9
set $path1 "C:\NumberA" // картинки золота
set $path2 "C:\NumberB" // картинки серебра
set $path3 "C:\NumberC" // картинки меди

dir (%path1 $path1 $bmp)
dir (%path2 $path2 $bmp)
dir (%path3 $path3 $bmp)

поиск1:
call test %picture %symbol %GetImage %path1 #deltaY #deltaspace #accuracy #deviation #wait #timeproc

поиск2:
call test %picture %symbol %GetImage %path2 #deltaY #deltaspace #accuracy #deviation #wait #timeproc

поиск3:
call test %picture %symbol %GetImage %path3 #deltaY #deltaspace #accuracy #deviation #wait #timeproc

Автор: dron4938 6.4.2017, 21:15

возник еще 1 вопрос))))
как выяснилось цвет цифр не статичный и постоянно меняется
Изображение

немного удалось добиться стабильного поиска с такими данными
set #accuracy 98 // точность поиска для Findimage
set #deviation 20 // погрешность оттенка для Findimage,

но бывает все же не находит цифру...Это тоже можно решить подставив две или даже 3 картинки в папку:

init_arr %picture 0 1 2 3 4 5 6 7 8 9 0a 1a 2a 3a 4a 5a 6a 7a 8a 9a
init_arr %symbol 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9

но тут проблема образовалась, иногда находит сразу обе картинки, т.е. 3 и 3a совпадает и тогда на выходе получается не 3, а 33. Т.е 2 раза число подставляет пилот.

Собственно вопрос: как прописать, чтобы если поиск нашел 2 совпадения, то в итоге 1 число подставлял?

Автор: dron4938 6.4.2017, 22:05

Чуть подробнее объясню

Изображение 3 картинки

init_arr %picture 0 1 1a 1b 2 3 4 5 6 7 8 9
init_arr %symbol 0 1 1 1 2 3 4 5 6 7 8 9

если поиск совпадает по всем 3 картинкам то, в итоге выйдет результат 111,
а нужно 1


Автор: WKnight 6.4.2017, 22:18

Иногда помогает отключить сглаживание шрифтов.

Автор: dron4938 6.4.2017, 22:24

Цитата(WKnight @ 6.4.2017, 22:18) *

Иногда помогает отключить сглаживание шрифтов.

Пробовал, не помогает, в самой игре цифры переливаются если сильно увеличить это видно

есть такая опция:
[#count] - ограничение количества найденных изображений. По умолчанию установлено для одного изображения - значение 1, для всех возможных - значение -1.
но что-то она не работает.
Нужно чтобы как только поиск нашел первую картинку он сразу останавливался, а получается он без остановки перебирает всю строку
init_arr %picture 0 1 1a 1b 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ......

set #accuracy 95 // точность поиска для Findimage
set #count 1
set #deviation 20 // погрешность оттенка для Findimage
set #wait 1 // пауза между поиском картинок, если указать меньше искать будет быстрее, но нагрузит процессор
set #timeproc 2000 // время (в мсек) для поиска картинок, если 0 не выйдет из процедуры пока не найдётся хотя бы 1 картинка


dir (%path $path $bmp)
set delimiter ' '
while 1 = 1
set size(%result) // уничтожить массив с предыдущими результатами
call test %picture %symbol %GetImage %path #deltaY #deltaspace #accuracy #count #deviation #wait #timeproc // процедура поиска

Автор: dron4938 7.4.2017, 0:12

разобрался)

// поиск картинок и их сортировка
set size(%result1)
while size(%result1) = 0 and (#timeproc > timer or #timeproc = 0)
set #z 0
set %get GetImage(#GetStartX #GetStartY #GetEndX #GetEndY) // сохранить часть экрана в память
set #v %get [1 1]
for #i 1 size(%number)
set #a Findimage(0 0 %get [1 2] %get [1 3] (%image[#i 1]) %a #v #accuracy -1 #deviation)

#accuracy -1 #deviation вместо -1, надо 1
кстати, а зачем -1, так же поиск будет дольше

Автор: DarkMaster 7.4.2017, 0:12

Цитата
set #accuracy 98 // точность поиска для Findimage

Это очень много в данной ситуации. Рекомендую выставить в пределах 80-90, при этом скорее всего получится чуть уменьшить deviation.

Автор: dron4938 7.4.2017, 0:32

#accuracy -1 #deviation вместо -1, надо 1

не, это не работает, он все равно лопатит всю строку, находит 3 картинки и пишет 3 раза число stars.gif

Автор: cirus 7.4.2017, 1:25

Цитата
set #a Findimage(0 0 %get [1 2] %get [1 3] (%image[#i 1]) %a #v #accuracy -1 #deviation)
#accuracy -1 #deviation вместо -1, надо 1
кстати, а зачем -1, так же поиск будет дольше

А если надо найти число, например, 33? Будет найдена первая 3 и поиск остановится.
Цитата
Собственно вопрос: как прописать, чтобы если поиск нашел 2 совпадения, то в итоге 1 число подставлял?

Если время будет допишу в выходные.
Пока попробуйте скриптом сделать картинку.
код
Код
// Поиск статичных точек на нескольких картинках

set %path [1] "C:\Users\abc\Desktop"     // путь для сохранения готовой картинки
set $path "C:\Users\abc\Desktop\22"     // путь к анализируемым картинкам
init_arr %rgb (1) 255 0 0          // цвет для закрашивания фона в формате RGB
set #deviat 5                      // погрешность в цвете

// остальное не менять
dir(%picture $path *.bmp*)
for #i 1 size(%picture)
    set %a [#i] Loadimage (%picture [#i 1])
end_for

set linedelay 0
set $imya prompt (Введите имя картинки)
set %imya [1] $imya

set workwindow windowhandle
set #r %rgb [1 1]
set #g %rgb [1 2]
set #b %rgb [1 3]
writemem #b %a [1 1] b
writemem #g eval(%a [1 1] + 1) b
writemem #r eval(%a [1 1] + 2) b


set #delta %a [1 4] - (%a [1 4] - %a [1 2] * 3 + 1)
for #j 0 eval(%a [1 3] - 1)
    for #i 0 #delta 3
        for #k 2 size(%a)
            set #z %a [1 1] + %a [1 4] * #j + #i
            set #z1 %a [1 1] + %a [1 4] * #j + #i + 1
            set #z2 %a [1 1] + %a [1 4] * #j + #i + 2
            readmem #b1 #z b
            readmem #g1 #z1 b
            readmem #r1 #z2 b

            set #z3 %a [#k 1] + %a [#k 4] * #j + #i
            set #z4 %a [#k 1] + %a [#k 4] * #j + #i + 1
            set #z5 %a [#k 1] + %a [#k 4] * #j + #i + 2
            readmem #b #z3 b
            readmem #g #z4 b
            readmem #r #z5 b
            gosub rgb

            if  #rmin > #r1 or #rmax < #r1 or #gmin > #g1 or #gmax < #g1 or #bmin > #b1 or #bmax < #b1
                set #rpaint %rgb [1 1]
                set #gpaint %rgb [1 2]
                set #bpaint %rgb [1 3]
                writemem #bpaint #z b
                writemem #gpaint #z1 b
                writemem #rpaint #z2 b
                break
            end_if
        end_for
    end_for
end_for

hint (20 clRed 500 500 (Картинка сохранена))
wait 1000
hint (10 clblack 1920 1 (1))
set $bmp SaveImage (%a [1 1] %path [1]\%imya [1].bmp)
end_script

:rgb
    set #rmin #r - 255 * #deviat / 100
    set #rmax #r + 255 * #deviat / 100
    set #gmin #g - 255 * #deviat / 100
    set #gmax #g + 255 * #deviat / 100
    set #bmin #b - 255 * #deviat / 100
    set #bmax #b + 255 * #deviat / 100

    set #dev 255 * #deviat / 100
    set #bmin #b - #dev
    set #bmax #b + #dev
    if  #bmax > 255
        set #bmax 255
    end_if
    if  #bmin < 0
        set #bmin 0
    end_if
    set #gmin #g - #dev
    set #gmax #g + #dev
    if  #gmax > 255
        set #gmax 255
    end_if
    if  #gmin < 0
        set  #gmin 0
    end_if
    set #rmin #r - #dev
    set #rmax #r + #dev
    if  #rmax > 255
        set #rmax 255
    end_if
    if  #rmin < 0
        set #rmin 0
    end_if
return

Закидываете в папку несколько картинок одной цифры, например 1, 1a, 1b. Скрипт сравнит картинки. Пиксели, которые присутствуют на всех картинках будут оставлены, остальные закрашены. Подберите погрешность по цвету, чтобы не слишком много было закрашено. Попробуйте искать полученную картинку.
Важно:
1. Картинки 1, 1a, 1b должны быть одного размера.
2. В скрипте поиска числа
Код
set #deviation 3      // указывать ту же (или больше) погрешность что и при сравнении картинок

3. Попробуйте уменьшить точность поиска.

Автор: cirus 7.4.2017, 2:26

Цитата
Собственно вопрос: как прописать, чтобы если поиск нашел 2 совпадения, то в итоге 1 число подставлял?

Попробуй этот:
код
Код
// Поиск числа с помощью FindImage
init_arr %GetImage (1) 0 0 99, 58     // координаты для поиска, StartX StartY EndX EndY

set linedelay 0
init_arr %picture 0 1 2 3 4 5 6 7 8 9     // имена картинок (0.bmp, 1.bmp и т. д.)
init_arr %symbol 0 1 2 3 4 5 6 7 8 9    // символ соответствующий имени, т. е. картинка 0.bmp соответствует 0
set $path "C:\Number2"                     // папка с картинками
set $bmp "*.bmp*"                           // формат картинок
set #deltaY 8                               // расстояние между строками (можно указать высоту картинок)
set #deltaspace 12                          // допустимое расстояние между цифрами, иначе будет считаться что это не одно число
set #accuracy 90                            // точность поиска для Findimage
set #deviation 3                            // погрешность оттенка  для Findimage
set #wait 2                                 // пауза между поиском картинок, если указать меньше искать будет быстрее, но нагрузит процессор
set #timeproc 2000                          // время (в мсек) для поиска картинок, если 0 не выйдет из процедуры пока не найдётся хотя бы 1 картинка
set #repeatimage 2                          // допустимое смещение координат, если используется несколько видов одной картинки

dir (%path $path $bmp)
set delimiter '   '
while 1 = 1
    set size(%result)                        // уничтожить массив с предыдущими результатами
    call test %picture %symbol %GetImage %path #deltaY #deltaspace #accuracy #deviation #wait #timeproc #repeatimage    // процедура поиска
    // save_array %result C:\resultarr.txt     // массив с результатами поиска

    if  size(%result) > 0         // если размер массива больше 0
        // ТУТ НУЖНЫЕ ДЕЙСТВИЯ
        ///////////// для примера вывод в hint того что нашлось (можно убрать)
        set $str
        set %z [1] \n
        for #i 1 size(%result)
            set $str $str%result[#i]
            if  #i != size(%result)
                set $str $str%z [1]
            end_if
        end_for
        hint (14 clBlue 409, 265 ($str))
        /////////////
    else
        hint Картинки не найдены
    end_if
end_while

// процедура поиска и сортировки
proc test %picture %symbol %GetImage %path #deltaY #deltaspace #accuracy #deviation #wait #timeproc #repeatimage
    set #GetStartX %GetImage [1 1]
    set #GetStartY %GetImage [1 2]
    set #GetEndX %GetImage [1 3]
    set #GetEndY %GetImage [1 4]
    set #current_script current_script
    // загрузка картинок в память
    if  size(%path) > 0                  // если картинки найдены
        for #i 1 size(%path)
            for #j 1 size(%picture)
                if  %path [#i 3] = %picture [#j]
                    set #n #n + 1
                    set %image [#n] LoadImage(%path [#i 1])
                    set %number [#n] %symbol [#j]
                    break
                end_if
            end_for
        end_for
    else
        log Картинки в: $path   не найдены
        log Скрипт остановлен
        stop_script #current_script
    end_if
    // поиск картинок и их сортировка
    set size(%result1)
    while size(%result1) = 0 and (#timeproc > timer or #timeproc = 0)
        set #z 0
        set %get GetImage(#GetStartX #GetStartY #GetEndX #GetEndY)      // сохранить часть экрана в память
        set #v %get [1 1]
        for #i 1 size(%number)
            set #a Findimage(0 0 %get [1 2] %get [1 3] (%image[#i 1]) %a #v #accuracy -1 #deviation)   // поиск
            if  #a < 0
                log Ошибка поиска картинки. Код ошибки: #a
                log Скрипт остановлен
                stop_script #current_script
            end_if
            if  #a > 0
                for #j 1 size(%a)
                    set #z #z + 1
                    init_arr %result1 (1 1 #z) %number[#i] %a[#j 1] %a[#j 2]   // запись результатов поиска в массив
                end_for
            end_if
            wait #wait
        end_for
        if  size(%result1) > 0
            gosub sortY        // сортировка по Y и X
        end_if
        set $b DeleteImage(%get[1 1])    // удалить изображение, полученное GetImage
    end_while
    goto end                 // выйти из процедуры

    :sortY
    ///// удаление повторных координат, если используется несколько видов одной картинки
        set #size 0
        set %tmp %result1
        set size(%result1)
        for #i 1 size(%tmp[1])
            set #break 0
            for #n 1 #size
                set #xrepeat %tmp[2 #i] - %result1[2 #n]
                set #yrepeat %tmp[3 #i] - %result1[3 #n]
                if  abs(#xrepeat) <= #repeatimage and abs(#yrepeat) <= #repeatimage
                    set #break 1
                    break
                end_if
            end_for
            if  #break = 0
                set #size #size + 1
                init_arr %result1 (1 1 #size) %tmp [1 #i]  %tmp [2 #i] %tmp [3 #i]
            end_if
        end_for
     ///////

        set #z 0
        set #z1 0
        set #z2 1
        set #z4 0
        sort_array %result1 -3
        while 1 = 1
            set #z 0
            set size(%tmp)
            for #i #z2 eval(size(%result1 [1]) - 1)
                set #j #i + 1
                set #x %result1 [3 #i] - %result1 [3 #j]
                if  abs(#x) < #deltaY
                    set #z #z + 1
                    init_arr %tmp (1 1 #z) %result1 [1 #i]  %result1 [2 #i] %result1 [3 #i]
                else
                    set #z #z + 1
                    init_arr %tmp (1 1 #z) %result1 [1 #i]  %result1 [2 #i] %result1 [3 #i]
                    break
                end_if
            end_for
            set #z2 #z2 + #z
            if  #z2 = size(%result1[])
                set #x %result1 [3 #i] - %result1 [3 #j]
                if  abs(#x) > #deltaY
                    set #jj #j
                    sort_array %tmp -2
                    set #z1 #z1 + 1
                    init_arr %result (#z1) %tmp [1]
                    gosub space
                    set size(%tmp)
                    set #z #z + 1
                    init_arr %tmp (1 1 #z) %result1 [1 #jj]  %result1 [2 #jj] %result1 [3 #jj]
                    set #z1 #z1 + 1
                    set %result.#current_script [#z1] %tmp [1]
                    gosub end
                end_if
                set #z #z + 1
                init_arr %tmp (1 1 #z) %result1 [1 #j]  %result1 [2 #j] %result1 [3 #j]
                sort_array %tmp -2
                set #z1 #z1 + 1
                init_arr %result (#z1) %tmp [1]
                gosub space
                break
            else
                sort_array %tmp -2
                set #z1 #z1 + 1
                init_arr %result (#z1) %tmp [1]
                gosub space
            end_if
        end_while
    return

    :space
        set #z3 0
        set size(%space)
        set #z4 #z4 + 1
        //посчитать где нужны пробелы
        for #i 1 eval(size(%tmp[]) - 1)
            set #j #i + 1
            set #space  %tmp [2 #i] - %tmp [2 #j]
            if  abs(#space) > #deltaspace
                set #z3 #z3 + 1
                set %space[#z3] #j
            end_if
        end_for
        // вставить пробелы
        for #i 1 size(%space)
            set $str %result [#z4]
            set $str insert(" " $str %space[#i])
            set #j #i + 1
            set %space[#j] %space[#j] + #i
            set %result [#z4] $str
        end_for
        // сохранение массива в основном скрипте
        for #i 1 size(%result)
            set size(%tmp1)
            init_arr %tmp1 (1) %result [#i]
            for #j 1 size(%tmp1[1])
                set %result.#current_script [#i #j] %tmp1 [1 #j]
            end_for
        end_for
    return

    :end
end_proc

Добавлен поиск и удаление лишних координат, если для поиска цифры используется несколько видов этой цифры. Особо не тестил.

Автор: dron4938 7.4.2017, 16:20

Цитата(cirus @ 7.4.2017, 2:26) *

Попробуй этот:
код
Код
// Поиск числа с помощью FindImage
init_arr %GetImage (1) 0 0 99, 58     // координаты для поиска, StartX StartY EndX EndY

set linedelay 0
init_arr %picture 0 1 2 3 4 5 6 7 8 9     // имена картинок (0.bmp, 1.bmp и т. д.)
init_arr %symbol 0 1 2 3 4 5 6 7 8 9    // символ соответствующий имени, т. е. картинка 0.bmp соответствует 0
set $path "C:\Number2"                     // папка с картинками
set $bmp "*.bmp*"                           // формат картинок
set #deltaY 8                               // расстояние между строками (можно указать высоту картинок)
set #deltaspace 12                          // допустимое расстояние между цифрами, иначе будет считаться что это не одно число
set #accuracy 90                            // точность поиска для Findimage
set #deviation 3                            // погрешность оттенка  для Findimage
set #wait 2                                 // пауза между поиском картинок, если указать меньше искать будет быстрее, но нагрузит процессор
set #timeproc 2000                          // время (в мсек) для поиска картинок, если 0 не выйдет из процедуры пока не найдётся хотя бы 1 картинка
set #repeatimage 2                          // допустимое смещение координат, если используется несколько видов одной картинки

dir (%path $path $bmp)
set delimiter '   '
while 1 = 1
    set size(%result)                        // уничтожить массив с предыдущими результатами
    call test %picture %symbol %GetImage %path #deltaY #deltaspace #accuracy #deviation #wait #timeproc #repeatimage    // процедура поиска
    // save_array %result C:\resultarr.txt     // массив с результатами поиска

    if  size(%result) > 0         // если размер массива больше 0
        // ТУТ НУЖНЫЕ ДЕЙСТВИЯ
        ///////////// для примера вывод в hint того что нашлось (можно убрать)
        set $str
        set %z [1] \n
        for #i 1 size(%result)
            set $str $str%result[#i]
            if  #i != size(%result)
                set $str $str%z [1]
            end_if
        end_for
        hint (14 clBlue 409, 265 ($str))
        /////////////
    else
        hint Картинки не найдены
    end_if
end_while

// процедура поиска и сортировки
proc test %picture %symbol %GetImage %path #deltaY #deltaspace #accuracy #deviation #wait #timeproc #repeatimage
    set #GetStartX %GetImage [1 1]
    set #GetStartY %GetImage [1 2]
    set #GetEndX %GetImage [1 3]
    set #GetEndY %GetImage [1 4]
    set #current_script current_script
    // загрузка картинок в память
    if  size(%path) > 0                  // если картинки найдены
        for #i 1 size(%path)
            for #j 1 size(%picture)
                if  %path [#i 3] = %picture [#j]
                    set #n #n + 1
                    set %image [#n] LoadImage(%path [#i 1])
                    set %number [#n] %symbol [#j]
                    break
                end_if
            end_for
        end_for
    else
        log Картинки в: $path   не найдены
        log Скрипт остановлен
        stop_script #current_script
    end_if
    // поиск картинок и их сортировка
    set size(%result1)
    while size(%result1) = 0 and (#timeproc > timer or #timeproc = 0)
        set #z 0
        set %get GetImage(#GetStartX #GetStartY #GetEndX #GetEndY)      // сохранить часть экрана в память
        set #v %get [1 1]
        for #i 1 size(%number)
            set #a Findimage(0 0 %get [1 2] %get [1 3] (%image[#i 1]) %a #v #accuracy -1 #deviation)   // поиск
            if  #a < 0
                log Ошибка поиска картинки. Код ошибки: #a
                log Скрипт остановлен
                stop_script #current_script
            end_if
            if  #a > 0
                for #j 1 size(%a)
                    set #z #z + 1
                    init_arr %result1 (1 1 #z) %number[#i] %a[#j 1] %a[#j 2]   // запись результатов поиска в массив
                end_for
            end_if
            wait #wait
        end_for
        if  size(%result1) > 0
            gosub sortY        // сортировка по Y и X
        end_if
        set $b DeleteImage(%get[1 1])    // удалить изображение, полученное GetImage
    end_while
    goto end                 // выйти из процедуры

    :sortY
    ///// удаление повторных координат, если используется несколько видов одной картинки
        set #size 0
        set %tmp %result1
        set size(%result1)
        for #i 1 size(%tmp[1])
            set #break 0
            for #n 1 #size
                set #xrepeat %tmp[2 #i] - %result1[2 #n]
                set #yrepeat %tmp[3 #i] - %result1[3 #n]
                if  abs(#xrepeat) <= #repeatimage and abs(#yrepeat) <= #repeatimage
                    set #break 1
                    break
                end_if
            end_for
            if  #break = 0
                set #size #size + 1
                init_arr %result1 (1 1 #size) %tmp [1 #i]  %tmp [2 #i] %tmp [3 #i]
            end_if
        end_for
     ///////

        set #z 0
        set #z1 0
        set #z2 1
        set #z4 0
        sort_array %result1 -3
        while 1 = 1
            set #z 0
            set size(%tmp)
            for #i #z2 eval(size(%result1 [1]) - 1)
                set #j #i + 1
                set #x %result1 [3 #i] - %result1 [3 #j]
                if  abs(#x) < #deltaY
                    set #z #z + 1
                    init_arr %tmp (1 1 #z) %result1 [1 #i]  %result1 [2 #i] %result1 [3 #i]
                else
                    set #z #z + 1
                    init_arr %tmp (1 1 #z) %result1 [1 #i]  %result1 [2 #i] %result1 [3 #i]
                    break
                end_if
            end_for
            set #z2 #z2 + #z
            if  #z2 = size(%result1[])
                set #x %result1 [3 #i] - %result1 [3 #j]
                if  abs(#x) > #deltaY
                    set #jj #j
                    sort_array %tmp -2
                    set #z1 #z1 + 1
                    init_arr %result (#z1) %tmp [1]
                    gosub space
                    set size(%tmp)
                    set #z #z + 1
                    init_arr %tmp (1 1 #z) %result1 [1 #jj]  %result1 [2 #jj] %result1 [3 #jj]
                    set #z1 #z1 + 1
                    set %result.#current_script [#z1] %tmp [1]
                    gosub end
                end_if
                set #z #z + 1
                init_arr %tmp (1 1 #z) %result1 [1 #j]  %result1 [2 #j] %result1 [3 #j]
                sort_array %tmp -2
                set #z1 #z1 + 1
                init_arr %result (#z1) %tmp [1]
                gosub space
                break
            else
                sort_array %tmp -2
                set #z1 #z1 + 1
                init_arr %result (#z1) %tmp [1]
                gosub space
            end_if
        end_while
    return

    :space
        set #z3 0
        set size(%space)
        set #z4 #z4 + 1
        //посчитать где нужны пробелы
        for #i 1 eval(size(%tmp[]) - 1)
            set #j #i + 1
            set #space  %tmp [2 #i] - %tmp [2 #j]
            if  abs(#space) > #deltaspace
                set #z3 #z3 + 1
                set %space[#z3] #j
            end_if
        end_for
        // вставить пробелы
        for #i 1 size(%space)
            set $str %result [#z4]
            set $str insert(" " $str %space[#i])
            set #j #i + 1
            set %space[#j] %space[#j] + #i
            set %result [#z4] $str
        end_for
        // сохранение массива в основном скрипте
        for #i 1 size(%result)
            set size(%tmp1)
            init_arr %tmp1 (1) %result [#i]
            for #j 1 size(%tmp1[1])
                set %result.#current_script [#i #j] %tmp1 [1 #j]
            end_for
        end_for
    return

    :end
end_proc

Добавлен поиск и удаление лишних координат, если для поиска цифры используется несколько видов этой цифры. Особо не тестил.


Да, то что нужно, вроде работает отлично, буду дальше тестить. С меня пивасик rolleyes.gif

Автор: dron4938 7.4.2017, 21:00

скрипт

Код

// Поиск числа с помощью FindImage
init_arr %GetImage (1) 939, 512 1115, 524     // координаты для поиска, StartX StartY EndX EndY

set linedelay 0
init_arr %picture 0a 0b 0c 1a 1b 2a 2b 2c 2d 2e 3a 3b 4a 4b 4c 5a 5b 5c 6a 6b 7a 7b 7c 8a 8b 8c 9a 9b 9c 9d 9e  // имена картинок (0.bmp, 1.bmp и т. д.)
init_arr %symbol  0 0 0 1 1 2 2 2 2 2 3 3 4 4 4 5 5 5 6 6 7 7 7 8 8 8 9 9 9 9 9 // символ соответствующий имени, т. е. картинка 0.bmp соответствует 0
set $path "C:\Users\Andrey\Desktop\Pil\ica\a"                     // папка с картинками
set $bmp "*.bmp*"                           // формат картинок
set #deltaY 8                               // расстояние между строками (можно указать высоту картинок)
set #deltaspace 12                          // допустимое расстояние между цифрами, иначе будет считаться что это не одно число
set #accuracy 94                            // точность поиска для Findimage
set #deviation 22                            // погрешность оттенка  для Findimage
set #wait 0                                 // пауза между поиском картинок, если указать меньше искать будет быстрее, но нагрузит процессор
set #timeproc 500                          // время (в мсек) для поиска картинок, если 0 не выйдет из процедуры пока не найдётся хотя бы 1 картинка
set #repeatimage 2                          // допустимое смещение координат, если используется несколько видов одной картинки

dir (%path $path $bmp)
set delimiter '   '

while 1 = 1
:aaa ////////// ПОИСК 1
set $path "C:\Users\Andrey\Desktop\Pil\ica\a"
dir (%path $path $bmp)
    set size(%result)                        // уничтожить массив с предыдущими результатами
    call test %picture %symbol %GetImage %path #deltaY #deltaspace #accuracy #deviation #wait #timeproc #repeatimage
    if  size(%result) > 0         // если размер массива больше 0
        set $str
        set %z [1] \n
        for #i 1 size(%result)
            set $str $str%result[#i]
            if  #i != size(%result)
                set $str $str%z [1]
            end_if
        end_for
    else
        set $str 00
    end_if

:bbb ///////// ПОИСК 2
set $path "C:\Users\Andrey\Desktop\Pil\ica\b"
dir (%path $path $bmp)
set size(%result)
call test %picture %symbol %GetImage %path #deltaY #deltaspace #accuracy #deviation #wait #timeproc #repeatimage
if  size(%result) > 0         // если размер массива больше 0
        set $str2
        set %z [1] \n
        for #i 1 size(%result)
            set $str2 $str2%result[#i]
            if  #i != size(%result)
                set $str2 $str2%z [1]
            end_if
        end_for
    else
        set $str2 00
    end_if

:ccc ///////// ПОИСК 3
set $path "C:\Users\Andrey\Desktop\Pil\ica\c"
dir (%path $path $bmp)
set size(%result)
call test %picture %symbol %GetImage %path #deltaY #deltaspace #accuracy #deviation #wait #timeproc #repeatimage
if  size(%result) > 0         // если размер массива больше 0
        set $str3
        set %z [1] \n
        for #i 1 size(%result)
            set $str3 $str3%result[#i]
            if  #i != size(%result)
                set $str3 $str3%z [1]
            end_if
        end_for
        hint (14 clBlue 409, 265 ($str $str2 $str3)) // РЕЗУЛЬТАТ 3 ПОИСКОВ = 3 ЧИСЛА
    else
        set $str3 00
        hint (14 clBlue 409, 265 ($str $str2 $str3)) // РЕЗУЛЬТАТ 3 ПОИСКОВ = 3 ЧИСЛА
    end_if
end_while




// процедура поиска и сортировки
proc test %picture %symbol %GetImage %path #deltaY #deltaspace #accuracy #deviation #wait #timeproc #repeatimage
    set #GetStartX %GetImage [1 1]
    set #GetStartY %GetImage [1 2]
    set #GetEndX %GetImage [1 3]
    set #GetEndY %GetImage [1 4]
    set #current_script current_script
    // загрузка картинок в память
    if  size(%path) > 0                  // если картинки найдены
        for #i 1 size(%path)
            for #j 1 size(%picture)
                if  %path [#i 3] = %picture [#j]
                    set #n #n + 1
                    set %image [#n] LoadImage(%path [#i 1])
                    set %number [#n] %symbol [#j]
                    break
                end_if
            end_for
        end_for
    else
        log Картинки в: $path   не найдены
        log Скрипт остановлен
        stop_script #current_script
    end_if
    // поиск картинок и их сортировка
    set size(%result1)
    while size(%result1) = 0 and (#timeproc > timer or #timeproc = 0)
        set #z 0
        set %get GetImage(#GetStartX #GetStartY #GetEndX #GetEndY)      // сохранить часть экрана в память
        set #v %get [1 1]
        for #i 1 size(%number)
            set #a Findimage(0 0 %get [1 2] %get [1 3] (%image[#i 1]) %a #v #accuracy -1 #deviation)   // поиск
            if  #a < 0
                log Ошибка поиска картинки. Код ошибки: #a
                log Скрипт остановлен
                stop_script #current_script
            end_if
            if  #a > 0
                for #j 1 size(%a)
                    set #z #z + 1
                    init_arr %result1 (1 1 #z) %number[#i] %a[#j 1] %a[#j 2]   // запись результатов поиска в массив
                end_for
            end_if
            wait #wait
        end_for
        if  size(%result1) > 0
            gosub sortY        // сортировка по Y и X
        end_if
        set $b DeleteImage(%get[1 1])    // удалить изображение, полученное GetImage
    end_while
    goto end                 // выйти из процедуры
    :sortY
    ///// удаление повторных координат, если используется несколько видов одной картинки
        set #size 0
        set %tmp %result1
        set size(%result1)
        for #i 1 size(%tmp[1])
            set #break 0
            for #n 1 #size
                set #xrepeat %tmp[2 #i] - %result1[2 #n]
                set #yrepeat %tmp[3 #i] - %result1[3 #n]
                if  abs(#xrepeat) <= #repeatimage and abs(#yrepeat) <= #repeatimage
                    set #break 1
                    break
                end_if
            end_for
            if  #break = 0
                set #size #size + 1
                init_arr %result1 (1 1 #size) %tmp [1 #i]  %tmp [2 #i] %tmp [3 #i]
            end_if
        end_for
     ///////

        set #z 0
        set #z1 0
        set #z2 1
        set #z4 0
        sort_array %result1 -3
        while 1 = 1
            set #z 0
            set size(%tmp)
            for #i #z2 eval(size(%result1 [1]) - 1)
                set #j #i + 1
                set #x %result1 [3 #i] - %result1 [3 #j]
                if  abs(#x) < #deltaY
                    set #z #z + 1
                    init_arr %tmp (1 1 #z) %result1 [1 #i]  %result1 [2 #i] %result1 [3 #i]
                else
                    set #z #z + 1
                    init_arr %tmp (1 1 #z) %result1 [1 #i]  %result1 [2 #i] %result1 [3 #i]
                    break
                end_if
            end_for
            set #z2 #z2 + #z
            if  #z2 = size(%result1[])
                set #x %result1 [3 #i] - %result1 [3 #j]
                if  abs(#x) > #deltaY
                    set #jj #j
                    sort_array %tmp -2
                    set #z1 #z1 + 1
                    init_arr %result (#z1) %tmp [1]
                    gosub space
                    set size(%tmp)
                    set #z #z + 1
                    init_arr %tmp (1 1 #z) %result1 [1 #jj]  %result1 [2 #jj] %result1 [3 #jj]
                    set #z1 #z1 + 1
                    set %result.#current_script [#z1] %tmp [1]
                    gosub end
                end_if
                set #z #z + 1
                init_arr %tmp (1 1 #z) %result1 [1 #j]  %result1 [2 #j] %result1 [3 #j]
                sort_array %tmp -2
                set #z1 #z1 + 1
                init_arr %result (#z1) %tmp [1]
                gosub space
                break
            else
                sort_array %tmp -2
                set #z1 #z1 + 1
                init_arr %result (#z1) %tmp [1]
                gosub space
            end_if
        end_while
    return

    :space
        set #z3 0
        set size(%space)
        set #z4 #z4 + 1
        //посчитать где нужны пробелы
        for #i 1 eval(size(%tmp[]) - 1)
            set #j #i + 1
            set #space  %tmp [2 #i] - %tmp [2 #j]
            if  abs(#space) > #deltaspace
                set #z3 #z3 + 1
                set %space[#z3] #j
            end_if
        end_for
        // вставить пробелы
        for #i 1 size(%space)
            set $str %result [#z4]
            set $str insert(" " $str %space[#i])
            set #j #i + 1
            set %space[#j] %space[#j] + #i
            set %result [#z4] $str
        end_for
        // сохранение массива в основном скрипте
        for #i 1 size(%result)
            set size(%tmp1)
            init_arr %tmp1 (1) %result [#i]
            for #j 1 size(%tmp1[1])
                set %result.#current_script [#i #j] %tmp1 [1 #j]
            end_for
        end_for
    return

    :end
end_proc

//////////////////////////////////////////////////


Сделал 3 последовательных поиска. Работает, но долго ищет, примерно за 3 секунды находятся все 3 числа, можно ускорить немного?)))
hint (14 clBlue 409, 265 ($str $str2 $str3)) // РЕЗУЛЬТАТ 3 ПОИСКОВ = 3 ЧИСЛА

set #timeproc 500 выставил 180
по логу через таймер все 3 числа находит за 1400мс, все равно долговато(

Автор: cirus 7.4.2017, 21:18

Цитата
set #deviation 22 // погрешность оттенка для Findimage

Уменьшить, это слишком много.
Слежение за ходом выключить, если включено.

Автор: dron4938 7.4.2017, 21:23

Цитата(cirus @ 7.4.2017, 22:18) *

Уменьшить, это слишком много.

Если уменьшить, то бывает не находит числа(
Я игрался с разными значениями

set #accuracy 94
set #deviation 22

такое вышло оптимальным.если уменьшать и то и то, то другие цифры бывает находит

Слежение за ходом- это что?

Автор: cirus 7.4.2017, 21:25

Цитата
Слежение за ходом- это что?

Прикрепленное изображение

Автор: dron4938 7.4.2017, 21:29

Цитата(cirus @ 7.4.2017, 22:25) *

Прикрепленное изображение

уф со слежением 1400мс
без слежения 700мс
ну уже нормик)

Автор: cirus 7.4.2017, 21:45

Быстрее не будет, 3 поиска по 30+ картинок. Только если меньше картинок искать. Попробуйте скриптом, который выше, сделать из нескольких картинок одну.

Автор: dron4938 7.4.2017, 21:51

Цитата(cirus @ 7.4.2017, 22:45) *

Быстрее не будет, 3 поиска по 30+ картинок. Только если меньше картинок искать. Попробуйте скриптом, который выше, сделать из нескольких картинок одну.

Ладно, сейчас испробую, интересно что выйдет из этого)

Автор: dron4938 7.4.2017, 22:07

4 картинки одной цифры сделал. Вообщем она полностью в красный закрашивается при #deviat 10
Архив с картинками прилепил, может что не так делаю.
А может можно искать картинку по вырезанному фону?)))

Изображение


Прикрепленные файлы
Прикрепленный файл  22.rar ( 1,43 килобайт ) Кол-во скачиваний: 1754

Автор: cirus 7.4.2017, 22:38

Пусть будет больше deviation, тогда меньше закрасит. В любом случае искать 1 картинку быстрее, чем 4.

Цитата
А может можно искать картинку по вырезанному фону?)))

Получится искать фон, а не число, т. е. даже если чисел нет вообще, то все картинки будут найдены. Т. к. чёрный фон найдётся, а пиксели цифр не сравниваются, т. к. закрашены.

Автор: DarkMaster 8.4.2017, 1:09

Цитата
set #accuracy 94
set #deviation 22

попробуйте где-то 80-90 и 7-12.

Автор: FREEON 9.4.2017, 10:57

Цитата(cirus @ 7.4.2017, 1:25) *


код
Код
// Поиск статичных точек на нескольких картинках

set %path [1] "C:\Users\abc\Desktop"     // путь для сохранения готовой картинки
set $path "C:\Users\abc\Desktop\22"     // путь к анализируемым картинкам
init_arr %rgb (1) 255 0 0          // цвет для закрашивания фона в формате RGB
set #deviat 5                      // погрешность в цвете

// остальное не менять
dir(%picture $path *.bmp*)
for #i 1 size(%picture)
    set %a [#i] Loadimage (%picture [#i 1])
end_for

set linedelay 0
set $imya prompt (Введите имя картинки)
set %imya [1] $imya

set workwindow windowhandle
set #r %rgb [1 1]
set #g %rgb [1 2]
set #b %rgb [1 3]
writemem #b %a [1 1] b
writemem #g eval(%a [1 1] + 1) b
writemem #r eval(%a [1 1] + 2) b
set #delta %a [1 4] - (%a [1 4] - %a [1 2] * 3 + 1)
for #j 0 eval(%a [1 3] - 1)
    for #i 0 #delta 3
        for #k 2 size(%a)
            set #z %a [1 1] + %a [1 4] * #j + #i
            set #z1 %a [1 1] + %a [1 4] * #j + #i + 1
            set #z2 %a [1 1] + %a [1 4] * #j + #i + 2
            readmem #b1 #z b
            readmem #g1 #z1 b
            readmem #r1 #z2 b

            set #z3 %a [#k 1] + %a [#k 4] * #j + #i
            set #z4 %a [#k 1] + %a [#k 4] * #j + #i + 1
            set #z5 %a [#k 1] + %a [#k 4] * #j + #i + 2
            readmem #b #z3 b
            readmem #g #z4 b
            readmem #r #z5 b
            gosub rgb

            if  #rmin > #r1 or #rmax < #r1 or #gmin > #g1 or #gmax < #g1 or #bmin > #b1 or #bmax < #b1
                set #rpaint %rgb [1 1]
                set #gpaint %rgb [1 2]
                set #bpaint %rgb [1 3]
                writemem #bpaint #z b
                writemem #gpaint #z1 b
                writemem #rpaint #z2 b
                break
            end_if
        end_for
    end_for
end_for

hint (20 clRed 500 500 (Картинка сохранена))
wait 1000
hint (10 clblack 1920 1 (1))
set $bmp SaveImage (%a [1 1] %path [1]\%imya [1].bmp)
end_script

:rgb
    set #rmin #r - 255 * #deviat / 100
    set #rmax #r + 255 * #deviat / 100
    set #gmin #g - 255 * #deviat / 100
    set #gmax #g + 255 * #deviat / 100
    set #bmin #b - 255 * #deviat / 100
    set #bmax #b + 255 * #deviat / 100

    set #dev 255 * #deviat / 100
    set #bmin #b - #dev
    set #bmax #b + #dev
    if  #bmax > 255
        set #bmax 255
    end_if
    if  #bmin < 0
        set #bmin 0
    end_if
    set #gmin #g - #dev
    set #gmax #g + #dev
    if  #gmax > 255
        set #gmax 255
    end_if
    if  #gmin < 0
        set  #gmin 0
    end_if
    set #rmin #r - #dev
    set #rmax #r + #dev
    if  #rmax > 255
        set #rmax 255
    end_if
    if  #rmin < 0
        set #rmin 0
    end_if
return

Закидываете в папку несколько картинок одной цифры, например 1, 1a, 1b. Скрипт сравнит картинки. Пиксели, которые присутствуют на всех картинках будут оставлены, остальные закрашены. Подберите погрешность по цвету, чтобы не слишком много было закрашено. Попробуйте искать полученную картинку.
Важно:
1. Картинки 1, 1a, 1b должны быть одного размера.
2. В скрипте поиска числа
Код
set #deviation 3      // указывать ту же (или больше) погрешность что и при сравнении картинок

3. Попробуйте уменьшить точность поиска.

А есть скрипт для закраски фона? Что бы в ручную не красить а то мне нуно в ручную 600 картинок перекрашивать. Желательно, что бы моно было задавать несколько цветов фона (2-4 ЦВЕТА)

Автор: cirus 9.4.2017, 12:02

Цитата
А есть скрипт для закраски фона?

код
Код
// Закрашивание фона
set %path [1] "C:\Users\abc\Desktop\567"     // путь для сохранения картинок, сохранятся с теми же именами что и были
set $path "C:\Users\abc\Desktop\33"     // путь к анализируемым картинкам
init_arr %rgb (1) 255 0 0          // цвет для закрашивания фона в формате RGB

// цвета фона в формате RGB или десятичном, указывать можно любое количество
init_arr %fon (1) 16777215
//init_arr %fon (2) 255 182 102
//init_arr %fon (3) 0
//init_arr %fon (4)

set #deviat 5               // погрешность в цвете


// остальное менять не нужно
for #i 1 size(%fon)
    if  %fon [#i 2] = "" and  %fon [#i 3] = ""
        set #colortmp %fon [#i 1]
        set #rgb colortorgb (#colortmp  %fon[#i])
    end_if
end_for

dir(%picture $path *.bmp*)
for #i 1 size(%picture)
    set %a [#i] Loadimage (%picture [#i 1])
end_for

set linedelay 0
set workwindow windowhandle

for #k 1 size(%a)
set #delta %a [#k 4] - (%a [#k 4] - %a [#k 2] * 3 + 1)
    set #r %rgb [1 1]
    set #g %rgb [1 2]
    set #b %rgb [1 3]
    writemem #b %a [#k 1] b
    writemem #g eval(%a [#k 1] + 1) b
    writemem #r eval(%a [#k 1] + 2) b
    for #j 0 eval(%a [#k 3] - 1)
        for #i 0 #delta 3
            set #z3 %a [#k 1] + %a [#k 4] * #j + #i
            set #z4 %a [#k 1] + %a [#k 4] * #j + #i + 1
            set #z5 %a [#k 1] + %a [#k 4] * #j + #i + 2
            readmem #b #z3 b
            readmem #g #z4 b
            readmem #r #z5 b
            gosub rgb

            for #l 1 size(%fon)
                if  #rmin <= %fon [#l 1] and #rmax >= %fon [#l 1] and #gmin <= %fon [#l 2] and #gmax >= %fon [#l 2] and #bmin <= %fon [#l 3] and #bmax >= %fon [#l 3]
                    set #rpaint %rgb [1 1]
                    set #gpaint %rgb [1 2]
                    set #bpaint %rgb [1 3]
                    writemem #rpaint #z5 b
                    writemem #gpaint #z4 b
                    writemem #bpaint #z3 b
                    break
                end_if
            end_for
        end_for
    end_for
    set $bmp SaveImage (%a [#k 1] %path [1]\%picture [#k 3].bmp)
end_for

hint (20 clRed 500 500 (Картинки сохранены))
wait 1000
hint (10 clblack 1920 1 (1))
end_script

:rgb
    set #rmin #r - 255 * #deviat / 100
    set #rmax #r + 255 * #deviat / 100
    set #gmin #g - 255 * #deviat / 100
    set #gmax #g + 255 * #deviat / 100
    set #bmin #b - 255 * #deviat / 100
    set #bmax #b + 255 * #deviat / 100

    set #dev 255 * #deviat / 100
    set #bmin #b - #dev
    set #bmax #b + #dev
    if  #bmax > 255
        set #bmax 255
    end_if
    if  #bmin < 0
        set #bmin 0
    end_if
    set #gmin #g - #dev
    set #gmax #g + #dev
    if  #gmax > 255
        set #gmax 255
    end_if
    if  #gmin < 0
        set  #gmin 0
    end_if
    set #rmin #r - #dev
    set #rmax #r + #dev
    if  #rmax > 255
        set #rmax 255
    end_if
    if  #rmin < 0
        set #rmin 0
    end_if
return

Накидал, пробуйте что получилось.
Подправил немного.

Автор: FREEON 9.4.2017, 14:00

Цитата(cirus @ 9.4.2017, 12:02) *

код
Код
// Закрашивание фона
set %path [1] "C:\Users\abc\Desktop\567"     // путь для сохранения картинок, сохранятся с теми же именами что и были
set $path "C:\Users\abc\Desktop\22"     // путь к анализируемым картинкам
init_arr %rgb (1) 255 0 0          // цвет для закрашивания фона в формате RGB

// цвета фона в формате RGB, указывать можно любое количество
init_arr %fon (1) 10 25 31
init_arr %fon (2) 26 37 34
//init_arr %fon (3) 45 52 37
//init_arr %fon (4)

set #deviat 5               // погрешность в цвете
// остальное менять не нужно
dir(%picture $path *.bmp*)
for #i 1 size(%picture)
    set %a [#i] Loadimage (%picture [#i 1])
end_for

set linedelay 0
set workwindow windowhandle

set #delta %a [1 4] - (%a [1 4] - %a [1 2] * 3 + 1)
for #k 1 size(%a)
    set #r %rgb [1 1]
    set #g %rgb [1 2]
    set #b %rgb [1 3]
    writemem #b %a [#k 1] b
    writemem #g eval(%a [#k 1] + 1) b
    writemem #r eval(%a [#k 1] + 2) b
    for #j 0 eval(%a [1 3] - 1)
        for #i 0 #delta 3
            set #z3 %a [#k 1] + %a [#k 4] * #j + #i
            set #z4 %a [#k 1] + %a [#k 4] * #j + #i + 1
            set #z5 %a [#k 1] + %a [#k 4] * #j + #i + 2
            readmem #b #z3 b
            readmem #g #z4 b
            readmem #r #z5 b
            gosub rgb

            for #l 1 size(%fon)
                if  #rmin <= %fon [#l 1] and #rmax >= %fon [#l 1] and #gmin <= %fon [#l 2] and #gmax >= %fon [#l 2] and #bmin <= %fon [#l 3] and #bmax >= %fon [#l 3]
                    set #rpaint %rgb [1 1]
                    set #gpaint %rgb [1 2]
                    set #bpaint %rgb [1 3]
                    writemem #rpaint #z5 b
                    writemem #gpaint #z4 b
                    writemem #bpaint #z3 b
                    break
                end_if
            end_for
        end_for
    end_for
   set $bmp SaveImage (%a [#k 1] %path [1]\%picture [#k 3].bmp)
end_for

hint (20 clRed 500 500 (Картинки сохранены))
wait 1000
hint (10 clblack 1920 1 (1))
end_script

:rgb
    set #rmin #r - 255 * #deviat / 100
    set #rmax #r + 255 * #deviat / 100
    set #gmin #g - 255 * #deviat / 100
    set #gmax #g + 255 * #deviat / 100
    set #bmin #b - 255 * #deviat / 100
    set #bmax #b + 255 * #deviat / 100

    set #dev 255 * #deviat / 100
    set #bmin #b - #dev
    set #bmax #b + #dev
    if  #bmax > 255
        set #bmax 255
    end_if
    if  #bmin < 0
        set #bmin 0
    end_if
    set #gmin #g - #dev
    set #gmax #g + #dev
    if  #gmax > 255
        set #gmax 255
    end_if
    if  #gmin < 0
        set  #gmin 0
    end_if
    set #rmin #r - #dev
    set #rmax #r + #dev
    if  #rmax > 255
        set #rmax 255
    end_if
    if  #rmin < 0
        set #rmin 0
    end_if
return

Накидал, пробуйте что получилось.
Подправил немного.

Благодарю, работает. Но есть маленький нюанс - Скрипт закрашивает по размеру пикселей первого изображения. Поэтому, что бы закрашивало всё изображения первое должно быть больше размером чем все остальные, либо все должны быть равными.

Автор: cirus 9.4.2017, 14:24

Цитата
Но есть маленький нюанс - Скрипт закрашивает по размеру пикселей первого изображения.

Исправил. Теперь можно указывать цвет фона в десятичном формате.

Автор: FREEON 9.4.2017, 22:07

Цитата(cirus @ 9.4.2017, 14:24) *

Исправил. Теперь можно указывать цвет фона в десятичном формате.

Извиняюсь может я не так пользуюсь. Но разницы не вижу. Цвет в десятичном коде у меня не задается и размер обработки изображения прежний sad.gif

Цитата(FREEON @ 9.4.2017, 22:05) *

Извиняюсь может я не так пользуюсь. Но разницы не вижу. Цвет в десятичном коде у меня не задается и размер обработки изображения прежний sad.gif

ой сори я рачело, случайно код из своего спойлера вставил laugh.gif

Автор: dron4938 15.4.2017, 13:59

Можете чуть пояснить как set #accuracy работает.

Пример 1. картинка 10х10- содержит 100 пикселей
set #accuracy 100
set #deviation 0
Изображение

если #accuracy 100 , то в этой картинке должны совпасть все 100 пикселей.
если #accuracy 89, то в этой картинке должны совпасть любых 89 пикселей.
Правильно я понимаю?

Пример 2. картинка 9х10 - содержит 90 пикселей
Изображение

если #accuracy 100 , то в этой картинке должны совпасть все 90 пикселей.
если #accuracy 89, то в этой картинке должны совпасть 89% от 90 = 89 х (1 / 100) Ч 90 = 80,1 пикселей.

Пример 3. картинка 5х7 - содержит 35 пикселей
Изображение
если #accuracy 100 , то в этой картинке должны совпасть все 35 пикселей.
если #accuracy 89, то в этой картинке должны совпасть 89% от 35 = 89 х (1 / 100) Ч 35 = 31,15 пикселей.

Правильно я понимаю? Или немного не так?

Далее в картинке есть фон, который пилот вырезает и не учитывает.
Изображение

минусуем 6 пикселей фона
35-6= 29
в итоге если #accuracy 89, то в этой картинке должны совпасть 89% от 29 = 89 Ч (1 / 100) Ч 29 = 25,81

округлим = 26 пикселей
Чтобы картинка нашлась в ней должно совпасть 26 пикселей из 29
и вывод: для мелких картинок можно ставить set #accuracy 100, ибо 2-3 пикселя погоды не сделают, скорость поиска от этого не упадет

------------------------------------------------------------------------------------
#accuracy 89
Изображение
26 пикселей из 29 - картинка найдена
------------------------------------------------
#accuracy 89
Изображение
26 пикселей из 29 - картинка найдена
в данном случае пилот проходит по в 28 пикселям в картинке, а это тоже самое, что #accuracy 97-99
------------------------------------------------
#accuracy 89
Изображение
26 пикселей из 29 - картинка НЕ найдена (найдено всего 25 пикселей)
в данном случае пилот проходит по всем 29 пикселям в картинке, а это тоже самое, что #accuracy 100

Автор: Cockney 15.4.2017, 15:10

Кто-то писал когда-то :

Код
Точность = (количество_совпавших_точек)/(sizeX*sizeY - 1)

Автор: cirus 15.4.2017, 19:45

Цитата
и вывод: для мелких картинок можно ставить set #accuracy 100, ибо 2-3 пикселя погоды не сделают, скорость поиска от этого не упадет

Область поиска влияет на скорость. Всё остальное не существенно. Если конечно картинка не 200*200 пикселей.
Цитата
Точность = (количество_совпавших_точек)/(sizeX*sizeY - 1)

Если закрасить половину картинки в цвет фона, то придётся указывать точность поиска 50%.
Предположу что так:
Код
Точность = (количество_совпавших_точек)/(sizeX*sizeY - количество_пикселей_фона)


Автор: dron4938 15.4.2017, 20:23

Цитата(cirus @ 15.4.2017, 20:45) *

Если закрасить половину картинки в цвет фона, то придётся указывать точность поиска 50%.

Вроде как нет.
Пример:
Если закрасить картинку 50% фоном
Изображение

То пилот будет искать 17 пикселей из всех 35.
И если задать точность поиска 50%, то из этих 17 пикселей, достаточно будет найти 8, что-бы картинка нашлась.
50% от 17 = 50 х (1 / 100) х 17 = 8,5

Изображение
и соответственно может определить картинку не верно

Автор: cirus 15.4.2017, 20:48

Цитата
Вроде как нет.

Если дочитать мой пост до конца, то там написана правильная формула.

Автор: dron4938 15.4.2017, 21:15

Цитата(cirus @ 15.4.2017, 21:48) *

Если дочитать мой пост до конца, то там написана правильная формула.

а как эту формулу разобрать? что ставить вместо вопросов?
Точность = (количество_совпавших_точек)/(sizeX*sizeY - количество_пикселей_фона)
50 = (???) / (5x7 - 18)

Автор: cirus 15.4.2017, 22:02

Картинка 5*7, 35 пикселей, 17 закрашиваем, значит 18 остаётся.
По идее так:

Код
18 * 100 / (5 * 7 - 17) - 100%, если нашлось 18 из 18 не закрашенных пикселей.
9 * 100 / (5 * 7 - 17) - 50%, если нашлось 9 из 18 не закрашенных пикселей.

Как на самом деле у Кнайта надо узнавать.



Автор: dron4938 15.4.2017, 22:10

Небольшой пример, есть 2 картинки (8х12)=96px с 50% закрашенным фоном, если присмотреться то верхушки картинок абсолютно схожи и если ставить точность поиска 50%, то в одной картинке поиск находит сразу две.
Изображение

Изображение

Изображение

96 пикселей из них 49 пикселей это фон и другие 47 картинка
Пилот ищет по 47 пикселям
50% от 47 = 23,5
(50 × (1 / 100) × 47 = 23,5)
т.е. найдя 23 пикселя, пилот скажет, что картинка найдена

Изображение





код

init_arr %GetImage (1) 0, 0 200, 80 // координаты для поиска, StartX StartY EndX EndY

set linedelay 0
init_arr %picture 8 9 // имена картинок (0.bmp, 1.bmp и т. д.)
init_arr %symbol 8 9 // символ соответствующий имени, т. е. картинка 0.bmp соответствует 0
set $path "C:\number" // папка с картинками
set $bmp "*.bmp*" // формат картинок
set #deltaY 8 // расстояние между строками (можно указать высоту картинок)
set #deltaspace 12 // допустимое расстояние между цифрами, иначе будет считаться что это не одно число
set #accuracy 50 // точность поиска для Findimage
set #deviation 0 // погрешность оттенка для Findimage
set #wait 1 // пауза между поиском картинок, если указать меньше искать будет быстрее, но нагрузит процессор
set #timeproc 200 // время (в мсек) для поиска картинок, если 0 не выйдет из процедуры пока не найдётся хотя бы 1 картинка


dir (%path $path $bmp)
set delimiter ' '
while 1 = 1
set size(%result) // уничтожить массив с предыдущими результатами
call test %picture %symbol %GetImage %path #deltaY #deltaspace #accuracy #deviation #wait #timeproc // процедура поиска
// save_array %result C:\resultarr.txt // массив с результатами поиска

if size(%result) > 0 // если размер массива больше 0
// ТУТ НУЖНЫЕ ДЕЙСТВИЯ
///////////// для примера вывод в hint того что нашлось (можно убрать)
set $str
set %z [1] \n
for #i 1 size(%result)
set $str $str%result[#i]
if #i != size(%result)
set $str $str%z [1]
end_if
end_for
hint (14 clBlue 139, 33 ($str))
/////////////
else
hint Картинки не найдены
end_if
end_while

// процедура поиска и сортировки
proc test %picture %symbol %GetImage %path #deltaY #deltaspace #accuracy #deviation #wait #timeproc
set #GetStartX %GetImage [1 1]
set #GetStartY %GetImage [1 2]
set #GetEndX %GetImage [1 3]
set #GetEndY %GetImage [1 4]
set #current_script current_script
// загрузка картинок в память
if size(%path) > 0 // если картинки найдены
for #i 1 size(%path)
for #j 1 size(%picture)
if %path [#i 3] = %picture [#j]
set #n #n + 1
set %image [#n] LoadImage(%path [#i 1])
set %number [#n] %symbol [#j]
break
end_if
end_for
end_for
else
log Картинки в: $path не найдены
log Скрипт остановлен
stop_script #current_script
end_if
// поиск картинок и их сортировка
set size(%result1)
while size(%result1) = 0 and (#timeproc > timer or #timeproc = 0)
set #z 0
set %get GetImage(#GetStartX #GetStartY #GetEndX #GetEndY) // сохранить часть экрана в память
set #v %get [1 1]
for #i 1 size(%number)
set #a Findimage(0 0 %get [1 2] %get [1 3] (%image[#i 1]) %a #v #accuracy -1 #deviation) // поиск
if #a < 0
log Ошибка поиска картинки. Код ошибки: #a
log Скрипт остановлен
stop_script #current_script
end_if
if #a > 0
for #j 1 size(%a)
set #z #z + 1
init_arr %result1 (1 1 #z) %number[#i] %a[#j 1] %a[#j 2] // запись результатов поиска в массив
end_for
end_if
wait #wait
end_for
if size(%result1) > 0
gosub sortY // сортировка по Y и X
end_if
set $b DeleteImage(%get[1 1]) // удалить изображение, полученное GetImage
end_while
goto end // выйти из процедуры

:sortY
set #z 0
set #z1 0
set #z2 1
set #z4 0
sort_array %result1 -3
while 1 = 1
set #z 0
set size(%tmp)
for #i #z2 eval(size(%result1 [1]) - 1)
set #j #i + 1
set #x %result1 [3 #i] - %result1 [3 #j]
if abs(#x) < #deltaY
set #z #z + 1
init_arr %tmp (1 1 #z) %result1 [1 #i] %result1 [2 #i] %result1 [3 #i]
else
set #z #z + 1
init_arr %tmp (1 1 #z) %result1 [1 #i] %result1 [2 #i] %result1 [3 #i]
break
end_if
end_for
set #z2 #z2 + #z
if #z2 = size(%result1[])
set #x %result1 [3 #i] - %result1 [3 #j]
if abs(#x) > #deltaY
set #jj #j
sort_array %tmp -2
set #z1 #z1 + 1
init_arr %result (#z1) %tmp [1]
gosub space
set size(%tmp)
set #z #z + 1
init_arr %tmp (1 1 #z) %result1 [1 #jj] %result1 [2 #jj] %result1 [3 #jj]
set #z1 #z1 + 1
set %result.#current_script [#z1] %tmp [1]
gosub end
end_if
set #z #z + 1
init_arr %tmp (1 1 #z) %result1 [1 #j] %result1 [2 #j] %result1 [3 #j]
sort_array %tmp -2
set #z1 #z1 + 1
init_arr %result (#z1) %tmp [1]
gosub space
break
else
sort_array %tmp -2
set #z1 #z1 + 1
init_arr %result (#z1) %tmp [1]
gosub space
end_if
end_while
return

:space
set #z3 0
set size(%space)
set #z4 #z4 + 1
//посчитать где нужны пробелы
for #i 1 eval(size(%tmp[]) - 1)
set #j #i + 1
set #space %tmp [2 #i] - %tmp [2 #j]
if abs(#space) > #deltaspace
set #z3 #z3 + 1
set %space[#z3] #j
end_if
end_for
// вставить пробелы
for #i 1 size(%space)
set $str %result [#z4]
set $str insert(" " $str %space[#i])
set #j #i + 1
set %space[#j] %space[#j] + #i
set %result [#z4] $str
end_for
// сохранение массива в основном скрипте
for #i 1 size(%result)
set size(%tmp1)
init_arr %tmp1 (1) %result [#i]
for #j 1 size(%tmp1[1])
set %result.#current_script [#i #j] %tmp1 [1 #j]
end_for
end_for
return

:end
end_proc



Прикрепленные файлы
Прикрепленный файл  number.rar ( 647 байт ) Кол-во скачиваний: 1792

Автор: cirus 15.4.2017, 22:42

Цитата
и если ставить точность поиска 50%

А зачем ставить 50?
Цитата
Пилот ищет по 47 пикселям
50% от 47 = 23,5
(50 × (1 / 100) × 47 = 23,5)
т.е. найдя 23 пикселя, пилот скажет, что картинка найдена

Всё правильно.
Про закрашенные пиксели можно вообще забыть. Считайте что их нет. Учитываются только те, что не являются цветом фона.

Автор: dron4938 15.4.2017, 22:58

Прогнал через поиск 100 раз картинку 180х280px с разными параметрами и немного удивился.
Оказывается точность вообще на время поиска не влияет.

Изображение

а вот #deviation cool.gif

Автор: Cockney 15.4.2017, 23:05

а где написано было ,что точность влияет на поиск ? Точность вообще ,грубо говоря, производная поиска. И к нему вообще не имеет отношения.

отклонение цвета же имеет прямое отношение к поиску и от него зависит кол-во цветов для сравнения.

Автор: cirus 15.4.2017, 23:08

Цитата
Оказывается точность вообще на время поиска не влияет.

Точность найденного изображения вычисляется после поиска, а не во время. При любой точности будут проверены все пиксели.


Автор: dron4938 15.4.2017, 23:13

Цитата(cirus @ 16.4.2017, 0:08) *

Точность найденного изображения вычисляется после поиска, а не во время. При любой точности будут проверены все пиксели.

А всё) теперь дошло как оно работает smile.gif

Автор: DarkMaster 16.4.2017, 9:33

Цитата
При любой точности будут проверены все пиксели.

насколько я помню - это не так. По крайней мере в сложных случаях с большим deviation приходилось увеличивать минимальную точность, чтобы понять с какой именно точностью находится изображение. Возможно это тонкости deviation.

Автор: WKnight 16.4.2017, 9:52

Точность = (количество_совпавших_точек*100)/(sizeX*sizeY - количество_пикселей_фона)

Цитата
Точность найденного изображения вычисляется после поиска, а не во время. При любой точности будут проверены все пиксели.


Автор: DarkMaster 16.4.2017, 11:04

Ок. Как тогда объяснить, что при больших значениях deviation, здоровых изображениях с большим фоном и малой точности % совападения зависит от выставленного минимального?
т.е. берем некторое изображение и ищем его 2 50 1 20
результат точности: 54%
увеличиваем минимальную точность 2 75 1 20
результат точности: 76%
увеличиваем еще 2 80 1 20
результат точности: не нашло.

Это ситуация встречалась на практике у меня не 1 и не 2 раза. Проявляется она в тяжелых случаях, как правило при поиске изображений обезображенных переливами jpg.

Автор: dron4938 22.5.2017, 1:15

Можно ли как то прописать поиск не из заданной области экрана, а из картинки
например:

set %a GetImage (0 0 100 100) // сохранить в памяти часть экранной области
set $bmp SaveImage (%a [1 1] C:\picture.bmp) // сохранить в файл на диск C:\
затем сделать поиск в этой сохраненной картинке

типа как финдимидж, только вместо координат путь к картинке
set #a FindImage (C:\picture.bmp ("C:\pilot\A.bmp") %arr 2 1 1 1)
rolleyes.gif

Автор: cirus 22.5.2017, 1:55

Без сохранения в файл:

Код
set %a GetImage (0 0 100 100)
set #a FindImage (0 0 100 100 ("C:\pilot\A.bmp") %arr %a [1 1] 1 1 1)  // вместо типа поиска - адрес в памяти
if #a > 0

end_if
set $del DeleteImage  (%a [1 1])  // удалить изображение из памяти

Поиск на картинке из файла:
Код
set %a GetImage (0 0 100 100) // сохранить в памяти часть экранной области
set $bmp SaveImage (%a [1 1] C:\picture.bmp) // сохранить в файл на диск C:\
   // тут возможно нужен wait чтоб картинка успела сохраниться/перезаписаться
set %b [1]  LoadImage (C:\picture.bmp)
set #a FindImage (0 0 100 100 ("C:\pilot\A.bmp") %arr %b [1 1] 1 1 1)
if #a > 0

end_if
set $del DeleteImage  (%b [1 1])

Не забываем удалять из памяти сохранённые через GetImage изображения , иначе пилот сожрёт 2гб памяти и будет ошибка.


Автор: dron4938 23.5.2017, 20:18

Спасябки smile.gif
Кстати а изменения можно посредством пилота внести в сохраненное изображение?
Сделать например изображение черно белым и уже потом поиск в нем произвести?

И можно ли чтобы картинка сохранялась новая, а не заменялась старая
set $bmp SaveImage (%a [1 1] C:\picture.bmp) // сохранить в файл на диск C:\

типа как
picture1.bmp
picture2.bmp
picture3.bmp
вернее даже не так)

наверное будет правильнее, что если такая картинка существует уже, то прибавить +1 к имени файла

получилось вот таким макаром
set #th Hour
set #tm Min
set #ts Sec
set $bm ".bmp"
set $bmp SaveImage (%a [1 1] C:\#th#tm#ts$bm) // сохранить в файл на диск C:\



Автор: cirus 24.5.2017, 2:26

Вопросы не касающиеся поиска числа задавайте в другой теме, лучше новой.

Цитата
Кстати а изменения можно посредством пилота внести в сохраненное изображение?

Пример
Код
set %a getimage (402, 395 442, 438)

set workwindow windowhandle
// закрасить первый пиксель в белый цвет
set #blue %a [1 1]
set #green %a [1 1] + 1
set #red %a [1 1] + 2
writemem 255 #blue b
writemem 255 #green b
writemem 255 #red b

// закрасить второй пиксель в чёрный цвет
set #blue %a [1 1] + 3
set #green %a [1 1] + 4
set #red %a [1 1] + 5
writemem 0 #blue b
writemem 0 #green b
writemem 0 #red b
// сохранить изменённую картинку
set $bmp SaveImage (%a[1 1] C:\qqq.bmp)
end_script

Цитата
наверное будет правильнее, что если такая картинка существует уже, то прибавить +1 к имени файла

Через dir находим сколько картинок уже есть, прибавляем 1.

Автор: dron4938 24.5.2017, 13:40

так это-же для поиска чисел) цветных
я тут подумал, что если картинку с цифрой перед поиском делать черно-белой, то можно будет более быстрее находить)

Код
set %a GetImage (0 0 100 100) // сохранить в памяти часть экранной области
set $bmp SaveImage (%a [1 1] C:\picture.bmp) // сохранить в файл на диск C:\
[b]тут код преобразовывающий картинку в черно белую[/b]
set %b [1]  LoadImage (C:\picture.bmp)
set #a FindImage (0 0 100 100 ("C:\pilot\A.bmp") %arr %b [1 1] 1 1 1)
set $del DeleteImage  (%b [1 1])
if #a = 100
end_if


Изображение
Изображение

как видим черно-белая преобразованная цифра имеет 100% схожесть в пикселях

Но скорее всего код будет огромным. наверно я ошибся) rolleyes.gif

Автор: cirus 24.5.2017, 14:18

Цитата
Но скорее всего код будет огромным.

Код не большой, только перевод картинки в черно-белый цвет на языке пилота займёт больше времени, чем просто поиск цифр разного цвета. Это надо делать отдельную функцию.

Автор: dron4938 24.5.2017, 14:25

Цитата(cirus @ 24.5.2017, 15:18) *

не большой, только перевод картинки в черно-белый цвет на языке пилота займёт больше времени, чем просто поиск цифр разного цвета. Это надо делать отдельную функцию.

в питоне есть такая функция, мб оттуда скопипастить)
https://habrahabr.ru/post/163663/

Автор: dron4938 24.5.2017, 19:34

Консольное изменение изображений (консольный фотошоп)

1. Скачиваем программу ImageMagick http://www.imagemagick.org/script/download.php
Крутим страницу в самый низ и скачиваем по последней ссылке ImageMagick-7.0.5-7-portable-Q16-x64.zip (для 64 винды)
это версия в архиве, не требующая установки- другие версии не заработали у меня чет)
2. Для удобства распаковываем в папку C:\Magic
3. Готово smile.gif

теперь в пилоте вместо обычного поиска картинки:

Код
set timer
set #a FindImage (0 0 300 300 ("C:\Users\Andrey\Desktop\Pil3\1.bmp") %arr 2 80 1 1)
if #a > 0
hint #a
end_if
log timer
end_script


поиск можно делать так:
Код
set timer
set %a GetImage (0 0 300 300) // сохранить в памяти часть экранной области
set $bmp SaveImage (%a [1 1] C:\picture.bmp) // сохранить в файл
exec C:\Magic\convert.exe "C:\picture.bmp" -colorspace gray "C:\picture.bmp"
wait 100
set %b [1]  LoadImage (C:\picture.bmp)
set #a FindImage (0 0 300 300 ("C:\Users\Andrey\Desktop\Pil3\2.bmp") %arr %b [1 1] 80 1 1)
set $del DeleteImage  (%b [1 1])
if #a > 0
hint #a
end_if
log timer
end_script

-----------------------------------------------
после изменения изображения приходится ставить паузу.
Методом научного тыка выяснилось, что если:
картинка 10х10pix то хватит паузы в ~40мс
картинка 100х100pix то хватит паузы в ~60мс
картинка 500х500pix то хватит паузы в ~90мс

возможно если сохранять картинку на SSD, то будет в пару раз быстрее

Соответственно поиск будет дольше, чем обычный. Но может пригодится в некоторых случаях, по этому оставлю здесь статью, чтоб не забыть)
--------------------------------------------------
Некоторые команды ImageMagick:
convert.exe img.png img.jpg (преобразует любые расширения изображений в другие jpg bmp png и т.д)
-colorspace gray (делает изображение черно-белым)
-resize 100×150 (изменяет размер изображения)
-resize 200% (изменяет размер изображения)
-rotate +20 (поворачивает изображение на указанный угол по часовой стрелке)
-rotate -20 (поворачивает изображение на указанный угол против часовой стрелки)
-normalize -posterize 3 (постеризация- число оттенков)
-gamma 0.1 (гамма)
-sepia-tone 80% (сепия)
-negate (негатив)
-brightness-contrast -20% (контраст меньше)
-brightness-contrast 20% (контраст больше)
-monochrome -normalize (монохромность)

Применять можно сразу несколько команд, напрмер:
exec C:\Magic\convert.exe "C:\picture.bmp" -resize 200% -colorspace gray -gamma 0.1 "C:\picture.bmp"

так же существует еще множество команд, которые можно найти в инете.
-----------------------------------------------------
Пример что можно получить, прогнав картинку через несколько фильтров:

Код
exec C:\Magic\convert.exe "C:\Users\andrey\Desktop\111\1.bmp" -resize 300% "C:\Users\andrey\Desktop\111\2.bmp"
wait 40
exec C:\Magic\convert.exe "C:\Users\andrey\Desktop\111\2.bmp" -colorspace gray "C:\Users\andrey\Desktop\111\3.bmp"
wait 40
exec C:\Magic\convert.exe "C:\Users\andrey\Desktop\111\3.bmp" -normalize -posterize 3 "C:\Users\andrey\Desktop\111\4.bmp"
wait 40
exec C:\Magic\convert.exe "C:\Users\andrey\Desktop\111\4.bmp" -gamma 0.1 "C:\Users\andrey\Desktop\111\5.bmp"
wait 40
exec C:\Magic\convert.exe "C:\Users\andrey\Desktop\111\5.bmp" -resize 33% "C:\Users\andrey\Desktop\111\6.bmp"
wait 100


Изображение 1

Изображение 2 -resize 300%

Изображение 3 -colorspace gray

Изображение 4 -normalize -posterize 3

Изображение 5 -gamma 0.1

Изображение 6 -resize 33%

пример для наглядности, весь кодд можно прописать 1 строкой:

Код
exec C:\Magic\convert.exe "C:\Users\andrey\Desktop\111\1.bmp" -resize 300% -colorspace gray -normalize -posterize 3 -gamma 0.1 -resize 33% "C:\Users\andrey\Desktop\111\1.bmp"
wait 100


Можно применять для поиска цветных и изменяющихся цифр к примеру, дабы не делать 100500 картинок с цифрами разного цвета

Автор: cirus 25.5.2017, 2:16

Цитата
после изменения изображения приходится ставить паузу.

Удаляем старую картинку и ждём пока не сохранится новая:
Код
filedelete (С:\picture2.bmp)    // удалить файл
exec C:\Magic\convert.exe "C:\picture.bmp" -colorspace gray "С:\picture2.bmp"   // сохранить с нужными изменениями
while fileexists (С:\picture2.bmp) = 0   // ждать пока файл не сохранится
    wait 1
end_while

Автор: dron4938 25.5.2017, 3:12

filedelete (С:\picture2.bmp) // удалить файл
exec C:\Magic\convert.exe "C:\picture.bmp" -colorspace gray "С:\picture2.bmp" // сохранить с нужными изменениями
while fileexists (С:\picture2.bmp) = 0 // ждать пока файл не сохранится
wait 1
end_while

не работает, файлделет не удаляет файл
и из цикла не выходит, хотя файл существует
странно чета

копирую файл на рабочий стол и пробую от туда удалить и удаляет)
filedelete ("C:\Users\andrey\Desktop\picture2.bmp")

а с диска С не хочет удалять
пилот от админа запущен, но походу всеравно прав не хватает на удаление
-----------------------------------------------------------
заработало, когда на рабочий стол перенес

Код
set timer
set %a GetImage (0 0 300 300) // сохранить в памяти часть экранной области
set $bmp SaveImage (%a [1 1] C:\Users\andrey\Desktop\picture.bmp) // сохранить в файл
filedelete ("C:\Users\andrey\Desktop\picture2.bmp")
exec C:\Magic\convert.exe "C:\Users\andrey\Desktop\picture.bmp" -colorspace gray "C:\Users\andrey\Desktop\picture2.bmp"   // сохранить с нужными изменениями
while fileexists (C:\Users\andrey\Desktop\picture2.bmp) = 0   // ждать пока файл не сохранится
    wait 1
end_while
set %b [1]  LoadImage (C:\Users\andrey\Desktop\picture2.bmp)
set #a FindImage (0 0 300 300 ("C:\Users\Andrey\Desktop\2.bmp") %arr %b [1 1] 80 1 1)
set $del DeleteImage  (%b [1 1])
if  #a > 0
    hint время- timer мс Картинка найдена #a
end_if
end_script

Автор: dron4938 9.6.2017, 21:46

Поиск числа с помощью Findimage 3.0

Код
// Поиск числа с помощью FindImage
init_arr %GetImage (1) 0 0 99, 58     // координаты для поиска, StartX StartY EndX EndY

set linedelay 0
init_arr %picture 0 1 2 3 4 5 6 7 8 9     // имена картинок (0.bmp, 1.bmp и т. д.)
init_arr %symbol 0 1 2 3 4 5 6 7 8 9    // символ соответствующий имени, т. е. картинка 0.bmp соответствует 0
set $path "C:\Number2"                     // папка с картинками
set $bmp "*.bmp*"                           // формат картинок
set #deltaY 8                               // расстояние между строками (можно указать высоту картинок)
set #deltaspace 12                          // допустимое расстояние между цифрами, иначе будет считаться что это не одно число
set #accuracy 90                            // точность поиска для Findimage
set #deviation 3                            // погрешность оттенка  для Findimage
set #wait 2                                 // пауза между поиском картинок, если указать меньше искать будет быстрее, но нагрузит процессор
set #timeproc 2000                          // время (в мсек) для поиска картинок, если 0 не выйдет из процедуры пока не найдётся хотя бы 1 картинка
set #repeatimage 2                          // допустимое смещение координат, если используется несколько видов одной картинки

dir (%path $path $bmp)
set delimiter '   '
while 1 = 1
    set size(%result)                        // уничтожить массив с предыдущими результатами
    call test %picture %symbol %GetImage %path #deltaY #deltaspace #accuracy #deviation #wait #timeproc #repeatimage    // процедура поиска
    // save_array %result C:\resultarr.txt     // массив с результатами поиска

    if  size(%result) > 0         // если размер массива больше 0
        // ТУТ НУЖНЫЕ ДЕЙСТВИЯ
        ///////////// для примера вывод в hint того что нашлось (можно убрать)
        set $str
        set %z [1] \n
        for #i 1 size(%result)
            set $str $str%result[#i]
            if  #i != size(%result)
                set $str $str%z [1]
            end_if
        end_for
        hint (14 clBlue 409, 265 ($str))
        /////////////
    else
        hint Картинки не найдены
    end_if
end_while

// процедура поиска и сортировки
proc test %picture %symbol %GetImage %path #deltaY #deltaspace #accuracy #deviation #wait #timeproc #repeatimage
    set #GetStartX %GetImage [1 1]
    set #GetStartY %GetImage [1 2]
    set #GetEndX %GetImage [1 3]
    set #GetEndY %GetImage [1 4]
    set #current_script current_script
    // загрузка картинок в память
    if  size(%path) > 0                  // если картинки найдены
        for #i 1 size(%path)
            for #j 1 size(%picture)
                if  %path [#i 3] = %picture [#j]
                    set #n #n + 1
                    set %image [#n] LoadImage(%path [#i 1])
                    set %number [#n] %symbol [#j]
                    break
                end_if
            end_for
        end_for
    else
        log Картинки в: $path   не найдены
        log Скрипт остановлен
        stop_script #current_script
    end_if
    // поиск картинок и их сортировка
    set size(%result1)
    while size(%result1) = 0 and (#timeproc > timer or #timeproc = 0)
        set #z 0
        set %get GetImage(#GetStartX #GetStartY #GetEndX #GetEndY)      // сохранить часть экрана в память
        set #v %get [1 1]
        for #i 1 size(%number)
            set #a Findimage(0 0 %get [1 2] %get [1 3] (%image[#i 1]) %a #v #accuracy -1 #deviation)   // поиск
            if  #a < 0
                log Ошибка поиска картинки. Код ошибки: #a
                log Скрипт остановлен
                stop_script #current_script
            end_if
            if  #a > 0
                for #j 1 size(%a)
                    set #z #z + 1
                    init_arr %result1 (1 1 #z) %number[#i] %a[#j 1] %a[#j 2]   // запись результатов поиска в массив
                end_for
            end_if
            wait #wait
        end_for
        if  size(%result1) > 0
            gosub sortY        // сортировка по Y и X
        end_if
        set $b DeleteImage(%get[1 1])    // удалить изображение, полученное GetImage
    end_while
    goto end                 // выйти из процедуры

    :sortY
    ///// удаление повторных координат, если используется несколько видов одной картинки
        set #size 0
        set %tmp %result1
        set size(%result1)
        for #i 1 size(%tmp[1])
            set #break 0
            for #n 1 #size
                set #xrepeat %tmp[2 #i] - %result1[2 #n]
                set #yrepeat %tmp[3 #i] - %result1[3 #n]
                if  abs(#xrepeat) <= #repeatimage and abs(#yrepeat) <= #repeatimage
                    set #break 1
                    break
                end_if
            end_for
            if  #break = 0
                set #size #size + 1
                init_arr %result1 (1 1 #size) %tmp [1 #i]  %tmp [2 #i] %tmp [3 #i]
            end_if
        end_for
     ///////

        set #z 0
        set #z1 0
        set #z2 1
        set #z4 0
        sort_array %result1 -3
        while 1 = 1
            set #z 0
            set size(%tmp)
            for #i #z2 eval(size(%result1 [1]) - 1)
                set #j #i + 1
                set #x %result1 [3 #i] - %result1 [3 #j]
                if  abs(#x) < #deltaY
                    set #z #z + 1
                    init_arr %tmp (1 1 #z) %result1 [1 #i]  %result1 [2 #i] %result1 [3 #i]
                else
                    set #z #z + 1
                    init_arr %tmp (1 1 #z) %result1 [1 #i]  %result1 [2 #i] %result1 [3 #i]
                    break
                end_if
            end_for
            set #z2 #z2 + #z
            if  #z2 = size(%result1[])
                set #x %result1 [3 #i] - %result1 [3 #j]
                if  abs(#x) > #deltaY
                    set #jj #j
                    sort_array %tmp -2
                    set #z1 #z1 + 1
                    init_arr %result (#z1) %tmp [1]
                    gosub space
                    set size(%tmp)
                    set #z #z + 1
                    init_arr %tmp (1 1 #z) %result1 [1 #jj]  %result1 [2 #jj] %result1 [3 #jj]
                    set #z1 #z1 + 1
                    set %result.#current_script [#z1] %tmp [1]
                    gosub end
                end_if
                set #z #z + 1
                init_arr %tmp (1 1 #z) %result1 [1 #j]  %result1 [2 #j] %result1 [3 #j]
                sort_array %tmp -2
                set #z1 #z1 + 1
                init_arr %result (#z1) %tmp [1]
                gosub space
                break
            else
                sort_array %tmp -2
                set #z1 #z1 + 1
                init_arr %result (#z1) %tmp [1]
                gosub space
            end_if
        end_while
    return

    :space
        set #z3 0
        set size(%space)
        set #z4 #z4 + 1
        //посчитать где нужны пробелы
        for #i 1 eval(size(%tmp[]) - 1)
            set #j #i + 1
            set #space  %tmp [2 #i] - %tmp [2 #j]
            if  abs(#space) > #deltaspace
                set #z3 #z3 + 1
                set %space[#z3] #j
            end_if
        end_for
        // вставить пробелы
        for #i 1 size(%space)
            set $str %result [#z4]
            set $str insert(" " $str %space[#i])
            set #j #i + 1
            set %space[#j] %space[#j] + #i
            set %result [#z4] $str
        end_for
        // сохранение массива в основном скрипте
        for #i 1 size(%result)
            set size(%tmp1)
            init_arr %tmp1 (1) %result [#i]
            for #j 1 size(%tmp1[1])
                set %result.#current_script [#i #j] %tmp1 [1 #j]
            end_for
        end_for
    return

    :end
end_proc



как в этом коде сделать чтобы использовался поиск workwindow

Автор: cirus 10.6.2017, 1:54

Находим строку:

Код
set %get GetImage(#GetStartX #GetStartY #GetEndX #GetEndY)      // сохранить часть экрана в память

Дописываем хендл окна или переменную workwindow:
Код
set %get GetImage(#GetStartX #GetStartY #GetEndX #GetEndY workwindow)


Автор: ivanTu 30.8.2017, 11:28

Уважаемый cirus, а как быть если к примеру "2" и "22" имеют разный вид двойки, подскажите пожалуйста.

Автор: cirus 30.8.2017, 11:50

Цитата
как быть если к примеру "2" и "22" имеют разный вид двойки

Можно искать несколько видов одной и той же цифры.
Код
init_arr %picture 0 1 2 2 2 3 4 5 6 7 8 9     
init_arr %symbol 0 1 2 2a 2b 3 4 5 6 7 8 9    // 3 картинки цифры 2


Автор: ivanTu 30.8.2017, 11:53

Спасибо cirus , Вы Молодец!

Автор: ivanTu 1.9.2017, 10:16

Уважаемый cirus , Не могли бы Вы мне помочь с кодом, у меня в игре есть 4ре ячейки с мобами, и я хотел последовательно проверять уровень мобов в каждой из ячеек, верхнюю правую нижнюю левую, картинки с цифрами все подготовил, а вот код не могу сформулировать в голове, и самое печально то, что для каждой ячейки с мобами идут свои картинки с цифрами, т.е у меня сейчас 4ре папки с картинками, собственно сам вопрос заключается в том, как мне прописать допустим в общем скрипте проверку всех четырёх ячеек с мобами и если к примеру моб достиг 25 лвла кликнуть по нему, ну с кликами я сам разберусь, самое главное проверку сделать, прилагаю скриншот для наглядности, спасибо за ранее если сможете мне помочь.
Извиняюсь если не по теме написал.



Эскизы прикрепленных изображений
Прикрепленное изображение

Автор: cirus 1.9.2017, 12:24

Теоретически можно искать все числа сразу, но надо тестить. Скиньте мне все картинки с цифрами и несколько картинок в bmp с мобами. В выходные гляну.
Пока делать 4 отдельных поиска, как-то так:

код
Код
set linedelay 0
init_arr %picture 0 1 2 3 4 5 6 7 8 9       // имена картинок (0.bmp, 1.bmp и т. д.)
init_arr %symbol 0 1 2 3 4 5 6 7 8 9        // символ соответствующий имени, т. е. картинка 0.bmp соответствует 0
set $bmp "*.bmp*"                           // формат картинок
set #deltaY 8                               // расстояние между строками (можно указать высоту картинок)
set #deltaspace 12                          // допустимое расстояние между цифрами, иначе будет считаться что это не одно число
set #accuracy 90                            // точность поиска для Findimage
set #deviation 3                            // погрешность оттенка  для Findimage
set #wait 2                                 // пауза между поиском картинок, если указать меньше искать будет быстрее, но нагрузит процессор
set #timeproc 2000                          // время (в мсек) для поиска картинок, если 0 не выйдет из процедуры пока не найдётся хотя бы 1 картинка

// 4 папки с картинками, цифры во всех папках назвать одинаково 0.bmp, 1.bmp и т. д.
set $path1 "C:\l2number1"                   // папка с картинками верхнего числа
set $path2 "C:\l2number2"                   // папка с картинками левого
set $path3 "C:\l2number3"                   // папка с картинками правого
set $path4 "C:\l2number4"                   // папка с картинками нижнего

// 4 массива с координатами
init_arr %GetImage1 (1) 132, 54 167, 83     // координаты для поиска верхнего числа
init_arr %GetImage2 (1) 50, 100 82, 126     // координаты для поиска левого
init_arr %GetImage3 (1) 229, 105 248, 124   // координаты для поиска правого
init_arr %GetImage4 (1) 142, 148 167, 171   // координаты для поиска нижнего


dir (%path1 $path1 $bmp)
dir (%path2 $path2 $bmp)
dir (%path3 $path3 $bmp)
dir (%path4 $path4 $bmp)

while 1 = 1
    // тут ваш скрипт
    gosub find   // переход к подпрограмме поиска цифр
end_while


// подпрограмма поиска цифр
:find
    // поиск картиноки из папки C:\l2number1, координаты %GetImage1
    set size(%result)                        // уничтожить массив с предыдущими результатами
    call test %picture %symbol %GetImage1 %path1 #deltaY #deltaspace #accuracy #deviation #wait #timeproc     // процедура поиска
    if  size(%result) > 0         // если размер массива больше 0
        // ТУТ НУЖНЫЕ ДЕЙСТВИЯ, например
        if %result [1 1] = 25    // если число равно 25
            log Число равно 25 !!!!!!
        else                    // иначе
            log Число равно %result [1 1]
        end_if
    end_if

    // поиск картиноки из папки C:\l2number2, координаты %GetImage2
    set size(%result)                        // уничтожить массив с предыдущими результатами
    call test %picture %symbol %GetImage2 %path2 #deltaY #deltaspace #accuracy #deviation #wait #timeproc     // процедура поиска, ищутся картинки из папки C:\l2number2
    if  size(%result) > 0         // если размер массива больше 0
        if %result [1 1] = 25    // если число равно 25
            log Число равно 25 !!!!!!
        end_if
    end_if

    // для остальных дописать
return


// процедура поиска и сортировки
proc test %picture %symbol %GetImage %path #deltaY #deltaspace #accuracy #deviation #wait #timeproc
    set #GetStartX %GetImage [1 1]
    set #GetStartY %GetImage [1 2]
    set #GetEndX %GetImage [1 3]
    set #GetEndY %GetImage [1 4]
    set #current_script current_script
    // загрузка картинок в память
    if  size(%path) > 0                  // если картинки найдены
        for #i 1 size(%path)
            for #j 1 size(%picture)
                if  %path [#i 3] = %picture [#j]
                    set #n #n + 1
                    set %image [#n] LoadImage(%path [#i 1])
                    set %number [#n] %symbol [#j]
                    break
                end_if
            end_for
        end_for
    else
        log Картинки в: $path   не найдены
        log Скрипт остановлен
        stop_script #current_script
    end_if
    // поиск картинок и их сортировка
    set size(%result1)
    while size(%result1) = 0 and (#timeproc > timer or #timeproc = 0)
        set #z 0
        set %get GetImage(#GetStartX #GetStartY #GetEndX #GetEndY)      // сохранить часть экрана в память
        set #v %get [1 1]
        for #i 1 size(%number)
            set #a Findimage(0 0 %get [1 2] %get [1 3] (%image[#i 1]) %a #v #accuracy -1 #deviation)   // поиск
            if  #a < 0
                log Ошибка поиска картинки. Код ошибки: #a
                log Скрипт остановлен
                stop_script #current_script
            end_if
            if  #a > 0
                for #j 1 size(%a)
                    set #z #z + 1
                    init_arr %result1 (1 1 #z) %number[#i] %a[#j 1] %a[#j 2]   // запись результатов поиска в массив
                end_for
            end_if
            wait #wait
        end_for
        if  size(%result1) > 0
            gosub sortY        // сортировка по Y и X
        end_if
        set $b DeleteImage(%get[1 1])    // удалить изображение, полученное GetImage
    end_while
    goto end                 // выйти из процедуры

    :sortY
        set #z 0
        set #z1 0
        set #z2 1
        set #z4 0
        sort_array %result1 -3
        while 1 = 1
            set #z 0
            set size(%tmp)
            for #i #z2 eval(size(%result1 [1]) - 1)
                set #j #i + 1
                set #x %result1 [3 #i] - %result1 [3 #j]
                if  abs(#x) < #deltaY
                    set #z #z + 1
                    init_arr %tmp (1 1 #z) %result1 [1 #i]  %result1 [2 #i] %result1 [3 #i]
                else
                    set #z #z + 1
                    init_arr %tmp (1 1 #z) %result1 [1 #i]  %result1 [2 #i] %result1 [3 #i]
                    break
                end_if
            end_for
            set #z2 #z2 + #z
            if  #z2 = size(%result1[])
                set #x %result1 [3 #i] - %result1 [3 #j]
                if  abs(#x) > #deltaY
                    set #jj #j
                    sort_array %tmp -2
                    set #z1 #z1 + 1
                    init_arr %result (#z1) %tmp [1]
                    gosub space
                    set size(%tmp)
                    set #z #z + 1
                    init_arr %tmp (1 1 #z) %result1 [1 #jj]  %result1 [2 #jj] %result1 [3 #jj]
                    set #z1 #z1 + 1
                    set %result.#current_script [#z1] %tmp [1]
                    gosub end
                end_if
                set #z #z + 1
                init_arr %tmp (1 1 #z) %result1 [1 #j]  %result1 [2 #j] %result1 [3 #j]
                sort_array %tmp -2
                set #z1 #z1 + 1
                init_arr %result (#z1) %tmp [1]
                gosub space
                break
            else
                sort_array %tmp -2
                set #z1 #z1 + 1
                init_arr %result (#z1) %tmp [1]
                gosub space
            end_if
        end_while
    return

    :space
        set #z3 0
        set size(%space)
        set #z4 #z4 + 1
        //посчитать где нужны пробелы
        for #i 1 eval(size(%tmp[]) - 1)
            set #j #i + 1
            set #space  %tmp [2 #i] - %tmp [2 #j]
            if  abs(#space) > #deltaspace
                set #z3 #z3 + 1
                set %space[#z3] #j
            end_if
        end_for
        // вставить пробелы
        for #i 1 size(%space)
            set $str %result [#z4]
            set $str insert(" " $str %space[#i])
            set #j #i + 1
            set %space[#j] %space[#j] + #i
            set %result [#z4] $str
        end_for
        // сохранение массива в основном скрипте
        for #i 1 size(%result)
            set size(%tmp1)
            init_arr %tmp1 (1) %result [#i]
            for #j 1 size(%tmp1[1])
                set %result.#current_script [#i #j] %tmp1 [1 #j]
            end_for
        end_for
    return

    :end
end_proc

Можете попробовать искать сразу все картинки:
Все картинки закинуть в одну папку, имена картинок: 0.bmp, 0a.bmp, 0b.bmp, 0c.bmp, 1.bmp, 1a.bmp, 1b.bmp, 1c.bmp и т. д
код
Код
// Поиск числа с помощью FindImage
init_arr %GetImage (1) 0 0 99, 58     // координаты для поиска, StartX StartY EndX EndY

set linedelay 0
init_arr %picture 0 1 2 3 4 5 6 7 8 9   0a 1a 2a 3a 4a 5a 6a 7a 8a 9a   0b 1b 2b 3b 4b 5b 6b 7b 8b 9b   0c 1c 2c 3c 4c 5c 6c 7c 8c 9c   // имена картинок (0.bmp, 1.bmp и т. д.)
init_arr %symbol 0 1 2 3 4 5 6 7 8 9   0 1 2 3 4 5 6 7 8 9   0 1 2 3 4 5 6 7 8 9   0 1 2 3 4 5 6 7 8 9  // символ соответствующий имени, т. е. картинка 0.bmp соответствует 0
set $path "C:\Number2"                     // папка с картинками
set $bmp "*.bmp*"                           // формат картинок
set #deltaY 8                               // расстояние между строками (можно указать высоту картинок)
set #deltaspace 12                          // допустимое расстояние между цифрами, иначе будет считаться что это не одно число
set #accuracy 90                            // точность поиска для Findimage
set #deviation 3                            // погрешность оттенка  для Findimage
set #wait 2                                 // пауза между поиском картинок, если указать меньше искать будет быстрее, но нагрузит процессор
set #timeproc 2000                          // время (в мсек) для поиска картинок, если 0 не выйдет из процедуры пока не найдётся хотя бы 1 картинка
set #repeatimage 2                          // допустимое смещение координат, если используется несколько видов одной картинки

dir (%path $path $bmp)
set delimiter '   '
while 1 = 1
    set size(%result)                        // уничтожить массив с предыдущими результатами
    call test %picture %symbol %GetImage %path #deltaY #deltaspace #accuracy #deviation #wait #timeproc #repeatimage    // процедура поиска
    // save_array %result C:\resultarr.txt     // массив с результатами поиска

    if  size(%result) > 0         // если размер массива больше 0
        // ТУТ НУЖНЫЕ ДЕЙСТВИЯ
        ///////////// для примера вывод в hint того что нашлось (можно убрать)
        set $str
        set %z [1] \n
        for #i 1 size(%result)
            set $str $str%result[#i]
            if  #i != size(%result)
                set $str $str%z [1]
            end_if
        end_for
        hint (14 clBlue 409, 265 ($str))
        /////////////
    else
        hint Картинки не найдены
    end_if
end_while

// процедура поиска и сортировки
proc test %picture %symbol %GetImage %path #deltaY #deltaspace #accuracy #deviation #wait #timeproc #repeatimage
    set #GetStartX %GetImage [1 1]
    set #GetStartY %GetImage [1 2]
    set #GetEndX %GetImage [1 3]
    set #GetEndY %GetImage [1 4]
    set #current_script current_script
    // загрузка картинок в память
    if  size(%path) > 0                  // если картинки найдены
        for #i 1 size(%path)
            for #j 1 size(%picture)
                if  %path [#i 3] = %picture [#j]
                    set #n #n + 1
                    set %image [#n] LoadImage(%path [#i 1])
                    set %number [#n] %symbol [#j]
                    break
                end_if
            end_for
        end_for
    else
        log Картинки в: $path   не найдены
        log Скрипт остановлен
        stop_script #current_script
    end_if
    // поиск картинок и их сортировка
    set size(%result1)
    while size(%result1) = 0 and (#timeproc > timer or #timeproc = 0)
        set #z 0
        set %get GetImage(#GetStartX #GetStartY #GetEndX #GetEndY)      // сохранить часть экрана в память
        set #v %get [1 1]
        for #i 1 size(%number)
            set #a Findimage(0 0 %get [1 2] %get [1 3] (%image[#i 1]) %a #v #accuracy -1 #deviation)   // поиск
            if  #a < 0
                log Ошибка поиска картинки. Код ошибки: #a
                log Скрипт остановлен
                stop_script #current_script
            end_if
            if  #a > 0
                for #j 1 size(%a)
                    set #z #z + 1
                    init_arr %result1 (1 1 #z) %number[#i] %a[#j 1] %a[#j 2]   // запись результатов поиска в массив
                end_for
            end_if
            wait #wait
        end_for
        if  size(%result1) > 0
            gosub sortY        // сортировка по Y и X
        end_if
        set $b DeleteImage(%get[1 1])    // удалить изображение, полученное GetImage
    end_while
    goto end                 // выйти из процедуры

    :sortY
    ///// удаление повторных координат, если используется несколько видов одной картинки
        set #size 0
        set %tmp %result1
        set size(%result1)
        for #i 1 size(%tmp[1])
            set #break 0
            for #n 1 #size
                set #xrepeat %tmp[2 #i] - %result1[2 #n]
                set #yrepeat %tmp[3 #i] - %result1[3 #n]
                if  abs(#xrepeat) <= #repeatimage and abs(#yrepeat) <= #repeatimage
                    set #break 1
                    break
                end_if
            end_for
            if  #break = 0
                set #size #size + 1
                init_arr %result1 (1 1 #size) %tmp [1 #i]  %tmp [2 #i] %tmp [3 #i]
            end_if
        end_for
     ///////

        set #z 0
        set #z1 0
        set #z2 1
        set #z4 0
        sort_array %result1 -3
        while 1 = 1
            set #z 0
            set size(%tmp)
            for #i #z2 eval(size(%result1 [1]) - 1)
                set #j #i + 1
                set #x %result1 [3 #i] - %result1 [3 #j]
                if  abs(#x) < #deltaY
                    set #z #z + 1
                    init_arr %tmp (1 1 #z) %result1 [1 #i]  %result1 [2 #i] %result1 [3 #i]
                else
                    set #z #z + 1
                    init_arr %tmp (1 1 #z) %result1 [1 #i]  %result1 [2 #i] %result1 [3 #i]
                    break
                end_if
            end_for
            set #z2 #z2 + #z
            if  #z2 = size(%result1[])
                set #x %result1 [3 #i] - %result1 [3 #j]
                if  abs(#x) > #deltaY
                    set #jj #j
                    sort_array %tmp -2
                    set #z1 #z1 + 1
                    init_arr %result (#z1) %tmp [1]
                    gosub space
                    set size(%tmp)
                    set #z #z + 1
                    init_arr %tmp (1 1 #z) %result1 [1 #jj]  %result1 [2 #jj] %result1 [3 #jj]
                    set #z1 #z1 + 1
                    set %result.#current_script [#z1] %tmp [1]
                    gosub end
                end_if
                set #z #z + 1
                init_arr %tmp (1 1 #z) %result1 [1 #j]  %result1 [2 #j] %result1 [3 #j]
                sort_array %tmp -2
                set #z1 #z1 + 1
                init_arr %result (#z1) %tmp [1]
                gosub space
                break
            else
                sort_array %tmp -2
                set #z1 #z1 + 1
                init_arr %result (#z1) %tmp [1]
                gosub space
            end_if
        end_while
    return

    :space
        set #z3 0
        set size(%space)
        set #z4 #z4 + 1
        //посчитать где нужны пробелы
        for #i 1 eval(size(%tmp[]) - 1)
            set #j #i + 1
            set #space  %tmp [2 #i] - %tmp [2 #j]
            if  abs(#space) > #deltaspace
                set #z3 #z3 + 1
                set %space[#z3] #j
            end_if
        end_for
        // вставить пробелы
        for #i 1 size(%space)
            set $str %result [#z4]
            set $str insert(" " $str %space[#i])
            set #j #i + 1
            set %space[#j] %space[#j] + #i
            set %result [#z4] $str
        end_for
        // сохранение массива в основном скрипте
        for #i 1 size(%result)
            set size(%tmp1)
            init_arr %tmp1 (1) %result [#i]
            for #j 1 size(%tmp1[1])
                set %result.#current_script [#i #j] %tmp1 [1 #j]
            end_for
        end_for
    return

    :end
end_proc

Автор: ivanTu 1.9.2017, 13:47

вот файлики, Спасибо не земное!!! )


Прикрепленные файлы
Прикрепленный файл  mob_lvls.7z ( 4,18 килобайт ) Кол-во скачиваний: 359
Прикрепленный файл  mobs_images.7z ( 156,94 килобайт ) Кол-во скачиваний: 355

Автор: cirus 1.9.2017, 13:49

Можете ещё попробовать искать сразу все картинки. Код добавил в пост выше.

Автор: ivanTu 1.9.2017, 13:59

Искать сразу все очень долго, картинок очень много просто около 50ти.,
да и действия требуются для каждого моба отдельно, к примеру не достиг максимального уровня, пропускаем его, если прокачался максимально, ткнуть на моба, он автоматически убирается, и на его нужно будет впихнуть другого моба, ну это уже будет другая подпрограмма )

Автор: cirus 3.9.2017, 2:13

Цитата
Искать сразу все очень долго, картинок очень много просто около 50ти

Искать сразу быстрее и достаточно по 1 картинке каждого числа, хоть они и отличаются.
В архиве видео и картинки, которые использовались для поиска: Прикрепленный файл  Поиск_чисел.zip ( 2,13 мегабайт ) Кол-во скачиваний: 433

Картинки для поиска сохранялись скриптом https://forum.uokit.com/index.php?act=ST&f=87&t=30118&st=0#entry226016
Скрипт сохраняет картинку с теми пикселями, которые присутствуют на всех анализируемых картинках. Оставшийся фон закрашен вручную.
Цитата
да и действия требуются для каждого моба отдельно

%result [1 1] - уровень верхнего моба
%result [2 1] - уровень левого моба
%result [2 2] - уровень правого моба
%result [3 1] - уровень нижнего моба




Автор: ivanTu 4.9.2017, 9:36

Спасибо огромное cirus, сейчас буду тестировать!

Автор: ivanTu 4.9.2017, 16:26

Цитата
%result [1 1] - уровень верхнего моба
%result [2 1] - уровень левого моба
%result [2 2] - уровень правого моба
%result [3 1] - уровень нижнего моба


Что то не совсем понимаю, как это работает,

делаю проверку типа:
Код

if %result [2 2] = 25
left Кординаты правого моба
end_if


но если моба справа нет, а есть снизу к примеру, он по прежнему клацает правого
Я наверное что то не понял...

Автор: cirus 5.9.2017, 3:58

Числа расположены по строкам и столбцам.
[1 1] - первая строка, первое число
[2 1] - вторая строка, первое число
[2 2] - вторая строка, второе число
[3 1] - третья строка, первое число
Попробуй этот скрипт.

код
Код
// Поиск числа с помощью FindImage
init_arr %GetImage (1) 0 0 99, 58     // координаты для поиска, StartX StartY EndX EndY

set linedelay 0
init_arr %picture 0 1 2 3 4 5 6 7 8 9     // имена картинок (0.bmp, 1.bmp и т. д.)
init_arr %symbol 0 1 2 3 4 5 6 7 8 9    // символ соответствующий имени, т. е. картинка 0.bmp соответствует 0
set $path "C:\Image3"                     // папка с картинками
set $bmp "*.bmp*"                           // формат картинок
set #deltaY 8                               // расстояние между строками (можно указать высоту картинок)
set #deltaspace 12                          // допустимое расстояние между цифрами, иначе будет считаться что это не одно число
set #accuracy 90                            // точность поиска для Findimage
set #deviation 3                            // погрешность оттенка  для Findimage
set #wait 2                                 // пауза между поиском картинок, если указать меньше искать будет быстрее, но нагрузит процессор
set #timeproc 2000                          // время (в мсек) для поиска картинок, если 0 не выйдет из процедуры пока не найдётся хотя бы 1 картинка
set #repeatimage 2                          // допустимое смещение координат, если используется несколько видов одной картинки

dir (%path $path $bmp)
set delimiter '   '
while 1 = 1
    set size(%result)                        // уничтожить массив с предыдущими результатами
    set size(%coord)                         // уничтожить массив с предыдущими координатами
    call test %picture %symbol %GetImage %path #deltaY #deltaspace #accuracy #deviation #wait #timeproc #repeatimage    // процедура поиска
    // save_array %result C:\resultarr.txt     // массив с результатами поиска
    // save_array %coord C:\coordarr.txt     // массив с координатами чисел
    if  size(%result) > 0         // если размер массива больше 0
        // ТУТ НУЖНЫЕ ДЕЙСТВИЯ
        ///////////// для примера вывод в hint того что нашлось (можно убрать)
        set $str
        set %z [1] \n
        for #i 1 size(%result)
            set $str $str%result[#i]
            if  #i != size(%result)
                set $str $str%z [1]
            end_if
        end_for
        hint (14 clBlue 409, 265 ($str))
        /////////////
    else
        hint Картинки не найдены
    end_if
end_while

// процедура поиска и сортировки
proc test %picture %symbol %GetImage %path #deltaY #deltaspace #accuracy #deviation #wait #timeproc #repeatimage
    set #GetStartX %GetImage [1 1]
    set #GetStartY %GetImage [1 2]
    set #GetEndX %GetImage [1 3]
    set #GetEndY %GetImage [1 4]
    set #current_script current_script
    // загрузка картинок в память
    if  size(%path) > 0                  // если картинки найдены
        for #i 1 size(%path)
            for #j 1 size(%picture)
                if  %path [#i 3] = %picture [#j]
                    set #n #n + 1
                    set %image [#n] LoadImage(%path [#i 1])
                    set %number [#n] %symbol [#j]
                    break
                end_if
            end_for
        end_for
    else
        log Картинки в: $path   не найдены
        log Скрипт остановлен
        stop_script #current_script
    end_if
    // поиск картинок и их сортировка
    set size(%result1)
    set size(%coord_tmp)
    while size(%result1) = 0 and (#timeproc > timer or #timeproc = 0)
        set #z 0
        set %get GetImage(#GetStartX #GetStartY #GetEndX #GetEndY)      // сохранить часть экрана в память
        set #v %get [1 1]
        for #i 1 size(%number)
            set #a Findimage(0 0 %get [1 2] %get [1 3] (%image[#i 1]) %a #v #accuracy -1 #deviation)   // поиск
            if  #a < 0
                log Ошибка поиска картинки. Код ошибки: #a
                log Скрипт остановлен
                stop_script #current_script
            end_if
            if  #a > 0
                for #j 1 size(%a)
                    set #z #z + 1
                    init_arr %result1 (1 1 #z) %number[#i] %a[#j 1] %a[#j 2]   // запись результатов поиска в массив
                end_for
            end_if
            wait #wait
        end_for
        if  size(%result1) > 0
            gosub sortY        // сортировка по Y и X
        end_if
        set $b DeleteImage(%get[1 1])    // удалить изображение, полученное GetImage
    end_while
    goto end                 // выйти из процедуры

    :sortY
    ///// удаление повторных координат, если используется несколько видов одной картинки
        set #size 0
        set %tmp %result1
        set size(%result1)
        for #i 1 size(%tmp[1])
            set #break 0
            for #n 1 #size
                set #xrepeat %tmp[2 #i] - %result1[2 #n]
                set #yrepeat %tmp[3 #i] - %result1[3 #n]
                if  abs(#xrepeat) <= #repeatimage and abs(#yrepeat) <= #repeatimage
                    set #break 1
                    break
                end_if
            end_for
            if  #break = 0
                set #size #size + 1
                init_arr %result1 (1 1 #size) %tmp [1 #i]  %tmp [2 #i] %tmp [3 #i]
            end_if
        end_for
     ///////

        set #z 0
        set #z1 0
        set #z2 1
        set #z4 0
        sort_array %result1 -3
        while 1 = 1
            set #z 0
            set size(%tmp)
            for #i #z2 eval(size(%result1 [1]) - 1)
                set #j #i + 1
                set #x %result1 [3 #i] - %result1 [3 #j]
                if  abs(#x) < #deltaY
                    set #z #z + 1
                    init_arr %tmp (1 1 #z) %result1 [1 #i]  %result1 [2 #i] %result1 [3 #i]
                else
                    set #z #z + 1
                    init_arr %tmp (1 1 #z) %result1 [1 #i]  %result1 [2 #i] %result1 [3 #i]
                    break
                end_if
            end_for
            set #z2 #z2 + #z
            if  #z2 = size(%result1[])
                set #x %result1 [3 #i] - %result1 [3 #j]
                if  abs(#x) > #deltaY
                    set #jj #j
                    sort_array %tmp -2
                    set #z1 #z1 + 1
                    init_arr %result (#z1) %tmp [1]
                    gosub space
                    set size(%tmp)
                    set #z #z + 1
                    init_arr %tmp (1 1 #z) %result1 [1 #jj]  %result1 [2 #jj] %result1 [3 #jj]
                    set #z1 #z1 + 1
                    set %result.#current_script [#z1] %tmp [1]
                    gosub end
                end_if
                set #z #z + 1
                init_arr %tmp (1 1 #z) %result1 [1 #j]  %result1 [2 #j] %result1 [3 #j]
                sort_array %tmp -2
                set #z1 #z1 + 1
                init_arr %result (#z1) %tmp [1]
                set %coord_tmp [#z1] %tmp [2 1], %tmp [3 1]
                gosub space
                break
            else
                sort_array %tmp -2
                set #z1 #z1 + 1
                init_arr %result (#z1) %tmp [1]
                set %coord_tmp [#z1] %tmp [2 1], %tmp [3 1]
                gosub space
            end_if
        end_while
    return

    :space
        set #z3 0
        set size(%space)
        set #z4 #z4 + 1
        //посчитать где нужны пробелы
        for #i 1 eval(size(%tmp[]) - 1)
            set #j #i + 1
            set #space  %tmp [2 #i] - %tmp [2 #j]
            if  abs(#space) > #deltaspace
                set #z3 #z3 + 1
                set %space[#z3] #j
                set %coord_tmp [#z1 #i] %tmp [2 #j], %tmp [3 #j]
            end_if
        end_for
        // вставить пробелы
        for #i 1 size(%space)
            set $str %result [#z4]
            set $str insert(" " $str %space[#i])
            set #j #i + 1
            set %space[#j] %space[#j] + #i
            set %result [#z4] $str
        end_for
        // сохранение массива в основном скрипте
        for #i 1 size(%result)
            set size(%tmp1)
            init_arr %tmp1 (1) %result [#i]
            for #j 1 size(%tmp1[1])
                set %result.#current_script [#i #j] %tmp1 [1 #j]
                set %coord.#current_script [#i #j] %coord_tmp [#i #j]
            end_for
        end_for
    return

    :end
end_proc

Кроме массива с числами создаётся массив %coord (с теми же индексами что и %result) с координатами чисел.
Получится:
Код
%result [1 1] - уровень верхнего моба    %coord [1 1] - координаты чисел у верхнего моба
%result [2 1] - уровень левого моба        %coord [2 1]
%result [2 2] - уровень правого моба      %coord [2 2]
%result [3 1] - уровень нижнего моба     %coord [3 1]

Условие так:
Код
if %result [1 1] = 25
    left %coord [1 1]
end_if
if %result [2 1] = 25
    left %coord [2 1]
end_if
if %result [2 2] = 25
    left %coord [2 2]
end_if
if %result [3 1] = 25
    left %coord [3 1]
end_if
// Или циклом проверять все элементы массива.

Допустим, верхнего моба нет, тогда верхним будет левый. Хотя это уже не имеет значения, координаты будут правильные.
Скрипт не тестил. Могут быть косяки. Будет время подправлю.

Автор: ivanTu 5.9.2017, 8:48

Все работает, как часы, у меня еще один вопрос, а можно к примеру искать на мобе сразу два числа, к примеру моб 6-ти звездный и 25 лвл, как это это можно идентифицировать? Есть ли возможность одним вашим скриптом обойтись?

Автор: cirus 5.9.2017, 11:46

Проще сделать отдельную подпрограмму для поиска звёзд. Координаты числа известны, т. е. можно вычислить область поиска звёзд для конкретного моба.

код
Код
if %result [1 1] = 25             // если моб 25 уровня
    set $coord %coord [1 1]       // записываем в переменную координаты
    gosub find_star               // переход в подпрограмму поиска звёзд
end_if
if %result [2 1] = 25             // если моб 25 уровня
    set $coord %coord [2 1]       // записываем в переменную координаты
    gosub find_star
end_if

:find_star
    init_arr %temp (1) $coord     // разделяем координаты на 2 элемента массива, %temp [1 1] - X, %temp [1 2] - Y
    // считаем область поиска звёзд относительно числа
    set #startX %temp [1 1] - 50
    set #startY %temp [1 2] - 60
    set #endX %temp [1 1] + 30
    set #endY %temp [1 2] - 30
    set #a findimage (#startX #startY #endX #endY (фиолетовая_звезда) %star)
    if #a > 0
        log Количество звёзд: size(%star)
    end_if
    set #a findimage (#startX #startY #endX #endY (жёлтая_звезда) %star)
    if #a > 0
        log Количество звёзд: size(%star)
    end_if
return

Автор: DarkMaster 5.9.2017, 12:05

Цитата
Проще сделать отдельную подпрограмму для поиска звёзд.

А есть ли смысл? Может просто звездам или набору звезд присвоить свой символ да и все?

Автор: cirus 5.9.2017, 12:51

Если бы всегда было 4 моба, то и проблем не было. А так не удобно соотносить какое число к какому мобу относится.

Автор: ivanTu 5.9.2017, 13:35

Что то не пойму как сравнить звезды с уровнем (
Подскажите нубу...

Автор: ivanTu 5.9.2017, 13:48

Мне картинки звезд делать уже каждую по отдельности или целиком ***** всю группу, что то запутался

Автор: cirus 5.9.2017, 14:11

Смотря что требуется. Если нужно знать точное количество звёзд, то делать картинку 1 звезды. Если интересует только когда 6 звёзд, то можно и целиком искать. Кстати, звёзды тоже отличаются, так что либо точность снижать и добавлять погрешность в цвете, либо сделать несколько картинок и сравнить скриптом.

Автор: ivanTu 5.9.2017, 14:19

Нужно искать группу звезд:

** - звезды (максимальный лвл с этими звездами ) - 20
*** - звезды (максимальный лвл с этими звездами ) - 25
**** - звезды (максимальный лвл с этими звездами ) - 30
***** - звезды (максимальный лвл с этими звездами ) - 35
****** - звезды (максимальный лвл с этими звездами ) - 40

Суть моей задумки, проверять моб достиг максимального уровня или нет, просто у мобов разный максимальный уровень в зависимости от количества звезд.
Уважаемый cirus, Вы мне и так сильно помогли, я очень благодарен Вам.
Если есть возможность подсказать кодом, буду Вам очень благодарен!

Автор: DarkMaster 5.9.2017, 14:28

cirus, в код скрипта какие-то изменения будешь вносить в ближайшее время? Если собираешься, просьба это сделать.

Автор: cirus 5.9.2017, 15:17

Цитата
Если есть возможность подсказать кодом

Как будет время, ближе к выходным.
Цитата
в код скрипта какие-то изменения будешь вносить в ближайшее время? Если собираешься, просьба это сделать.

В одном куске надо подправить возвращение координат. К выходным сделаю.
Вообще на луа надо написать, но в нём не работали getimage и loadimage.

Автор: ivanTu 5.9.2017, 15:20

Цитата(cirus @ 5.9.2017, 15:17) *

Как будет время, ближе к выходным.

В одном куске надо подправить возвращение координат. К выходным сделаю.
Вообще на луа надо написать, но в нём не работали getimage и loadimage.


Поклон тебе rolleyes.gif

Автор: DarkMaster 5.9.2017, 15:25

Цитата
Вообще на луа надо написать, но в нём не работали getimage и loadimage.

Ну как бы в этом и дело) Меня прижало, собрался переписывать, а судя по теме что-то править вроде собирался. Ну и чтобы мне потом не искать что правилось, решил сначала спросить. Если правка мелкая, сделай, если не сложно, в ближайшее время, т.к. ждать до выходных я не буду точно и перепишу "как есть". По поводу переписки есть пара идей, как сделать чуть более удобно по части вызова и доп параметров необязательных.

Автор: cirus 5.9.2017, 15:42

Правка мелкая пару строчек, по сути не повлияет на работу. Но, проще самому скрипт написать, чем чей-то переписывать. Если надо могу написать принцип работы, но это ночью. Ушёл на работу.

Автор: DarkMaster 5.9.2017, 15:52

Смысл писать то, что уже написано и потом баги ловить? Принцип я понимаю. Более того могу сам пару таких принципов написать) Тут вопрос отладки и ошибок по невнимательности.

еще бы кто-то с goto не позорился)))

Автор: cirus 6.9.2017, 4:01

Цитата
еще бы кто-то с goto не позорился)))

smile.gif Сначала был костыль для отладки, потом так и остался.
Исправил несколько косяков с возвращением координат чисел.
код
Код
// Поиск числа с помощью FindImage
init_arr %GetImage (1) 0 0 245, 98      // координаты для поиска, StartX StartY EndX EndY

set linedelay 0
init_arr %picture 0 1 2 3 4 5 6 7 8 9     // имена картинок (0.bmp, 1.bmp и т. д.)
init_arr %symbol 0 1 2 3 4 5 6 7 8 9    // символ соответствующий имени, т. е. картинка 0.bmp соответствует 0
set $path "C:\Image3"                     // папка с картинками
set $bmp "*.bmp*"                           // формат картинок
set #deltaY 8                               // расстояние между строками (можно указать высоту картинок)
set #deltaspace 12                          // допустимое расстояние между цифрами, иначе будет считаться что это не одно число
set #accuracy 90                            // точность поиска для Findimage
set #deviation 3                            // погрешность оттенка  для Findimage
set #wait 2                                 // пауза между поиском картинок, если указать меньше искать будет быстрее, но нагрузит процессор
set #timeproc 2000                          // время (в мсек) для поиска картинок, если 0 не выйдет из процедуры пока не найдётся хотя бы 1 картинка
set #repeatimage 2                          // допустимое смещение координат, если используется несколько видов одной картинки

dir (%path $path $bmp)
set delimiter '   '
while 1 = 1
    set size(%result)                        // уничтожить массив с предыдущими результатами
    set size(%coord)                         // уничтожить массив с предыдущими координатами
    call test %picture %symbol %GetImage %path #deltaY #deltaspace #accuracy #deviation #wait #timeproc #repeatimage    // процедура поиска
//     save_array %result C:\Users\abc\Desktop\result111.txt     // массив с результатами поиска
//     save_array %coord C:\Users\abc\Desktop\coord111.txt     // массив с координатами чисел
    if  size(%result) > 0         // если размер массива больше 0
        // ТУТ НУЖНЫЕ ДЕЙСТВИЯ
        ///////////// для примера вывод в hint того что нашлось (можно убрать)
        set $str
        set %z [1] \n
        for #i 1 size(%result)
            set $str $str%result[#i]
            if  #i != size(%result)
                set $str $str%z [1]
            end_if
        end_for
        hint (14 clBlue 409, 265 ($str))
        /////////////
    else
        hint Картинки не найдены
    end_if
end_while

// процедура поиска и сортировки
proc test %picture %symbol %GetImage %path #deltaY #deltaspace #accuracy #deviation #wait #timeproc #repeatimage
    set #GetStartX %GetImage [1 1]
    set #GetStartY %GetImage [1 2]
    set #GetEndX %GetImage [1 3]
    set #GetEndY %GetImage [1 4]
    set #current_script current_script
    // загрузка картинок в память
    if  size(%path) > 0                  // если картинки найдены
        for #i 1 size(%path)
            for #j 1 size(%picture)
                if  %path [#i 3] = %picture [#j]
                    set #n #n + 1
                    set %image [#n] LoadImage(%path [#i 1])
                    set %number [#n] %symbol [#j]
                    break
                end_if
            end_for
        end_for
    else
        log Картинки в: $path   не найдены
        log Скрипт остановлен
        stop_script #current_script
    end_if
    // поиск картинок и их сортировка
    set size(%result1)
    set size(%coord_tmp)
    while size(%result1) = 0 and (#timeproc > timer or #timeproc = 0)
        set #z 0
        set %get GetImage(#GetStartX #GetStartY #GetEndX #GetEndY)      // сохранить часть экрана в память
        set #v %get [1 1]
        for #i 1 size(%number)
            set #a Findimage(0 0 %get [1 2] %get [1 3] (%image[#i 1]) %a #v #accuracy -1 #deviation)   // поиск
            if  #a < 0
                log Ошибка поиска картинки. Код ошибки: #a
                log Скрипт остановлен
                stop_script #current_script
            end_if
            if  #a > 0
                for #j 1 size(%a)
                    set #z #z + 1
                    init_arr %result1 (1 1 #z) %number[#i] %a[#j 1] %a[#j 2]   // запись результатов поиска в массив
                end_for
            end_if
            wait #wait
        end_for
        if  size(%result1) > 0
            gosub sortY        // сортировка по Y и X
        end_if
        set $b DeleteImage(%get[1 1])    // удалить изображение, полученное GetImage
    end_while
    goto end                 // выйти из процедуры

    :sortY
    ///// удаление повторных координат, если используется несколько видов одной картинки
        set #size 0
        set %tmp %result1
        set size(%result1)
        for #i 1 size(%tmp[1])
            set #break 0
            for #n 1 #size
                set #xrepeat %tmp[2 #i] - %result1[2 #n]
                set #yrepeat %tmp[3 #i] - %result1[3 #n]
                if  abs(#xrepeat) <= #repeatimage and abs(#yrepeat) <= #repeatimage
                    set #break 1
                    break
                end_if
            end_for
            if  #break = 0
                set #size #size + 1
                init_arr %result1 (1 1 #size) %tmp [1 #i]  %tmp [2 #i] %tmp [3 #i]
            end_if
        end_for
     ///////

        set #z 0
        set #z1 0
        set #z2 1
        set #z4 0
        sort_array %result1 -3
        while 1 = 1
            set #z 0
            set size(%tmp)
            for #i #z2 eval(size(%result1 [1]) - 1)
                set #j #i + 1
                set #x %result1 [3 #i] - %result1 [3 #j]
                if  abs(#x) < #deltaY
                    set #z #z + 1
                    init_arr %tmp (1 1 #z) %result1 [1 #i]  %result1 [2 #i] %result1 [3 #i]
                else
                    set #z #z + 1
                    init_arr %tmp (1 1 #z) %result1 [1 #i]  %result1 [2 #i] %result1 [3 #i]
                    break
                end_if
            end_for
            set #z2 #z2 + #z
            if  #z2 = size(%result1[])
                set #x %result1 [3 #i] - %result1 [3 #j]
                if  abs(#x) > #deltaY
                    set #jj #j
                    sort_array %tmp -2
                    set #z1 #z1 + 1
                    init_arr %result (#z1) %tmp [1]
                    set %coord_tmp [#z1] %tmp [2 1], %tmp [3 1]
                    set %coord.#current_script [#z1] %tmp [2 #z], %tmp [3 #z]
                    gosub space
                    set size(%tmp)
                    set #z #z + 1
                    init_arr %tmp (1 1 #z) %result1 [1 #jj]  %result1 [2 #jj] %result1 [3 #jj]
                    set #z1 #z1 + 1
                    set %result.#current_script [#z1] %tmp [1]
                    set %coord.#current_script [#z1] %tmp [2 #z], %tmp [3 #z]
                    gosub end
                end_if
                set #z #z + 1
                init_arr %tmp (1 1 #z) %result1 [1 #j]  %result1 [2 #j] %result1 [3 #j]
                sort_array %tmp -2
                set #z1 #z1 + 1
                init_arr %result (#z1) %tmp [1]
                set %coord_tmp [#z1] %tmp [2 1], %tmp [3 1]
                gosub space
                break
            else
                sort_array %tmp -2
                set #z1 #z1 + 1
                init_arr %result (#z1) %tmp [1]
                set %coord_tmp [#z1] %tmp [2 1], %tmp [3 1]
                gosub space
            end_if
        end_while
    return

    :space
        set #z3 0
        set size(%space)
        set #z4 #z4 + 1
        //посчитать где нужны пробелы
        for #i 1 eval(size(%tmp[]) - 1)
            set #j #i + 1
            set #space  %tmp [2 #i] - %tmp [2 #j]
            if  abs(#space) > #deltaspace
                set #z3 #z3 + 1
                set %space[#z3] #j
                set #size_coord 1
                while %coord_tmp[#z1 #size_coord] != ""
                    set #size_coord #size_coord + 1
                end_while
                set %coord_tmp [#z1 #size_coord] %tmp [2 #j], %tmp [3 #j]
            end_if
        end_for
        // вставить пробелы
        for #i 1 size(%space)
            set $str %result [#z4]
            set $str insert(" " $str %space[#i])
            set #j #i + 1
            set %space[#j] %space[#j] + #i
            set %result [#z4] $str
        end_for
        // сохранение массива в основном скрипте
        for #i 1 size(%result)
            set size(%tmp1)
            init_arr %tmp1 (1) %result [#i]
            for #j 1 size(%tmp1[1])
                set %result.#current_script [#i #j] %tmp1 [1 #j]
                set %coord.#current_script [#i #j] %coord_tmp [#i #j]
            end_for
        end_for
    return

    :end
end_proc

Тестил только в блокноте. Вроде работает.

Автор: cirus 7.9.2017, 3:13

ivanTu, пробуй. Нацарапал чего-то. На скринах работает.

код
Код
// Поиск числа с помощью FindImage
init_arr %GetImage (1) 0 0 268, 184      // координаты для поиска, StartX StartY EndX EndY
log clear
log mode compact

set $path_star_purple C:\Users\abc\Desktop\star_purple.bmp    // путь к картинке фиолетовой звезды
set $path_star_yellow C:\Users\abc\Desktop\star_yellow.bmp    // путь к картинке жёлтой звезды

set linedelay 0
init_arr %picture 0 1 2 3 4 5 8     // имена картинок (0.bmp, 1.bmp и т. д.)
init_arr %symbol 0 1 2 3 4 5 8    // символ соответствующий имени, т. е. картинка 0.bmp соответствует 0
set $path "C:\Users\abc\Desktop\пилот тест\картинки"                     // папка с картинками
set $bmp "*.bmp*"                           // формат картинок
set #deltaY 11                               // расстояние между строками (можно указать высоту картинок)
set #deltaspace 12                          // допустимое расстояние между цифрами, иначе будет считаться что это не одно число
set #accuracy 100                            // точность поиска для Findimage
set #deviation 7                            // погрешность оттенка  для Findimage
set #wait 2                                 // пауза между поиском картинок, если указать меньше искать будет быстрее, но нагрузит процессор
set #timeproc 2000                          // время (в мсек) для поиска картинок, если 0 не выйдет из процедуры пока не найдётся хотя бы 1 картинка
set #repeatimage 2                          // допустимое смещение координат, если используется несколько видов одной картинки

set %star [1] LoadImage ($path_star_purple)     // загрузка картинок звёзд в память
set %star [2] LoadImage ($path_star_yellow)
dir (%path $path $bmp)
set delimiter '   '
while 1 = 1
    set size(%result)                        // уничтожить массив с предыдущими результатами
    set size(%coord)                         // уничтожить массив с предыдущими координатами
    call test %picture %symbol %GetImage %path #deltaY #deltaspace #accuracy #deviation #wait #timeproc #repeatimage    // процедура поиска
    //     save_array %result C:\Users\abc\Desktop\result111.txt     // массив с результатами поиска
    //     save_array %coord C:\Users\abc\Desktop\coord111.txt     // массив с координатами чисел
    if  size(%result) > 0         // если размер массива больше 0
        // ТУТ НУЖНЫЕ ДЕЙСТВИЯ
        ///////////// для примера вывод в hint того что нашлось (можно убрать)
        set $str
        set %z [1] \n
        for #i 1 size(%result)
            set $str $str%result[#i]
            if  #i != size(%result)
                set $str $str%z [1]
            end_if
        end_for
        hint (14 clBlue 409, 265 ($str))
        /////////////

        // поиск звёзд и проверка достиг ли моб максимального уровня
        for #i 1 size(%result)
            for #j 1 size(%result[])
                if  %result [#i #j] != ""
                    set $coord %coord [#i #j]
                    gosub find_star     // подпрограмма поиска звёзд
                end_if
            end_for
        end_for

        end_script   // убрать
        
    else
        hint Картинки не найдены
    end_if

end_while

:find_star
    init_arr %tmp (1) $coord
    set #mindistX 5
    set #mindistY 5
    set #startX %tmp[1 1] - 50
    set #startY %tmp[1 2] - 60
    set #endX %tmp[1 1] + 30
    set #endY %tmp[1 2] - 30
    set #a Findimage(#startX #startY #endX #endY (%star[1 1]) %arr 2 90 -1 10) // фиолетовые звёзды
    if  #a > 0
        gosub del_double  // удаление лишних картинок
        gosub level       // проверка уровня моба в зависимости от количества звёзд
    end_if
    set #a Findimage(#startX #startY #endX #endY (%star [2 1]) %arr 2 90 -1 12) // жёлтые звёзды
    if  #a > 0
        gosub del_double  // удаление лишних картинок
        gosub level       // проверка уровня моба в зависимости от количества звёзд
    end_if
return

:del_double
    set #ii -1
    while #ii < size(%arr)
        set #ii #ii + 1
        set #double 1
        while #double = 1
            set #double 0
            set #iii #ii + 1
            set #jj #iii
            while #jj < size(%arr)
                set #jj #jj + 1
                set #distX abs(eval(%arr [#iii 1] - %arr [#jj 1]))
                set #distY abs(eval(%arr [#iii 2] - %arr [#jj 2]))
                if  #distX < #mindistX and #distY < #mindistY
                    delete_array %arr -#jj
                    set #jj #jj - 1
                    set #double 1
                end_if
            end_while
        end_while
    end_while
return

:level
    switch size(%arr)
        case 2: log Количество звёзд 2
            if %result [#i #j] = 20
                log Моб достиг максимального уровня
                log Уровень моба: %result [#i #j]
                log
                move %coord [#i #j]
                wait 500
            else
                log Моб не достиг максимального уровня
                log Уровень моба: %result [#i #j]
                log
            end_if
            break
        case 3: log Количество звёзд 3
            if %result [#i #j] = 25
                log Моб достиг максимального уровня
                log Уровень моба: %result [#i #j]
                log
                move %coord [#i #j]
                wait 500
            else
                log Моб не достиг максимального уровня
                log Уровень моба: %result [#i #j]
                log
            end_if
            break
        case 4: log Количество звёзд 4
            if %result [#i #j] = 30
                log Моб достиг максимального уровня
                log Уровень моба: %result [#i #j]
                log
                move %coord [#i #j]
                wait 500
            else
                log Моб не достиг максимального уровня
                log Уровень моба: %result [#i #j]
                log
            end_if
            break
        case 5: log Количество звёзд 5
            if %result [#i #j] = 35
                log Моб достиг максимального уровня
                log Уровень моба: %result [#i #j]
                log
                move %coord [#i #j]
                wait 500
            else
                log Моб не достиг максимального уровня
                log Уровень моба: %result [#i #j]
                log
            end_if
            break
        case 6: log Количество звёзд 6
            if %result [#i #j] = 40
                log Моб достиг максимального уровня
                log Уровень моба: %result [#i #j]
                log
                move %coord [#i #j]
                wait 500
            else
                log Моб не достиг максимального уровня
                log Уровень моба: %result [#i #j]
                log
            end_if
    end_switch
return

// процедура поиска и сортировки
proc test %picture %symbol %GetImage %path #deltaY #deltaspace #accuracy #deviation #wait #timeproc #repeatimage
    set #GetStartX %GetImage [1 1]
    set #GetStartY %GetImage [1 2]
    set #GetEndX %GetImage [1 3]
    set #GetEndY %GetImage [1 4]
    set #current_script current_script
    // загрузка картинок в память
    if  size(%path) > 0                  // если картинки найдены
        for #i 1 size(%path)
            for #j 1 size(%picture)
                if  %path [#i 3] = %picture [#j]
                    set #n #n + 1
                    set %image [#n] LoadImage(%path [#i 1])
                    set %number [#n] %symbol [#j]
                    break
                end_if
            end_for
        end_for
    else
        log Картинки в: $path   не найдены
        log Скрипт остановлен
        stop_script #current_script
    end_if
    // поиск картинок и их сортировка
    set size(%result1)
    set size(%coord_tmp)
    while size(%result1) = 0 and (#timeproc > timer or #timeproc = 0)
        set #z 0
        set %get GetImage(#GetStartX #GetStartY #GetEndX #GetEndY)      // сохранить часть экрана в память
        set #v %get [1 1]

        for #i 1 size(%number)
            set #a Findimage(0 0 %get [1 2] %get [1 3] (%image[#i 1]) %a #v #accuracy -1 #deviation)   // поиск
            if  #a < 0
                log Ошибка поиска картинки. Код ошибки: #a
                log Скрипт остановлен
                stop_script #current_script
            end_if
            if  #a > 0
                for #j 1 size(%a)
                    set #z #z + 1
                    init_arr %result1 (1 1 #z) %number[#i] %a[#j 1] %a[#j 2]   // запись результатов поиска в массив
                end_for
            end_if
            wait #wait
        end_for
        if  size(%result1) > 0
            gosub sortY        // сортировка по Y и X
        end_if
        set $b DeleteImage(%get[1 1])    // удалить изображение, полученное GetImage
    end_while
    goto end                 // выйти из процедуры

    :sortY
        ///// удаление повторных координат, если используется несколько видов одной картинки
        set #size 0
        set %tmp %result1
        set size(%result1)
        for #i 1 size(%tmp[1])
            set #break 0
            for #n 1 #size
                set #xrepeat %tmp[2 #i] - %result1[2 #n]
                set #yrepeat %tmp[3 #i] - %result1[3 #n]
                if  abs(#xrepeat) <= #repeatimage and abs(#yrepeat) <= #repeatimage
                    set #break 1
                    break
                end_if
            end_for
            if  #break = 0
                set #size #size + 1
                init_arr %result1 (1 1 #size) %tmp [1 #i]  %tmp [2 #i] %tmp [3 #i]
            end_if
        end_for
        ///////

        set #z 0
        set #z1 0
        set #z2 1
        set #z4 0
        sort_array %result1 -3
        while 1 = 1
            set #z 0
            set size(%tmp)
            for #i #z2 eval(size(%result1 [1]) - 1)
                set #j #i + 1
                set #x %result1 [3 #i] - %result1 [3 #j]
                if  abs(#x) < #deltaY
                    set #z #z + 1
                    init_arr %tmp (1 1 #z) %result1 [1 #i]  %result1 [2 #i] %result1 [3 #i]
                else
                    set #z #z + 1
                    init_arr %tmp (1 1 #z) %result1 [1 #i]  %result1 [2 #i] %result1 [3 #i]
                    break
                end_if
            end_for
            set #z2 #z2 + #z
            if  #z2 = size(%result1[])
                set #x %result1 [3 #i] - %result1 [3 #j]
                if  abs(#x) > #deltaY
                    set #jj #j
                    sort_array %tmp -2
                    set #z1 #z1 + 1
                    init_arr %result (#z1) %tmp [1]
                    set %coord_tmp [#z1] %tmp [2 1], %tmp [3 1]
                    set %coord.#current_script [#z1] %tmp [2 #z], %tmp [3 #z]
                    gosub space
                    set size(%tmp)
                    set #z #z + 1
                    init_arr %tmp (1 1 #z) %result1 [1 #jj]  %result1 [2 #jj] %result1 [3 #jj]
                    set #z1 #z1 + 1
                    set %result.#current_script [#z1] %tmp [1]
                    set %coord.#current_script [#z1] %tmp [2 #z], %tmp [3 #z]
                    gosub end
                end_if
                set #z #z + 1
                init_arr %tmp (1 1 #z) %result1 [1 #j]  %result1 [2 #j] %result1 [3 #j]
                sort_array %tmp -2
                set #z1 #z1 + 1
                init_arr %result (#z1) %tmp [1]
                set %coord_tmp [#z1] %tmp [2 1], %tmp [3 1]
                gosub space
                break
            else
                sort_array %tmp -2
                set #z1 #z1 + 1
                init_arr %result (#z1) %tmp [1]
                set %coord_tmp [#z1] %tmp [2 1], %tmp [3 1]
                gosub space
            end_if
        end_while
    return

    :space
        set #z3 0
        set size(%space)
        set #z4 #z4 + 1
        //посчитать где нужны пробелы
        for #i 1 eval(size(%tmp[]) - 1)
            set #j #i + 1
            set #space  %tmp [2 #i] - %tmp [2 #j]
            if  abs(#space) > #deltaspace
                set #z3 #z3 + 1
                set %space[#z3] #j
                set #size_coord 1
                while %coord_tmp[#z1 #size_coord] != ""
                    set #size_coord #size_coord + 1
                end_while
                set %coord_tmp [#z1 #size_coord] %tmp [2 #j], %tmp [3 #j]
            end_if
        end_for
        // вставить пробелы
        for #i 1 size(%space)
            set $str %result [#z4]
            set $str insert(" " $str %space[#i])
            set #j #i + 1
            set %space[#j] %space[#j] + #i
            set %result [#z4] $str
        end_for
        // сохранение массива в основном скрипте
        for #i 1 size(%result)
            set size(%tmp1)
            init_arr %tmp1 (1) %result [#i]
            for #j 1 size(%tmp1[1])
                set %result.#current_script [#i #j] %tmp1 [1 #j]
                set %coord.#current_script [#i #j] %coord_tmp [#i #j]
            end_for
        end_for
    return

    :end
end_proc

Прикрепленный файл  star_purple.bmp ( 236 байт ) Кол-во скачиваний: 360

Прикрепленный файл  star_yellow.bmp ( 248 байт ) Кол-во скачиваний: 386

Автор: ivanTu 7.9.2017, 9:28

cirus Огромное Вам спасибо, благодаря Вам, понимаю что сделать можно все, вы вдохновляете нубов как я на изучение программирования в целом! )))

Автор: DarkMaster 8.9.2017, 4:18

кхе... думал часа за 2 перепишу) вобщем формат хранения данных в пилотовском синтаксисе и lua сильно различаются и прозрачно делать не везде получается, а где-то очень кощунственно выглядит и приходится подправлять. smile.gif Делаю под красивые луашные вызовы. Это я все к чему, если собирался переписывать - погоди чуток, чтобы вместе одно и то же не делали.

Автор: cirus 8.9.2017, 11:59

В ближайшее время не соберусь. Вдохновение ещё не пришло.

Автор: DarkMaster 21.9.2017, 17:10

Бетка распознавания текста. Буду благодарен за тесты и багрепорты, т.к. времени катастрофически не хватает.

Распознавание текста
Код
do
    -- Символы для поиска.
    -- Возможно указать в двух вариантах синтаксиса: упрощенном и полном.
    -- Упрощенный синтаксис:
    -- В упрощенном варианте синтаксиса допускается не указывать
    -- соответствие имен файлов и строке/символу,
    -- который они обозначают: считается, что они идентичны.
    -- Пример упрощенного синтаксиса:
    -- local symbols = {"0", "1", "2", "3", "a", "b", "c", "test"}
    -- Полный синтаксис:
    -- Полный синтаксис бывает необходим при использовании
    -- нескольких изображений соответсвующих одной и той же строке/символу.
    -- Допускаются переносы строк:
    -- local symbols = {
    --       "0" = {"zero1", "zero2"},
    --       "1" = {"1a", "1b"},
    --       "2" = {"two", "second"}
    --      }
    -- Оба варианта синтаксиса можно сочетать:
    -- local symbols = {"0", "1", "2" = {"two", "second"}, "3"}


    local default = {}
    -- набор стандартных символов
    default.symbols      = {["0"]={"0"}, ["1"]={"1"}, ["2"]={"2"}, ["3"]={"3"}, ["4"]={"4"}, ["5"]={"5"}, ["6"]={"6"}, ["7"]={"7"}, ["8"]={"8"}, ["9"]={"9"}}
    default.crds         = {0, 0, 1920, 1080} -- Координаты поиска
    default.path         = "c:\\image"        -- Папка с картинками
    default.ext          = ".bmp"             -- Расширение картинок
    default.deltaY       = 8                  -- Расстояние между строками (можно указать высоту картинок)
    default.deltaSpace   = 12                 -- Допустимое расстояние между цифрами, иначе будет считаться что это не одно число
    default.accuracy     = 95                 -- Точность поиска для Findimage
    default.deviation    = 3                  -- Погрешность оттенка  для Findimage
    default.wait         = 2                  -- Пауза между поиском картинок, если указать меньше искать будет быстрее, но нагрузит процессор
    default.timeProc     = 2000               -- Время в секундах (может быть не целым) для поиска картинок, если -1 не выйдет из процедуры пока не найдётся хотя бы 1 картинка
    default.repeatImage  = 2                  -- Допустимое смещение координат, если используется несколько видов одной картинки
    default.window       = "workwindow"       -- Метод|хендл_окна в котором происходит поиск (если указан источник изображения(source), то параметр будет проигнорирован)
    default.abs          = 0                  -- Использовать abs координаты.
    default.source       = nil                -- Изображение в котором производится поиск. nil приведет к захвату изображения с экрана.
    default.bufferAddNew = 1                  -- Добавлять изображения в буфер
    default.bufferIgnore = 0                  -- Игнорировать изображения находящиеся в буфере
    default.bufferUpdate = 1                  -- Обновить изображения содержащиеся в буфере.
    default.loadPath     = nil                -- Путь по которому будут загружены все изображения с указанными расширением. Имя файла будет соответсвовать имени символа.


    -- Буфер
    -- Буфер
    -- Буфер

    local buffer = {} -- Массив с загруженными картинками.
    imageToStringBuffer = {} -- набор функций по управлению буфером.
    -- Полностью очищаем массив.
    function imageToStringBuffer.flush()
        for k,_ in pairs(buffer) do buffer[v] = nil end
    end
    -- Удаляем элемент из буфера
    function imageToStringBuffer.flush(element)
        buffer[element] = nil
    end
    -- Добавляем изображение в буфер
    function imageToStringBuffer.flush(element, val)
        buffer[element] = val
    end


    -- Поиск
    -- Поиск
    -- Поиск

    function imageToString(options)

        -- Проверяем переданные параметры. Если они отсутствуют - подставляем параметры по умолчанию.
        if  options              == nil then options              = {}                    end
        if  options.symbols      == nil then options.symbols      = default.symbols       end
        if  options.crds         == nil then options.crds         = default.crds          end
        if  options.path         == nil then options.path         = default.path          end
        if  options.ext          == nil then options.ext          = default.ext           end
        if  options.deltaY       == nil then options.deltaY       = default.deltaY        end
        if  options.deltaSpace   == nil then options.deltaSpace   = default.deltaSpace    end
        if  options.accuracy     == nil then options.accuracy     = default.accuracy      end
        if  options.deviation    == nil then options.deviation    = default.deviation     end
        if  options.wait         == nil then options.wait         = default.wait          end
        if  options.timeProc     == nil then options.timeProc     = default.timeProc      end
        if  options.repeatImage  == nil then options.repeatImage  = default.repeatImage   end
        if  options.window       == nil then options.window       = default.window        end
        if  options.abs          == nil then options.abs          = default.abs           end
        if  options.source       == nil then options.source       = default.source        end
        if  options.bufferAddNew == nil then options.bufferAddNew = default.bufferAddNew  end
        if  options.bufferIgnore == nil then options.bufferIgnore = default.bufferIgnore  end
        if  options.bufferUpdate == nil then options.bufferUpdate = default.bufferUpdate  end
        if  options.loadPath     == nil then options.loadPath     = default.loadPath      end


        --Добавляем при необходимости обратный слэш в путь.
        if  string.sub(options.path, -1) ~= "\\" then options.path = options.path .. "\\" end

        -- Преобразуем урощенный синтаксис в полноценный.
        for symbolName, imageName in pairs(options.symbols) do
            if type(options.symbols[symbolName]) ~= "table" then
                options.symbols[imageName] = {imageName}
            end
        end

        -- Преобразуем ссылку на папку с изображениями
        -- в полноценный синтаксис.
        --local fileList = {}
        --log (options.path, options.ext)
        --fileList = dir(options.path, options.ext)
        --table.show(fileList, "fileList")

        -- Удаляем параметры переданные, как упрощенные (теперь уже содежатся в полном виде)
        for i=1, #options.symbols do
            table.remove(options.symbols, i)
        end

        -- Приводим options.abs к виду пригодному для финдимиджа.
        if     options.abs == 1 then options.abs = "abs"
        elseif options.abs == 0 then options.abs = ""
        end
        --table.show(options)


        -- Загрузка картинок
        local images={}     --Загружает в память изображения {имя символа, {адреса в памяти}}
        local loadError = 0
        for symbolName, fileList in pairs(options.symbols) do
            images[symbolName] = {}
            for i=1, #fileList, 1 do
                -- Загружен ли файл в буфер, если нет, то подгружаем.
                local filePath = options.path..fileList[i]..options.ext
                if  options.bufferIgnore == 0 and options.bufferUpdate == 0 and buffer[filePath] == nil then
                    images[symbolName][i] = buffer[filePath]
                else
                    -- В буфере изображения нет, загружаем с диска.
                    --log(filePath.."В буфере изображения нет, загружаем с диска.")
                    images[symbolName][i] = loadimage(filePath)
                    -- Обновляем загруженное в буфер изображение
                    if  buffer[filePath] ~= nil then
                        DeleteImage(buffer[filePath])
                        buffer[filePath] =  images[symbolName][i]
                    elseif options.bufferAddNew == 1 and options.bufferIgnore == 0 then
                        -- Добавляем в буфер новое изображение.
                        buffer[filePath] = images[symbolName][i]
                    end
                end
                -- Поиск ошибок загрузки.
                if images[symbolName][i] < 0  then
                    loadError = loadError + 1
                    log("Image loading fail. Error file: "..filePath..'.')
                end
            end
        end
        -- При загрузке изображений произошли ошибки. Останавливаем скрипт.
        if  loadError > 0 then
            log("Error loading count: "..loadError..'.')
            stop_script()
        end
        --table.show(images)


        local timeout = os.clock() + options.timeProc
        crdsRaw={} -- Массив со всеми найденными изображениями, возможны дубли, не сортированный.
        repeat  -- Повторяем пока что-то не найдем или не выйдет время на поиск (options.timeProc).
            -- Получаем изображение с экрана, если источник не указан.
            local screenshot = nil
            if  options.source == nil then
                screenshot = getimage(options.crds[1],options.crds[2],options.crds[3],options.crds[4], options.window)
            else
                screenshot = options.source
            end
            --log(screenshot)
            for symbolName, imageAddress in pairs(images) do
                tmp = {}
                findResult = findimage(
                    options.crds[1] .. " " .. options.crds[2] .. " " ..
                    options.crds[3] .. " " .. options.crds[4] .. " " ..
                    "(" .. options.path .. symbolName .. options.ext .. ") " ..
                    "%tmp " .. screenshot .. " " .. options.accuracy .. " -1 " .. options.deviation .. " " .. options.abs)
                --log("symoblName: ".. symbolName .. " findResult: " .. findResult)
                -- проверяем на возрват нуля или ошбики, со стрингом нормально не сравнить.
                if  findResult ~= "0" and not string.find(findResult, "-") then
                    -- Добавляем найденные значения в общий результат поисков.
                    --table.show(tmp,"tmp")
                    for i = 1, #tmp, 1 do
                        -- Напрямую вернуть таблицу в функцию нельзя из-за синтаксиса.
                        -- FIX. Нужен фикс функции findimage пилота (возвращает координаты стрингом)
                        -- после фикса просто удалить "tonumber(parm)" оставив parm.
                        table.insert(crdsRaw,{x=tonumber(tmp[i][1]),y=tonumber(tmp[i][2]),symbolName=symbolName})
                    end
                end
            end

            -- Удаляем изображение, если делали скриншот.
            if  options.source ~= nil then
                deleteimage(screenshot)
            end

            --table.show(images, "images")
            --log (#crdsRaw, timeout, os.clock(), options.timeProc)
            --log ("until")
            local clock = os.clock()
        until not ((#crdsRaw == 0) and (timeout > clock or options.timeProc == -1))
        --table.show(crdsRaw, "crdsRaw")

        --  Изображения не были найдены, выходим из поиска.
        if  #crdsRaw < 1 then
            return nil
        end
        -- Удаляем дубли.
        crdsClear={} -- Массив без дублей.
        for i=1, #crdsRaw, 1 do
            local catch = 0 -- Флаг найденного дубля.
            for n=i+1, #crdsRaw, 1 do
                --log(
                --  crdsRaw[i].symbolName.." == "..crdsRaw[n].symbolName.." and "..
                --  math.abs(crdsRaw[i].x - crdsRaw[n].x).." <= "..options.repeatImage.." and "..
                --  math.abs(crdsRaw[i].y - crdsRaw[n].y).." <= "..options.repeatImage
                --)
                if  crdsRaw[i].symbolName == crdsRaw[n].symbolName and
                  math.abs(crdsRaw[i].x - crdsRaw[n].x) <= options.repeatImage and
                  math.abs(crdsRaw[i].y - crdsRaw[n].y) <= options.repeatImage then
                    catch = 1
                    break
                end
            end
            --log(catch)
            if  catch == 0 then -- не дубль, копируем значение в чистый массив.
                table.insert(crdsClear,crdsRaw[i])
            end
        end

        -- Сортируем элементы.
        -- Сортировка происходит, как по X координате,
        -- так и по Y учитывая возможность нескольких строк.
        -- Межстрочный интервал задается с помощью options.deltaY.
        -- Для уплотнения поиска options.deltaY может быть отрицательным.
        -- Отрицательный options.deltaY в первую очередь необходим,
        -- если изображения символов содержат сверху и снизу от символа фон.
        -- crdsClear был предварительно очищен от дублей, теперь сортируется.

        --table.show(crdsClear,"crdsClear")
        --table.toInit(crdsClear)
        table.sort(crdsClear,
            function(a,b)
                if  math.abs(a.y - b.y) <= options.deltaY then
                    if  a.x < b.x then
                        return true
                    else
                        return false
                    end
                else
                    if a.y < b.y then
                        return true
                    else
                        return false
                    end
                end
            end
        )
        --table.show(crdsClear,"crdsClear")

        -- Собираем строку
        --log(#crdsClear)
        local result = {{crdsClear[1].symbolName}}
        local resultX, resultY = 1, 1
        for i=2, #crdsClear, 1 do
            -- Добавляем перенос и символ, возрващем каретку.
            if  crdsClear[i-1].y  + options.deltaY < crdsClear[i].y then
                resultX = resultX + 1
                resultY = 1 -- возврат картеки
                result[resultX]={crdsClear[i].symbolName}
            -- Добавляем пробел и символ
            elseif crdsClear[i-1].x  + options.deltaSpace < crdsClear[i].x then
                resultY = resultY + 1
                result[resultX][resultY] = crdsClear[i].symbolName
            -- Добавляем символ
            else
                result[resultX][resultY] = result[resultX][resultY].. crdsClear[i].symbolName
            end
            --table.show(result,"result")
        end
        --table.show(result,"result")
        return result
    end
end

Пример вызова:
Код
result = imageToString{path="img", timeProc=0, crds={0,0,110,150}}


Может пригодится при тестах:
Вывод таблицы в лог
Код
do
    local tab = ""
    local deep = 0
    function table.show(t, comment)
        -- Пишем в лог комментарий.
        deep = deep + 1 -- Уровень вложенности вызовов функции.
        --log(comment .. commentSended .. deep)
        if  comment ~= nil and deep == 1 then
            log(comment)
        end


        if     type(t) == "nil"     then log("table is nil")
        elseif type(t) == "string"  then log('table is string: "'..t..'"')
        elseif type(t) == "number"  then log('table is number: '..t)
        elseif type(t) == "table"   then
            local elementsInTable = 0
            for k,v in pairs(t) do
                if  type (v) == "table" then
                    log(tab.."table: "..k)
                    tab = tab .. "    "
                    table.show(v)
                    tab = string.sub(tab, 1, -5)
                    elementsInTable = elementsInTable + 1
                else
                    elementsInTable = elementsInTable + 1
                    if type(v) == "string" then v = '"'..v..'"' end
                    if type(k) == "string" then k = '"'..k..'"' end
                    log(tab..""..k.." = "..v)
                end
            end
            if elementsInTable == 0 then log("table is empty") end
        else
            log('table is unknow data type')
        end
        -- Пишем в лог комментарий.
        deep = deep - 1 -- Уровень вложенности вызовов функции.
    end
end

Вывод таблицы в лог в формате инициализации
Код
function table.toInit(t)
        log("mode compact")
        log('table_name={')
        for k,v in pairs (t) do
           local str = "    {"
           for k2,v2 in pairs(v) do
               str = str .. k2.. "=" .. v2 .. ","
           end
           str = str .. "},"
           log(str)
        end
        log("}")
end

Автор: cirus 22.9.2017, 4:08

Цитата
Буду благодарен за тесты и багрепорты

Лучше в отдельную тему, чтобы эту не засорять.
Если используется getimage, то в findimage указываются координаты 0, 0, ширина, высота. Где ширина и высота это размер изображения полученного getimage.
Т. е. при crds={100,100,250,350}, getimage(100,100,250,350) , а findimage не (100,100,250,350), а (0, 0, 151, 251).
Код
    -- Вместо этого:
screenshot = getimage(options.crds[1],options.crds[2],options.crds[3],options.crds[4], options.window)
    -- Это:
screenshot, options.crds[3], options.crds[4] = getimage(options.crds[1], options.crds[2], options.crds[3],options.crds[4], options.window)
options.crds[1], options.crds[2] = 0, 0

Автор: cirus 22.9.2017, 12:44

Исправь:

Код
DeleteImage(buffer[filePath])

На:
Код
deleteimage(buffer[filePath])

Вроде как Кнайт не правил deleteimage. Он хоть работает?
Похоже что не работает, память жрёт.

Автор: DarkMaster 22.9.2017, 15:12

Цитата
Лучше в отдельную тему, чтобы эту не засорять.

2 темы по двум аналогичным скриптам? Я понимаю, что это твой уголок и бессовестно вторгаться не буду, но как тогда это лучше сделать, чтобы не получился бардак с кучей тем?

Цитата
Если используется getimage, то в findimage указываются координаты 0, 0, ширина, высота. Где ширина и высота это размер изображения полученного getimage.
Т. е. при crds={100,100,250,350}, getimage(100,100,250,350) , а findimage не (100,100,250,350), а (0, 0, 151, 251).

спасибо

Код
for i=1, 10000, 1 do
    v = getimage(0, 0, 1920, 1080, workwindow)
    deleteimage(v)
end

Все исправно работает. Там чуть-чуть растет память, потом уменьшается. Это луа и его сборщик мусора.

-- Удаляем изображение, если делали скриншот.
if options.source == nil then
deleteimage(screenshot)
end
тут была ошибка) поправил.

Автор: cirus 22.9.2017, 15:16

Передавая в findimage options.path .. symbolName .. options.ext загрузка картинок в память не имеет смысла.
Передавать нужно адрес в памяти, а с учётом что картинок одного символа может быть несколько, то нужен ещё один цикл, для перебора всех адресов.

код
Код
for symbolName, imageAddress in pairs(images) do
    for _, j in pairs(imageAddress) do     -- цикл, если для одного символа несколько картинок
        tmp = {}
        findResult = findimage(
        options.crds[1] .. " " .. options.crds[2] .. " " ..
        options.crds[3] .. " " .. options.crds[4] .. " " ..
        "(" .. j .. ") " ..                         -- передаём j - адрес в памяти
        "%tmp " .. screenshot .. " " .. options.accuracy .. " -1 " .. options.deviation .. " " .. options.abs)
        -- log("symoblName: ".. symbolName .. " findResult: " .. findResult)
        -- проверяем на возрват нуля или ошбики, со стрингом нормально не сравнить.

        if  findResult ~= "0" and not string.find(findResult, "-") then
        -- Добавляем найденные значения в общий результат поисков.
        --table.show(tmp,"tmp")
            for i = 1, #tmp, 1 do
                -- Напрямую вернуть таблицу в функцию нельзя из-за синтаксиса.
                -- FIX. Нужен фикс функции findimage пилота (возвращает координаты стрингом)
                -- после фикса просто удалить "tonumber(parm)" оставив parm.
                table.insert(crdsRaw,{x=tonumber(tmp[i][1]),y=tonumber(tmp[i][2]),symbolName=symbolName})
            end
        end
    end
end

Цитата
2 темы по двум аналогичным скриптам? Я понимаю, что это твой уголок и бессовестно вторгаться не буду, но как тогда это лучше сделать, чтобы не получился бардак с кучей тем?

Имелось ввиду для обсуждения багов отдельная тема, которую потом можно и удалить. Растягивать эту тему постами, которые будут не актуальны после исправления багов смысла нет. Или придётся потом эту тему чистить.
Когда скрипт будет доделан первый пост отредактируешь, останется мой скрипт на языке пилота и твой на луа.

Автор: DarkMaster 22.9.2017, 15:23

А по адресу можно определить высоту/ширину изображения? Чтобы не передавать кучу параметров вместо одного, если в функцию передается источник изображения? Всмысле по-человечески. Понятно, что можно взять readmem и понеслался...

Цитата
Передавая в findimage options.path .. symbolName .. options.ext загрузка картинок в память не имеет смысла.

Пофиксил. Видимо после тестов осталось, а думал, что закончил блок. Скорее всего из-за того, что прерывался на несколько дней регулярно.

Автор: cirus 22.9.2017, 15:45

Код
symbols = {
           "0" = {"zero1", "zero2"},
           "1" = {"1a", "1b"},
           "2" = {"two", "second"}
          }

Нужны квадратные скобки.
Код
symbols = {
           ["0"] = {"zero1", "zero2"},
           ["1"] = {"1a", "1b"},
           ["2"] = {"two", "second"}
          }

Автор: DarkMaster 22.9.2017, 17:28

Цитата
Нужны квадратные скобки.

Ща переделаю. Не нужны будут кавычки)

Автор: cirus 23.9.2017, 3:09

Первый пост почистил.

Код
default.loadPath     = nil                -- Путь по которому будут загружены все изображения с указанными расширением. Имя файла будет соответсвовать имени символа.

Для чего это? Оно нигде не используется.
Как сделать чтобы картинки загружались только при первом вызове функции?
Код
fileList = dir(options.path, options.ext)

Исправить на:
Код
fileList = dir(options.path, "*" .. options.ext .. "*")


Автор: DarkMaster 23.9.2017, 10:21

Цитата
Для чего это? Оно нигде не используется.
Как сделать чтобы картинки загружались только при первом вызове функции?

Я не смог заставить работать dir. По плану указываешь папку и вся папка загружается. dir у меня почему-то работает только с корнем диска. Кхе... Сейчас сразу завелся... Вызывал без фильтров при тестах. В чем проблема была не понятно.

Автор: DarkMaster 25.9.2017, 19:32

Кое-что пофиксил, добавил, переработал. В целом можно назвать релиз кандидатом. По функционалу есть вопрос: нужна ли возможность одновременно указать несколько источников изображений? Умолчательные, перечисленные, папку? Несколько папок (подпапки можно уже сейчас)?

Lua распознавание текста
Код
-- Баг:  из-за особенностей костыля финдимиджа создается НЕ локальня переменная tmp.
-- Фикс: изображение не добавлялось в буфер.
-- Фикс: расчет пробела от конечной х координаты.
-- Фикс: очистка буфера после захвата изображения.
-- Фикс: область поиска при источнике из getimage должна быть с нуля.
-- Фикс: искалось только одно изображение из-за недостающего вложенного цикла.
-- Фикс: буфер теперь действительно буферезует.
-- Переработно преобразование из упрощенного синтаксиса в полнеценный. Добавлена защита от дурка (типы данных).
-- Добавлено: загрузка папки с изображениями.
-- Добавлено: ожидание прогрузки изображений (options.secondFrame).
-- Добавлено: чтение из буфера.

do
    -- Символы для поиска.
    -- Возможно указать в двух вариантах синтаксиса: упрощенном и полном.
    -- Упрощенный синтаксис:
    -- В упрощенном варианте синтаксиса допускается не указывать
    -- соответствие имен файлов и строке/символу,
    -- который они обозначают: считается, что они идентичны.
    -- Пример упрощенного синтаксиса:
    -- local symbols = {"0", "1", "2", "3", "a", "b", "c", "test"}
    -- Полный синтаксис:
    -- Полный синтаксис бывает необходим при использовании
    -- нескольких изображений соответсвующих одной и той же строке/символу.
    -- Допускаются переносы строк:
    -- local symbols = {
    --       ["0"] = {"zero1", "zero2"},
    --       ["1"] = {"1a", "1b"},
    --       ["2"] = {"two", "second"}
    --      }
    -- Оба варианта синтаксиса можно сочетать:
    -- local symbols = {"0", "1", ["2"] = {"two", "second"}, "3"}


    local default = {}
    default.crds         = {0, 0, 1920, 1080} -- Координаты поиска
    default.path         = "c:\\image"        -- Папка с картинками
    default.ext          = ".bmp"             -- Расширение картинок
    default.loadFolder   = nil                -- Путь по которому будут загружены все изображения с указанными расширением {path=путь, mask=маска, sub=1|0}(sub - подпапки). Имя файла будет соответсвовать имени символа.
    default.deltaY       = 8                  -- Расстояние между строками (можно указать высоту картинок)
    default.deltaSpace   = 2                  -- Допустимое расстояние между цифрами, иначе будет считаться что это не одно число
    default.accuracy     = 95                 -- Точность поиска для Findimage
    default.deviation    = 3                  -- Погрешность оттенка  для Findimage
    default.wait         = 2                  -- Пауза между поиском картинок, если указать меньше искать будет быстрее, но нагрузит процессор
    default.timeProc     = 2                  -- Время в секундах (может быть не целым) для поиска картинок, если -1 не выйдет из процедуры пока не найдётся хотя бы 1 картинка
    default.repeatImage  = 2                  -- Допустимое смещение координат, если используется несколько видов одной картинки
    default.window       = "workwindow"       -- Метод|хендл_окна в котором происходит поиск (если указан источник изображения(source), то параметр будет проигнорирован)
    default.abs          = 0                  -- Использовать abs координаты.
    default.source       = nil                -- Изображение в котором производится поиск. Должен быть задан таблицей {адрес, ширина, высота}, nil вместо таблицы приведет к захвату изображения с экрана.
    default.bufferAddNew = 1                  -- Добавлять изображения в буфер
    default.bufferIgnore = 0                  -- Игнорировать изображения находящиеся в буфере
    default.bufferUpdate = 0                  -- Обновить изображения содержащиеся в буфере.
    default.secondFrame  = 0                  -- Ожидание прогрузки значений. Изображение будет проанализировано только после secondFrame секунд с первой успешной попытки считать любое из избражений.
    -- набор стандартных символов
    default.symbols      = {["0"]={"0"}, ["1"]={"1"}, ["2"]={"2"}, ["3"]={"3"}, ["4"]={"4"}, ["5"]={"5"}, ["6"]={"6"}, ["7"]={"7"}, ["8"]={"8"}, ["9"]={"9"}}


    -- Буфер
    -- Буфер
    -- Буфер

    local buffer = {} -- Массив с загруженными картинками.
    imageToStringBuffer = {} -- набор функций по управлению буфером.
    -- Полностью очищаем массив.
    function imageToStringBuffer.flush()
        for k,_ in pairs(buffer) do buffer[v] = nil end
    end
    -- Удаляем элемент из буфера
    function imageToStringBuffer.flush(element)
        buffer[element] = nil
    end
    -- Добавляем изображение в буфер
    function imageToStringBuffer.flush(element, val)
        buffer[element] = val
    end
    -- Читаем изображение из буфера
    function imageToStringBuffer.flush(element)
        return buffer[element]
    end


    -- Поиск
    -- Поиск
    -- Поиск

    function imageToString(options)

        -- Проверяем переданные параметры. Если они отсутствуют - подставляем параметры по умолчанию.
        if  options              == nil then local options        = {}                    end
        if  options.crds         == nil then options.crds         = default.crds          end
        if  options.path         == nil then options.path         = default.path          end
        if  options.ext          == nil then options.ext          = default.ext           end
        if  options.loadFolder   == nil then options.loadFolder   = default.loadFolder    end
        if  options.deltaY       == nil then options.deltaY       = default.deltaY        end
        if  options.deltaSpace   == nil then options.deltaSpace   = default.deltaSpace    end
        if  options.accuracy     == nil then options.accuracy     = default.accuracy      end
        if  options.deviation    == nil then options.deviation    = default.deviation     end
        if  options.wait         == nil then options.wait         = default.wait          end
        if  options.timeProc     == nil then options.timeProc     = default.timeProc      end
        if  options.repeatImage  == nil then options.repeatImage  = default.repeatImage   end
        if  options.window       == nil then options.window       = default.window        end
        if  options.abs          == nil then options.abs          = default.abs           end
        if  options.source       == nil then options.source       = default.source        end
        if  options.bufferAddNew == nil then options.bufferAddNew = default.bufferAddNew  end
        if  options.bufferIgnore == nil then options.bufferIgnore = default.bufferIgnore  end
        if  options.bufferUpdate == nil then options.bufferUpdate = default.bufferUpdate  end
        if  options.secondFrame  == nil then options.secondFrame  = default.secondFrame   end
        if  options.symbols      == nil then
            if  options.loadFolder   == nil then
                options.symbols = default.symbols
            else
                options.symbols = {}
            end
        end


        --Добавляем при необходимости обратный слэш в путь.
        if  string.sub(options.path, -1) ~= "\\" then options.path = options.path .. "\\" end

        -- Папка для загрузки изображений не задана, загружаем обычным методом.
        if  options.loadFolder.path == nil then

            -- Преобразуем урощенный синтаксис в полноценный, преобразуем пути в полные.
            do
                local tmp = {} --Массив в который временно помещаются преобразованные данные.
                for symbolName, imageName in pairs(options.symbols) do
                    -- Если занчение задано строкой/числом, приводим его к таблице, дописываем путь до полного.
                    if  type(options.symbols[symbolName]) == "number" then
                        options.symbols[symbolName] = {options.path..tostring(imageName)..options.ext}
                    elseif  type(options.symbols[symbolName]) == "string" then
                        options.symbols[symbolName] = {options.path..imageName..options.ext}
                    --  Значение задано таблицей, преобразоываем числа в строки, дописываем путь до полного.
                    elseif  type(options.symbols[symbolName]) == "table" then
                        for n=1, #options.symbols[symbolName] do
                            if  type(options.symbols[symbolName][n]) == "number" then
                                options.symbols[symbolName][n] = options.path..tostring(options.symbols[symbolName][n])..options.ext
                            elseif  type(options.symbols[symbolName][n]) == "string" then
                                options.symbols[symbolName][n] = options.path..options.symbols[symbolName][n]..options.ext
                            else
                                msg ("Ошибочный тип значения картинок символов в таблице. Остановка скрипта")
                                stop_script()
                            end
                        end
                    else
                        msg ("Ошибочный тип значения картинок символов. Остановка скрипта")
                        stop_script()
                    end

                    -- Если ключ цифровой, преобразуем к строке
                    if  type(symbolName) == "number" then
                        tmp[tostring(symbolName)] = options.symbols[symbolName]
                    elseif  type(symbolName) == "string" then
                        tmp[symbolName] = options.symbols[symbolName]
                    else
                        msg ("Ошибочный тип ключа символов. Остановка скрипта")
                        stop_script()
                    end
                end
                options.symbols = tmp
            end
        else
            -- Загружаем папку с изображениями.
            -- Имя файла = имя символа.
            -- Допускается несколько одинаковых символов в различных подпапках.
            -- Приводим к понятному для пилота виду флаг чтение подпапок.

            -- Прилепляем кавычки к пути чтобы пилот не путал путь и маску.
            options.loadFolder.path = '"'..options.loadFolder.path..'"'
            if options.loadFolder.sub ~= 0 then options.loadFolder.sub = "norecursion" else options.loadFolder.sub = nil end
            -- Приводим маску к надлежащему виду, если она не задана.
            if options.loadFolder.mask == nil then options.loadFolder.mask = "*" end

            fileList = dir(options.loadFolder.path, options.loadFolder.mask, options.loadFolder.sub)
            for k, v in pairs (fileList) do
                -- символ уже существует (несколько вариантов изображения)
                if  options.symbols[v[3]] ~= nil then
                    table.insert(options.symbols[v[3]], v[1])
                else
                    options.symbols[v[3]] = {v[1]}
                end
            end
        end
        --table.show(options.symbols)
        --if 1 then return end



        -- Приводим options.abs к виду пригодному для финдимиджа.
        if     options.abs == 1 then options.abs = "abs"
        elseif options.abs == 0 then options.abs = ""
        end
        --table.show(options.symbols)


        -- Загрузка картинок
        local images={}     --Загружает в память изображения {имя символа, {адреса в памяти}}
        local loadError = 0
        for symbolName, fileList in pairs(options.symbols) do
            images[symbolName] = {}
            for i=1, #fileList, 1 do
                -- Загружен ли файл в буфер, если нет, то подгружаем.
                local filePath = fileList[i]
                if  options.bufferIgnore == 0 and options.bufferUpdate == 0 and buffer[filePath] ~= nil then
                    images[symbolName][i] = buffer[filePath]
                else
                    -- В буфере изображения нет, загружаем с диска.
                    --log(filePath.."В буфере изображения нет, загружаем с диска.")
                    images[symbolName][i] = loadimage(filePath)
                    -- Обновляем загруженное в буфер изображение
                    if  buffer[filePath] ~= nil then
                        deleteimage(buffer[filePath])
                        buffer[filePath] =  images[symbolName][i]
                    elseif options.bufferAddNew == 1 and options.bufferIgnore == 0 then
                        -- Добавляем в буфер новое изображение.
                        buffer[filePath] = images[symbolName][i]
                    end
                end
                -- Поиск ошибок загрузки.
                if images[symbolName][i] < 0  then
                    loadError = loadError + 1
                    log("Image loading fail. Error file: "..filePath..'.')
                end
            end
        end
        -- При загрузке изображений произошли ошибки. Останавливаем скрипт.
        if  loadError > 0 then
            log("Error loading count: "..loadError..'.')
            stop_script()
        end
        --table.show(images)


        local timeout = os.clock() + options.timeProc

        -- log(options.secondFrame)
        -- Таймаут на прогрузку. Поиск для детекта изображений.
        if options.secondFrame > 0 then
            -- Создаем карман области видимости.
            -- Реузльататы блока не нужны для остального скрипта.
            do
                local catch = 0
                -- Если вермя ожидания после детекта не уложится в общий
                -- таймаут, то выходим из цикла без дальшейших попыток найти изображение.
                secondFrameTimeout = timeout - options.secondFrame
                while true do -- выход внутри цикла  timeout < os.clock()
                    local screenshot, width, height = nil, nil, nil
                    if  options.source == nil then
                        screenshot, width, height = getimage(options.crds[1],options.crds[2],options.crds[3],options.crds[4], options.window)
                    else
                        screenshot, width, height = options.source[1],options.source[2],options.source[3]
                    end
                    for symbolName, imageAddressArray in pairs(images) do
                        for _, imageAddress in pairs(imageAddressArray) do
                            local tmp = {}
                            findResult = findimage(
                                0 .. " " .. 0 .. " " ..
                                width .. " " .. height .. " " ..
                                "(" .. imageAddress .. ") " ..
                                "%tmp " .. screenshot .. " " .. options.accuracy .. " -1 " .. options.deviation .. " " .. options.abs)
                            --log("symoblName: ".. symbolName .. " findResult: " .. findResult)
                            -- проверяем на возрват нуля или ошбики, со стрингом нормально не сравнить.
                            if  findResult ~= "0" and not string.find(findResult, "-") then
                                catch = 1
                                --log("break")
                                wait(math.floor(options.secondFrame * 1000))
                                break
                            end
                            -- Время на всю функцию истекло
                            if  timeout - options.secondFrame < os.clock() then
                                return
                            end
                        end
                        if catch == 1 then break end
                    end
                    if catch == 1 then break end
                end
            end
        end


        -- Ищем изображения
        local crdsRaw={} -- Массив со всеми найденными изображениями, возможны дубли, не сортированный.
        repeat  -- Повторяем пока что-то не найдем или не выйдет время на поиск (options.timeProc).
            -- Получаем изображение с экрана, если источник не указан.
            local screenshot, width, height = nil
            if  options.source == nil then
                screenshot, width, height = getimage(options.crds[1],options.crds[2],options.crds[3],options.crds[4], options.window)
            else
                screenshot, width, height = options.source[1],options.source[2],options.source[3]
            end
            --log(screenshot)
            for symbolName, imageAddressArray in pairs(images) do
                for _, imageAddress in pairs(imageAddressArray) do
                    tmp = {}
                    findResult = findimage(
                        0 .. " " .. 0 .. " " ..
                        width .. " " .. height .. " " ..
                        "(" .. imageAddress .. ") " ..
                        "%tmp " .. screenshot .. " " .. options.accuracy .. " -1 " .. options.deviation .. " " .. options.abs)
                    --log("symoblName: ".. symbolName .. " findResult: " .. findResult)
                    -- проверяем на возрват нуля или ошбики, со стрингом нормально не сравнить.
                    if  findResult ~= "0" and not string.find(findResult, "-") then
                        -- Добавляем найденные значения в общий результат поисков.
                        table.show(tmp,"tmp")
                        for i = 1, #tmp, 1 do
                            -- Напрямую вернуть таблицу в функцию нельзя из-за синтаксиса.
                            -- FIX. Нужен фикс функции findimage пилота (возвращает координаты стрингом)
                            -- после фикса просто удалить "tonumber(parm)" оставив parm.
                            table.insert(crdsRaw,{x=tonumber(tmp[i][1]),y=tonumber(tmp[i][2]),xEnd=tonumber(tmp[i][3]),symbolName=symbolName})
                        end
                    end
                end
            end

            -- Удаляем изображение, если делали скриншот.
            if  options.source == nil then
                deleteimage(screenshot)
            end

            --table.show(images, "images")
            --log (#crdsRaw, timeout, os.clock(), options.timeProc)
            log ("until")
            local clock = os.clock()
        until not ((#crdsRaw == 0) and (timeout > clock or options.timeProc == -1))
        --table.show(crdsRaw, "crdsRaw")

        --  Изображения не были найдены, выходим из поиска.
        if  #crdsRaw < 1 then
            return nil
        end
        -- Удаляем дубли.
        local crdsClear={} -- Массив без дублей.
        for i=1, #crdsRaw, 1 do
            local catch = 0 -- Флаг найденного дубля.
            for n=i+1, #crdsRaw, 1 do
                --log(
                --  crdsRaw[i].symbolName.." == "..crdsRaw[n].symbolName.." and "..
                --  math.abs(crdsRaw[i].x - crdsRaw[n].x).." <= "..options.repeatImage.." and "..
                --  math.abs(crdsRaw[i].y - crdsRaw[n].y).." <= "..options.repeatImage
                --)
                if  crdsRaw[i].symbolName == crdsRaw[n].symbolName and
                  math.abs(crdsRaw[i].x - crdsRaw[n].x) <= options.repeatImage and
                  math.abs(crdsRaw[i].y - crdsRaw[n].y) <= options.repeatImage then
                    catch = 1
                    break
                end
            end
            --log(catch)
            if  catch == 0 then -- не дубль, копируем значение в чистый массив.
                table.insert(crdsClear,crdsRaw[i])
            end
        end

        -- Сортируем элементы.
        -- Сортировка происходит, как по X координате,
        -- так и по Y учитывая возможность нескольких строк.
        -- Межстрочный интервал задается с помощью options.deltaY.
        -- Для уплотнения поиска options.deltaY может быть отрицательным.
        -- Отрицательный options.deltaY в первую очередь необходим,
        -- если изображения символов содержат сверху и снизу от символа фон.
        -- crdsClear был предварительно очищен от дублей, теперь сортируется.

        --table.show(crdsClear,"crdsClear")
        --table.toInit(crdsClear)
        table.sort(crdsClear,
            function(a,b)
                if  math.abs(a.y - b.y) <= options.deltaY then
                    if  a.x < b.x then
                        return true
                    else
                        return false
                    end
                else
                    if a.y < b.y then
                        return true
                    else
                        return false
                    end
                end
            end
        )
        --table.show(crdsClear,"crdsClear")

        -- Собираем строку
        --log(#crdsClear)
        local result = {{crdsClear[1].symbolName}}
        local resultX, resultY = 1, 1
        for i=2, #crdsClear, 1 do
            -- Добавляем перенос и символ, возрващем каретку.
            if  crdsClear[i-1].y  + options.deltaY < crdsClear[i].y then
                resultX = resultX + 1
                resultY = 1 -- возврат картеки
                result[resultX]={crdsClear[i].symbolName}
            -- Добавляем пробел и символ
            elseif crdsClear[i-1].xEnd  + options.deltaSpace < crdsClear[i].x then
                resultY = resultY + 1
                result[resultX][resultY] = crdsClear[i].symbolName
            -- Добавляем символ
            else
                result[resultX][resultY] = result[resultX][resultY].. crdsClear[i].symbolName
            end
            --table.show(result,"result")
        end
        --table.show(result,"result")
        return result
    end
end


Погоняй, пожалуйста.

Автор: cirus 26.9.2017, 4:20

Цитата
if options.loadFolder.path == nil then

Обращение к несуществующему элементу таблицы? Есть только options.path и options.loadFolder.
Код
log ("until")
table.show(tmp,"tmp")

Закомментировать.
Код
--if 1 then return end

Лишнее.
Код
secondFrameTimeout = timeout - options.secondFrame

Переменная глобальная и нигде не используется.
Подозреваю что должна быть тут (если она вообще нужна):
Код
if  timeout - options.secondFrame < os.clock() then

Т. е.
Код
if secondFrameTimeout < os.clock() then

При default.timeProc = -1 и default.secondFrame = 1 сразу выходит из функции.
Цитата
По функционалу есть вопрос: нужна ли возможность одновременно указать несколько источников изображений? Умолчательные, перечисленные, папку? Несколько папок (подпапки можно уже сейчас)?

Если можно подпапки, то не вижу смысла.
Если указать папку без картинок, то пилот закрывается. Хотя это наверное косяки 10 бетки, а не скрипта.
Добавить возможность сохранить изображение, в котором производился поиск (screenshot).

Автор: DarkMaster 26.9.2017, 12:05

Цитата
Обращение к несуществующему элементу таблицы? Есть только options.path и options.loadFolder.

Вообще в этом и был смысл, т.к. планировалось loadFolder по умолчанию задавать пустой таблицей, но потом я ушел от этого. При этом обращение к несуществующему элементу, если он загружен по умолчанию, но обязательно заданному, если loadFolder использовался при вызове, дало бы нужный результат. Поправил.
Цитата
Переменная глобальная и нигде не используется.
Подозреваю что должна быть тут (если она вообще нужна):

Все правильно понял, локал проставил.
Цитата
При default.timeProc = -1 и default.secondFrame = 1 сразу выходит из функции.

Фиксанул.

Автор: DarkMaster 26.9.2017, 12:17

Цитата
Если указать папку без картинок, то пилот закрывается. Хотя это наверное косяки 10 бетки, а не скрипта.

Это бетки проблемы. Пока пытался понять на каком этапе вылетает (по факту там скорее всего на один из stop_script() скрипт наступал) вылетать перестало. Сделал принудительную проверку на наличие изображений, если их нет, то будет stop_script(). Т.е. скрипт точно так же выбьет пилот, но теперь будет ясно где и в лог пофлудит.

Автор: DarkMaster 26.9.2017, 12:43

Если замечаний нет, то можно в первый пост, да начну документацию писать.

Распознавание текста Lua.
Код
// Автор скрипта DarkMaster.
-- Написано по мотивам скрипта Cirus.
-- Тестирование Cirus.
-- Вопросы, баги, предложения на форум
-- в специальную тему по этому скрипту
-- https://forum.uokit.com/index.php?showtopic=30000

-- Фикс: флаг чтения подпапок был инвертирован.
-- Фикс: secondFrameTimeout больше не глобальная и используется по назначению.
-- Фикс: При default.timeProc = -1 и default.secondFrame > 0 не выходит преждевременно из функции.
-- Фикс: Почистил отладочные выводы в лог.
-- Добавлено сохранение изображение в котором происходил поиск.

-- Баг:  из-за особенностей костыля финдимиджа создается НЕ локальня переменная tmp.
-- Фикс: изображение не добавлялось в буфер.
-- Фикс: расчет пробела от конечной х координаты.
-- Фикс: очистка буфера после захвата изображения.
-- Фикс: область поиска при источнике из getimage должна быть с нуля.
-- Фикс: искалось только одно изображение из-за недостающего вложенного цикла.
-- Фикс: буфер теперь действительно буферезует.
-- Переработно преобразование из упрощенного синтаксиса в полнеценный. Добавлена защита от дурка (типы данных).
-- Добавлено: загрузка папки с изображениями.
-- Добавлено: ожидание прогрузки изображений (options.secondFrame).
-- Добавлено: чтение из буфера.

do

-- Раскомментировать, если в отладке будет использоват table.show.
--[[do
    local tab = ""
    local deep = 0
    function table.show(t, comment)
        -- Пишем в лог комментарий.
        deep = deep + 1 -- Уровень вложенности вызовов функции.
        --log(comment .. commentSended .. deep)
        if  comment ~= nil and deep == 1 then
            log(comment)
        end


        if     type(t) == "nil"     then log("table is nil")
        elseif type(t) == "string"  then log('table is string: "'..t..'"')
        elseif type(t) == "number"  then log('table is number: '..t)
        elseif type(t) == "table"   then
            local elementsInTable = 0
            for k,v in pairs(t) do
                if  type (v) == "table" then
                    if type(k) == "string" then
                        log(tab..'table: "'..k..'"')
                    else
                        log(tab..'table: '..k)
                    end
                    tab = tab .. "    "
                    table.show(v)
                    tab = string.sub(tab, 1, -5)
                    elementsInTable = elementsInTable + 1
                else
                    elementsInTable = elementsInTable + 1
                    if type(v) == "string" then v = '"'..v..'"' end
                    if type(k) == "string" then k = '"'..k..'"' end
                    log(tab..""..k.." = "..v)
                end
            end
            if elementsInTable == 0 then log("table is empty") end
        else
            log('table is unknow data type')
        end
        -- Пишем в лог комментарий.
        deep = deep - 1 -- Уровень вложенности вызовов функции.
    end
end
]]


    -- Символы для поиска.
    -- Возможно указать в двух вариантах синтаксиса: упрощенном и полном.
    -- Упрощенный синтаксис:
    -- В упрощенном варианте синтаксиса допускается не указывать
    -- соответствие имен файлов и строке/символу,
    -- который они обозначают: считается, что они идентичны.
    -- Пример упрощенного синтаксиса:
    -- local symbols = {"0", "1", "2", "3", "a", "b", "c", "test"}
    -- Полный синтаксис:
    -- Полный синтаксис бывает необходим при использовании
    -- нескольких изображений соответсвующих одной и той же строке/символу.
    -- Допускаются переносы строк:
    -- local symbols = {
    --       ["0"] = {"zero1", "zero2"},
    --       ["1"] = {"1a", "1b"},
    --       ["2"] = {"two", "second"}
    --      }
    -- Оба варианта синтаксиса можно сочетать:
    -- local symbols = {"0", "1", ["2"] = {"two", "second"}, "3"}


    local default = {}
    default.crds         = {0, 0, 1920, 1080} -- Координаты поиска
    default.path         = "c:\\image"        -- Папка с картинками
    default.ext          = ".bmp"             -- Расширение картинок
    default.loadFolder   = nil                -- Путь по которому будут загружены все изображения с указанной маской {path=путь, mask=маска, sub=1|0}(sub - подпапки). Имя файла будет соответсвовать имени символа.
    default.deltaY       = 8                  -- Расстояние между строками (можно указать высоту картинок)
    default.deltaSpace   = 2                  -- Допустимое расстояние между цифрами, иначе будет считаться что это не одно число
    default.accuracy     = 95                 -- Точность поиска для Findimage
    default.deviation    = 3                  -- Погрешность оттенка  для Findimage
    default.wait         = 2                  -- Пауза между поиском картинок, если указать меньше искать будет быстрее, но нагрузит процессор
    default.timeProc     = 2                  -- Время в секундах (может быть не целым) для поиска картинок, если -1 не выйдет из процедуры пока не найдётся хотя бы 1 картинка
    default.repeatImage  = 2                  -- Допустимое смещение координат, если используется несколько видов одной картинки
    default.window       = "workwindow"       -- Метод|хендл_окна в котором происходит поиск (если указан источник изображения(source), то параметр будет проигнорирован)
    default.abs          = 0                  -- Использовать abs координаты.
    default.source       = nil                -- Изображение в котором производится поиск. Должен быть задан таблицей {адрес, ширина, высота}, nil вместо таблицы приведет к захвату изображения с экрана.
    default.bufferAddNew = 1                  -- Добавлять изображения в буфер
    default.bufferIgnore = 0                  -- Игнорировать изображения находящиеся в буфере
    default.bufferUpdate = 0                  -- Обновить изображения содержащиеся в буфере.
    default.secondFrame  = 0                  -- Ожидание прогрузки значений. Изображение будет проанализировано только после secondFrame секунд с первой успешной попытки считать любое из избражений.
    default.saveImage    = nil                -- Путь по которому будет сохранено изображение в котором происходит поиск.
    -- набор стандартных символов
    default.symbols      = {["0"]={"0"}, ["1"]={"1"}, ["2"]={"2"}, ["3"]={"3"}, ["4"]={"4"}, ["5"]={"5"}, ["6"]={"6"}, ["7"]={"7"}, ["8"]={"8"}, ["9"]={"9"}}


    -- Буфер
    -- Буфер
    -- Буфер

    local buffer = {} -- Массив с загруженными картинками.
    imageToStringBuffer = {} -- набор функций по управлению буфером.
    -- Полностью очищаем массив.
    function imageToStringBuffer.flush()
        for k,_ in pairs(buffer) do buffer[v] = nil end
    end
    -- Удаляем элемент из буфера
    function imageToStringBuffer.flush(element)
        buffer[element] = nil
    end
    -- Добавляем изображение в буфер
    function imageToStringBuffer.flush(element, val)
        buffer[element] = val
    end
    -- Читаем изображение из буфера
    function imageToStringBuffer.flush(element)
        return buffer[element]
    end


    -- Поиск
    -- Поиск
    -- Поиск

    function imageToString(options)

        -- Проверяем переданные параметры. Если они отсутствуют - подставляем параметры по умолчанию.
        if  options              == nil then local options        = {}                    end
        if  options.crds         == nil then options.crds         = default.crds          end
        if  options.path         == nil then options.path         = default.path          end
        if  options.ext          == nil then options.ext          = default.ext           end
        if  options.loadFolder   == nil then options.loadFolder   = default.loadFolder    end
        if  options.deltaY       == nil then options.deltaY       = default.deltaY        end
        if  options.deltaSpace   == nil then options.deltaSpace   = default.deltaSpace    end
        if  options.accuracy     == nil then options.accuracy     = default.accuracy      end
        if  options.deviation    == nil then options.deviation    = default.deviation     end
        if  options.wait         == nil then options.wait         = default.wait          end
        if  options.timeProc     == nil then options.timeProc     = default.timeProc      end
        if  options.repeatImage  == nil then options.repeatImage  = default.repeatImage   end
        if  options.window       == nil then options.window       = default.window        end
        if  options.abs          == nil then options.abs          = default.abs           end
        if  options.source       == nil then options.source       = default.source        end
        if  options.bufferAddNew == nil then options.bufferAddNew = default.bufferAddNew  end
        if  options.bufferIgnore == nil then options.bufferIgnore = default.bufferIgnore  end
        if  options.bufferUpdate == nil then options.bufferUpdate = default.bufferUpdate  end
        if  options.secondFrame  == nil then options.secondFrame  = default.secondFrame   end
        if  options.saveImage    == nil then options.saveImage    = default.saveImage     end
        if  options.symbols      == nil then
            if  options.loadFolder   == nil then
                options.symbols = default.symbols
            else
                options.symbols = {}
            end
        end


        --Добавляем при необходимости обратный слэш в путь.
        if  string.sub(options.path, -1) ~= "\\" then options.path = options.path .. "\\" end

        -- Папка для загрузки изображений не задана, загружаем обычным методом.
        if  options.loadFolder == nil then
            -- Преобразуем урощенный синтаксис в полноценный, преобразуем пути в полные.
            do
                local tmp = {} --Массив в который временно помещаются преобразованные данные.
                for symbolName, imageName in pairs(options.symbols) do
                    -- Если занчение задано строкой/числом, приводим его к таблице, дописываем путь до полного.
                    if  type(options.symbols[symbolName]) == "number" then
                        options.symbols[symbolName] = {options.path..tostring(imageName)..options.ext}
                    elseif  type(options.symbols[symbolName]) == "string" then
                        options.symbols[symbolName] = {options.path..imageName..options.ext}
                    --  Значение задано таблицей, преобразоываем числа в строки, дописываем путь до полного.
                    elseif  type(options.symbols[symbolName]) == "table" then
                        for n=1, #options.symbols[symbolName] do
                            if  type(options.symbols[symbolName][n]) == "number" then
                                options.symbols[symbolName][n] = options.path..tostring(options.symbols[symbolName][n])..options.ext
                            elseif  type(options.symbols[symbolName][n]) == "string" then
                                options.symbols[symbolName][n] = options.path..options.symbols[symbolName][n]..options.ext
                            else
                                msg ("Ошибочный тип значения картинок символов в таблице. Остановка скрипта")
                                stop_script()
                            end
                        end
                    else
                        msg ("Ошибочный тип значения картинок символов. Остановка скрипта")
                        stop_script()
                    end

                    -- Если ключ цифровой, преобразуем к строке
                    if  type(symbolName) == "number" then
                        tmp[tostring(symbolName)] = options.symbols[symbolName]
                    elseif  type(symbolName) == "string" then
                        tmp[symbolName] = options.symbols[symbolName]
                    else
                        msg ("Ошибочный тип ключа символов. Остановка скрипта")
                        stop_script()
                    end
                end
                options.symbols = tmp
            end
        else
            -- Загружаем папку с изображениями.
            -- Имя файла = имя символа.
            -- Допускается несколько одинаковых символов в различных подпапках.
            -- Приводим к понятному для пилота виду флаг чтение подпапок.

            -- Прилепляем кавычки к пути чтобы пилот не путал путь и маску.
            options.loadFolder.path = '"'..options.loadFolder.path..'"'
            if options.loadFolder.sub == 1 then options.loadFolder.sub = nil else options.loadFolder.sub = "norecursion" end
            -- Приводим маску к надлежащему виду, если она не задана.
            if options.loadFolder.mask == nil then options.loadFolder.mask = "*" end
            fileList = dir(options.loadFolder.path, options.loadFolder.mask, options.loadFolder.sub)
            --table.show(fileList, "fileList")
            for k, v in pairs (fileList) do
                -- символ уже существует (несколько вариантов изображения)
                if  options.symbols[v[3]] ~= nil then
                    table.insert(options.symbols[v[3]], v[1])
                else
                    options.symbols[v[3]] = {v[1]}
                end
            end
        end
        --table.show(options.symbols)


        -- Приводим options.abs к виду пригодному для финдимиджа.
        if      options.abs == 1 then options.abs = "abs"
        elseif  options.abs == 0 then options.abs = ""
        end


        -- Загрузка картинок
        local images={}     --Загружает в память изображения {имя символа, {адреса в памяти}}
        local loadError = 0
        for symbolName, fileList in pairs(options.symbols) do
            images[symbolName] = {}
            for i=1, #fileList, 1 do
                -- Загружен ли файл в буфер, если нет, то подгружаем.
                local filePath = fileList[i]
                if  options.bufferIgnore == 0 and options.bufferUpdate == 0 and buffer[filePath] ~= nil then
                    images[symbolName][i] = buffer[filePath]
                else
                    -- В буфере изображения нет, загружаем с диска.
                    --log(filePath.."В буфере изображения нет, загружаем с диска.")
                    images[symbolName][i] = loadimage(filePath)
                    -- Обновляем загруженное в буфер изображение
                    if  buffer[filePath] ~= nil then
                        deleteimage(buffer[filePath])
                        buffer[filePath] =  images[symbolName][i]
                    elseif options.bufferAddNew == 1 and options.bufferIgnore == 0 then
                        -- Добавляем в буфер новое изображение.
                        buffer[filePath] = images[symbolName][i]
                    end
                end
                -- Поиск ошибок загрузки.
                if images[symbolName][i] < 0  then
                    loadError = loadError + 1
                    log("Image loading fail. Error file: "..filePath..'.')
                end
            end
        end
        -- При загрузке изображений произошли ошибки. Останавливаем скрипт.
        if  loadError > 0 then
            log("Error loading count: "..loadError..'.')
            stop_script()
        end
        if  images == nil then
            log("Файлы изображений не найдены. Скрипт остановлен.")
            stop_script()
        end
        --table.show(images,"images")


        local timeout = os.clock() + options.timeProc


        -- log(options.secondFrame)
        -- Таймаут на прогрузку. Поиск для детекта изображений.
        if options.secondFrame > 0 then
            -- Создаем карман области видимости.
            -- Реузльататы блока не нужны для остального скрипта.
            do
                local catch = 0
                -- Если вермя ожидания после детекта не уложится в общий
                -- таймаут, то выходим из цикла без дальшейших попыток найти изображение.
                local secondFrameTimeout = timeout - options.secondFrame
                while true do -- выход внутри цикла  timeout < os.clock()
                    local screenshot, width, height = nil, nil, nil
                    if  options.source == nil then
                        screenshot, width, height = getimage(options.crds[1],options.crds[2],options.crds[3],options.crds[4], options.window)
                    else
                        screenshot, width, height = options.source[1],options.source[2],options.source[3]
                    end
                    for symbolName, imageAddressArray in pairs(images) do
                        for _, imageAddress in pairs(imageAddressArray) do
                            local tmp = {}
                            findResult = findimage(
                                0 .. " " .. 0 .. " " ..
                                width .. " " .. height .. " " ..
                                "(" .. imageAddress .. ") " ..
                                "%tmp " .. screenshot .. " " .. options.accuracy .. " -1 " .. options.deviation .. " " .. options.abs)
                            --log("symoblName: ".. symbolName .. " findResult: " .. findResult)
                            -- проверяем на возрват нуля или ошбики, со стрингом нормально не сравнить.
                            if  findResult ~= "0" and not string.find(findResult, "-") then
                                catch = 1
                                --log("break")
                                wait(math.floor(options.secondFrame * 1000))
                                break
                            end
                            -- Время на всю функцию истекло
                            if  secondFrameTimeout < os.clock() and options.timeProc ~= -1 then
                                return
                            end
                        end
                        if catch == 1 then break end
                    end
                    if catch == 1 then break end
                end
            end
        end


        -- Ищем изображения
        local crdsRaw={} -- Массив со всеми найденными изображениями, возможны дубли, не сортированный.
        repeat  -- Повторяем пока что-то не найдем или не выйдет время на поиск (options.timeProc).
            -- Получаем изображение с экрана, если источник не указан.
            local screenshot, width, height = nil
            if  options.source == nil then
                screenshot, width, height = getimage(options.crds[1],options.crds[2],options.crds[3],options.crds[4], options.window)
            else
                screenshot, width, height = options.source[1],options.source[2],options.source[3]
            end
            --log(screenshot)
            for symbolName, imageAddressArray in pairs(images) do
                for _, imageAddress in pairs(imageAddressArray) do
                    tmp = {}
                    findResult = findimage(
                        0 .. " " .. 0 .. " " ..
                        width .. " " .. height .. " " ..
                        "(" .. imageAddress .. ") " ..
                        "%tmp " .. screenshot .. " " .. options.accuracy .. " -1 " .. options.deviation .. " " .. options.abs)
                    --log("symoblName: ".. symbolName .. " findResult: " .. findResult)
                    -- проверяем на возрват нуля или ошбики, со стрингом нормально не сравнить.
                    if  findResult ~= "0" and not string.find(findResult, "-") then
                        -- Добавляем найденные значения в общий результат поисков.
                        --table.show(tmp,"tmp")
                        for i = 1, #tmp, 1 do
                            -- Напрямую вернуть таблицу в функцию нельзя из-за синтаксиса.
                            -- FIX. Нужен фикс функции findimage пилота (возвращает координаты стрингом)
                            -- после фикса просто удалить "tonumber(parm)" оставив parm.
                            table.insert(crdsRaw,{x=tonumber(tmp[i][1]),y=tonumber(tmp[i][2]),xEnd=tonumber(tmp[i][3]),symbolName=symbolName})
                        end
                    end
                end
            end

            -- Сохраняем изображение.
            if  options.saveImage ~= nil then
                saveimage(screenshot, options.saveImage)
            end
            -- Удаляем изображение, если получали его из приложения.
            if  options.source == nil then
                deleteimage(screenshot)
            end

            --table.show(images, "images")
            --log (#crdsRaw, timeout, os.clock(), options.timeProc)
            --log ("until")
            local clock = os.clock()
        until not ((#crdsRaw == 0) and (timeout > clock or options.timeProc == -1))
        --table.show(crdsRaw, "crdsRaw")

        --  Изображения не были найдены, выходим из поиска.
        if  #crdsRaw < 1 then
            return nil
        end
        -- Удаляем дубли.
        local crdsClear={} -- Массив без дублей.
        for i=1, #crdsRaw, 1 do
            local catch = 0 -- Флаг найденного дубля.
            for n=i+1, #crdsRaw, 1 do
                --log(
                --  crdsRaw[i].symbolName.." == "..crdsRaw[n].symbolName.." and "..
                --  math.abs(crdsRaw[i].x - crdsRaw[n].x).." <= "..options.repeatImage.." and "..
                --  math.abs(crdsRaw[i].y - crdsRaw[n].y).." <= "..options.repeatImage
                --)
                if  crdsRaw[i].symbolName == crdsRaw[n].symbolName and
                  math.abs(crdsRaw[i].x - crdsRaw[n].x) <= options.repeatImage and
                  math.abs(crdsRaw[i].y - crdsRaw[n].y) <= options.repeatImage then
                    catch = 1
                    break
                end
            end
            --log(catch)
            if  catch == 0 then -- не дубль, копируем значение в чистый массив.
                table.insert(crdsClear,crdsRaw[i])
            end
        end

        -- Сортируем элементы.
        -- Сортировка происходит, как по X координате,
        -- так и по Y учитывая возможность нескольких строк.
        -- Межстрочный интервал задается с помощью options.deltaY.
        -- Для уплотнения поиска options.deltaY может быть отрицательным.
        -- Отрицательный options.deltaY в первую очередь необходим,
        -- если изображения символов содержат сверху и снизу от символа фон.
        -- crdsClear был предварительно очищен от дублей, теперь сортируется.

        --table.show(crdsClear,"crdsClear")
        --table.toInit(crdsClear)
        table.sort(crdsClear,
            function(a,b)
                if  math.abs(a.y - b.y) <= options.deltaY then
                    if  a.x < b.x then
                        return true
                    else
                        return false
                    end
                else
                    if a.y < b.y then
                        return true
                    else
                        return false
                    end
                end
            end
        )
        --table.show(crdsClear,"crdsClear")

        -- Собираем строку
        --log(#crdsClear)
        local result = {{crdsClear[1].symbolName}}
        local resultX, resultY = 1, 1
        for i=2, #crdsClear, 1 do
            -- Добавляем перенос и символ, возрващем каретку.
            if  crdsClear[i-1].y  + options.deltaY < crdsClear[i].y then
                resultX = resultX + 1
                resultY = 1 -- возврат картеки
                result[resultX]={crdsClear[i].symbolName}
            -- Добавляем пробел и символ
            elseif crdsClear[i-1].xEnd  + options.deltaSpace < crdsClear[i].x then
                resultY = resultY + 1
                result[resultX][resultY] = crdsClear[i].symbolName
            -- Добавляем символ
            else
                result[resultX][resultY] = result[resultX][resultY].. crdsClear[i].symbolName
            end
            --table.show(result,"result")
        end
        --table.show(result,"result")
        return result
    end
end

Автор: cirus 26.9.2017, 14:22

Цитата
// Автор

Исправь на комментарий луа --
Добавь --lua в начало скрипта.
Если маска задана: mask="bmp", то не найдёт картинки. Допиши проверку на наличие и добавление * к маске, если * нет.
Код
result = imageToString{crds={33, 189 ,292, 255}}
result = imageToString{crds={33, 189 ,292, 255}}

При втором вызове функции массив с картинками пуст.

Автор: DarkMaster 26.9.2017, 15:32

Цитата
Исправь на комментарий луа --

Исправил через секунду после поста) Слишком быстрый ты smile.gif
Цитата
Если маска задана: mask="bmp", то не найдёт картинки. Допиши проверку на наличие и добавление * к маске, если * нет.

И не должно находить. Это стандартный синтаксис маски, где буквенное сочетание предполагает полное совпадение, а возможные отсутствующие символы задаются с помощью * - (любое количество любых символов) и ? - один неизвестный символ. Я даже хз как этот синтаксис называется и где его полная версия, но эти подстановки еще со времен 95 винды помню.

Автор: DarkMaster 26.9.2017, 16:27

Фишки луа, которые не учел. Тут же arr={} не таблица, а только ссылка на таблицу и копирование arr2=arr1 не проходит - данные не копируются.

Распознавание текста Lua
Код
--lua
-- Автор скрипта DarkMaster.
-- Написано по мотивам скрипта Cirus.
-- Тестирование Cirus.
-- Вопросы, баги, предложения на форум
-- в специальную тему по этому скрипту
-- https://forum.uokit.com/index.php?showtopic=30000

-- Фикс: символы по умолчанию больше не изменятся, сделано корректное копирование массива.

-- Фикс: флаг чтения подпапок был инвертирован.
-- Фикс: secondFrameTimeout больше не глобальная и используется по назначению.
-- Фикс: При default.timeProc = -1 и default.secondFrame > 0 не выходит преждевременно из функции.
-- Фикс: Почистил отладочные выводы в лог.
-- Добавлено сохранение изображение в котором происходил поиск.

-- Баг:  из-за особенностей костыля финдимиджа создается НЕ локальня переменная tmp.
-- Фикс: изображение не добавлялось в буфер.
-- Фикс: расчет пробела от конечной х координаты.
-- Фикс: очистка буфера после захвата изображения.
-- Фикс: область поиска при источнике из getimage должна быть с нуля.
-- Фикс: искалось только одно изображение из-за недостающего вложенного цикла.
-- Фикс: буфер теперь действительно буферезует.
-- Переработно преобразование из упрощенного синтаксиса в полнеценный. Добавлена защита от дурка (типы данных).
-- Добавлено: загрузка папки с изображениями.
-- Добавлено: ожидание прогрузки изображений (options.secondFrame).
-- Добавлено: чтение из буфера.

do

    -- Раскомментировать, если в отладке будет использоват table.show.
    --[[do
        local tab = ""
        local deep = 0
        function table.show(t, comment)
            -- Пишем в лог комментарий.
            deep = deep + 1 -- Уровень вложенности вызовов функции.
            --log(comment .. commentSended .. deep)
            if  comment ~= nil and deep == 1 then
                log(comment)
            end


            if     type(t) == "nil"     then log("table is nil")
            elseif type(t) == "string"  then log('table is string: "'..t..'"')
            elseif type(t) == "number"  then log('table is number: '..t)
            elseif type(t) == "table"   then
                local elementsInTable = 0
                for k,v in pairs(t) do
                    if  type (v) == "table" then
                        if type(k) == "string" then
                            log(tab..'table: "'..k..'"')
                        else
                            log(tab..'table: '..k)
                        end
                        tab = tab .. "    "
                        table.show(v)
                        tab = string.sub(tab, 1, -5)
                        elementsInTable = elementsInTable + 1
                    else
                        elementsInTable = elementsInTable + 1
                        if type(v) == "string" then v = '"'..v..'"' end
                        if type(k) == "string" then k = '"'..k..'"' end
                        log(tab..""..k.." = "..v)
                    end
                end
                if elementsInTable == 0 then log("table is empty") end
            else
                log('table is unknow data type')
            end
            -- Пишем в лог комментарий.
            deep = deep - 1 -- Уровень вложенности вызовов функции.
        end
    end
    ]]

    local function deepcopy(orig)
        local orig_type = type(orig)
        local copy
        if orig_type == 'table' then
            copy = {}
            for orig_key, orig_value in next, orig, nil do
                copy[deepcopy(orig_key)] = deepcopy(orig_value)
            end
            setmetatable(copy, deepcopy(getmetatable(orig)))
        else -- number, string, boolean, etc
            copy = orig
        end
        return copy
    end

    -- Символы для поиска.
    -- Возможно указать в двух вариантах синтаксиса: упрощенном и полном.
    -- Упрощенный синтаксис:
    -- В упрощенном варианте синтаксиса допускается не указывать
    -- соответствие имен файлов и строке/символу,
    -- который они обозначают: считается, что они идентичны.
    -- Пример упрощенного синтаксиса:
    -- local symbols = {"0", "1", "2", "3", "a", "b", "c", "test"}
    -- Полный синтаксис:
    -- Полный синтаксис бывает необходим при использовании
    -- нескольких изображений соответсвующих одной и той же строке/символу.
    -- Допускаются переносы строк:
    -- local symbols = {
    --       ["0"] = {"zero1", "zero2"},
    --       ["1"] = {"1a", "1b"},
    --       ["2"] = {"two", "second"}
    --      }
    -- Оба варианта синтаксиса можно сочетать:
    -- local symbols = {"0", "1", ["2"] = {"two", "second"}, "3"}


    local default = {}
    default.crds         = {0, 0, 1920, 1080} -- Координаты поиска
    default.path         = "c:\\image"        -- Папка с картинками
    default.ext          = ".bmp"             -- Расширение картинок
    default.loadFolder   = nil                -- Путь по которому будут загружены все изображения с указанной маской {path=путь, mask=маска, sub=1|0}(sub - подпапки). Имя файла будет соответсвовать имени символа.
    default.deltaY       = 8                  -- Расстояние между строками (можно указать высоту картинок)
    default.deltaSpace   = 2                  -- Допустимое расстояние между цифрами, иначе будет считаться что это не одно число
    default.accuracy     = 95                 -- Точность поиска для Findimage
    default.deviation    = 3                  -- Погрешность оттенка  для Findimage
    default.wait         = 2                  -- Пауза между поиском картинок, если указать меньше искать будет быстрее, но нагрузит процессор
    default.timeProc     = 2                  -- Время в секундах (может быть не целым) для поиска картинок, если -1 не выйдет из процедуры пока не найдётся хотя бы 1 картинка
    default.repeatImage  = 2                  -- Допустимое смещение координат, если используется несколько видов одной картинки
    default.window       = "workwindow"       -- Метод|хендл_окна в котором происходит поиск (если указан источник изображения(source), то параметр будет проигнорирован)
    default.abs          = 0                  -- Использовать abs координаты.
    default.source       = nil                -- Изображение в котором производится поиск. Должен быть задан таблицей {адрес, ширина, высота}, nil вместо таблицы приведет к захвату изображения с экрана.
    default.bufferAddNew = 1                  -- Добавлять изображения в буфер
    default.bufferIgnore = 0                  -- Игнорировать изображения находящиеся в буфере
    default.bufferUpdate = 0                  -- Обновить изображения содержащиеся в буфере.
    default.secondFrame  = 0                  -- Ожидание прогрузки значений. Изображение будет проанализировано только после secondFrame секунд с первой успешной попытки считать любое из избражений.
    default.saveImage    = nil                -- Путь по которому будет сохранено изображение в котором происходит поиск.
    -- набор стандартных символов
    default.symbols      = {["0"]={"0"}, ["1"]={"1"}, ["2"]={"2"}, ["3"]={"3"}, ["4"]={"4"}, ["5"]={"5"}, ["6"]={"6"}, ["7"]={"7"}, ["8"]={"8"}, ["9"]={"9"}}


    -- Буфер
    -- Буфер
    -- Буфер

    local buffer = {} -- Массив с загруженными картинками.
    imageToStringBuffer = {} -- набор функций по управлению буфером.
    -- Полностью очищаем массив.
    function imageToStringBuffer.flush()
        for k,_ in pairs(buffer) do buffer[v] = nil end
    end
    -- Удаляем элемент из буфера
    function imageToStringBuffer.flush(element)
        buffer[element] = nil
    end
    -- Добавляем изображение в буфер
    function imageToStringBuffer.flush(element, val)
        buffer[element] = val
    end
    -- Читаем изображение из буфера
    function imageToStringBuffer.flush(element)
        return buffer[element]
    end


    -- Поиск
    -- Поиск
    -- Поиск

    function imageToString(options)

        -- Проверяем переданные параметры. Если они отсутствуют - подставляем параметры по умолчанию.
        if  options              == nil then local options        = {}                    end
        if  options.crds         == nil then options.crds         = default.crds          end
        if  options.path         == nil then options.path         = default.path          end
        if  options.ext          == nil then options.ext          = default.ext           end
        if  options.loadFolder   == nil then options.loadFolder   = default.loadFolder    end
        if  options.deltaY       == nil then options.deltaY       = default.deltaY        end
        if  options.deltaSpace   == nil then options.deltaSpace   = default.deltaSpace    end
        if  options.accuracy     == nil then options.accuracy     = default.accuracy      end
        if  options.deviation    == nil then options.deviation    = default.deviation     end
        if  options.wait         == nil then options.wait         = default.wait          end
        if  options.timeProc     == nil then options.timeProc     = default.timeProc      end
        if  options.repeatImage  == nil then options.repeatImage  = default.repeatImage   end
        if  options.window       == nil then options.window       = default.window        end
        if  options.abs          == nil then options.abs          = default.abs           end
        if  options.source       == nil then options.source       = default.source        end
        if  options.bufferAddNew == nil then options.bufferAddNew = default.bufferAddNew  end
        if  options.bufferIgnore == nil then options.bufferIgnore = default.bufferIgnore  end
        if  options.bufferUpdate == nil then options.bufferUpdate = default.bufferUpdate  end
        if  options.secondFrame  == nil then options.secondFrame  = default.secondFrame   end
        if  options.saveImage    == nil then options.saveImage    = default.saveImage     end
        if  options.symbols      == nil then
            if  options.loadFolder   == nil then
                options.symbols = deepcopy(default.symbols)
            else
                options.symbols = {}
            end
        end

        --Добавляем при необходимости обратный слэш в путь.
        if  string.sub(options.path, -1) ~= "\\" then options.path = options.path .. "\\" end

        -- Папка для загрузки изображений не задана, загружаем обычным методом.
        if  options.loadFolder == nil then
            -- Преобразуем урощенный синтаксис в полноценный, преобразуем пути в полные.
            do
                local tmp = {} --Массив в который временно помещаются преобразованные данные.
                for symbolName, imageName in pairs(options.symbols) do
                    -- Если занчение задано строкой/числом, приводим его к таблице, дописываем путь до полного.
                    if  type(options.symbols[symbolName]) == "number" then
                        options.symbols[symbolName] = {options.path..tostring(imageName)..options.ext}
                    elseif  type(options.symbols[symbolName]) == "string" then
                        options.symbols[symbolName] = {options.path..imageName..options.ext}
                    --  Значение задано таблицей, преобразоываем числа в строки, дописываем путь до полного.
                    elseif  type(options.symbols[symbolName]) == "table" then
                        for n=1, #options.symbols[symbolName] do
                            if  type(options.symbols[symbolName][n]) == "number" then
                                options.symbols[symbolName][n] = options.path..tostring(options.symbols[symbolName][n])..options.ext
                            elseif  type(options.symbols[symbolName][n]) == "string" then
                                options.symbols[symbolName][n] = options.path..options.symbols[symbolName][n]..options.ext
                            else
                                msg ("Ошибочный тип значения картинок символов в таблице. Остановка скрипта")
                                stop_script()
                            end
                        end
                    else
                        msg ("Ошибочный тип значения картинок символов. Остановка скрипта")
                        stop_script()
                    end

                    -- Если ключ цифровой, преобразуем к строке
                    if  type(symbolName) == "number" then
                        tmp[tostring(symbolName)] = options.symbols[symbolName]
                    elseif  type(symbolName) == "string" then
                        tmp[symbolName] = options.symbols[symbolName]
                    else
                        msg ("Ошибочный тип ключа символов. Остановка скрипта")
                        stop_script()
                    end
                end
                options.symbols = tmp
            end
        else
            -- Загружаем папку с изображениями.
            -- Имя файла = имя символа.
            -- Допускается несколько одинаковых символов в различных подпапках.
            -- Приводим к понятному для пилота виду флаг чтение подпапок.

            -- Прилепляем кавычки к пути чтобы пилот не путал путь и маску.
            options.loadFolder.path = '"'..options.loadFolder.path..'"'
            if options.loadFolder.sub == 1 then options.loadFolder.sub = nil else options.loadFolder.sub = "norecursion" end
            -- Приводим маску к надлежащему виду, если она не задана.
            if options.loadFolder.mask == nil then options.loadFolder.mask = "*" end
            fileList = dir(options.loadFolder.path, options.loadFolder.mask, options.loadFolder.sub)
            --table.show(fileList, "fileList")
            for k, v in pairs (fileList) do
                -- символ уже существует (несколько вариантов изображения)
                if  options.symbols[v[3]] ~= nil then
                    table.insert(options.symbols[v[3]], v[1])
                else
                    options.symbols[v[3]] = {v[1]}
                end
            end
        end
        --table.show(options.symbols)


        -- Приводим options.abs к виду пригодному для финдимиджа.
        if      options.abs == 1 then options.abs = "abs"
        elseif  options.abs == 0 then options.abs = ""
        end


        -- Загрузка картинок
        local images={}     --Загружает в память изображения {имя символа, {адреса в памяти}}
        local loadError = 0
        for symbolName, fileList in pairs(options.symbols) do
            images[symbolName] = {}
            for i=1, #fileList, 1 do
                -- Загружен ли файл в буфер, если нет, то подгружаем.
                local filePath = fileList[i]
                if  options.bufferIgnore == 0 and options.bufferUpdate == 0 and buffer[filePath] ~= nil then
                    images[symbolName][i] = buffer[filePath]
                else
                    -- В буфере изображения нет, загружаем с диска.
                    --log(filePath.."В буфере изображения нет, загружаем с диска.")
                    images[symbolName][i] = loadimage(filePath)
                    -- Обновляем загруженное в буфер изображение
                    if  buffer[filePath] ~= nil then
                        deleteimage(buffer[filePath])
                        buffer[filePath] =  images[symbolName][i]
                    elseif options.bufferAddNew == 1 and options.bufferIgnore == 0 then
                        -- Добавляем в буфер новое изображение.
                        buffer[filePath] = images[symbolName][i]
                    end
                end
                -- Поиск ошибок загрузки.
                if images[symbolName][i] < 0  then
                    loadError = loadError + 1
                    log("Image loading fail. Error file: "..filePath..'.')
                end
            end
        end
        -- При загрузке изображений произошли ошибки. Останавливаем скрипт.
        if  loadError > 0 then
            log("Error loading count: "..loadError..'.')
            stop_script()
        end
        if  images == nil then
            log("Файлы изображений не найдены. Скрипт остановлен.")
            stop_script()
        end
        --table.show(images,"images")


        local timeout = os.clock() + options.timeProc


        -- log(options.secondFrame)
        -- Таймаут на прогрузку. Поиск для детекта изображений.
        if options.secondFrame > 0 then
            -- Создаем карман области видимости.
            -- Реузльататы блока не нужны для остального скрипта.
            do
                local catch = 0
                -- Если вермя ожидания после детекта не уложится в общий
                -- таймаут, то выходим из цикла без дальшейших попыток найти изображение.
                local secondFrameTimeout = timeout - options.secondFrame
                while true do -- выход внутри цикла  timeout < os.clock()
                    local screenshot, width, height = nil, nil, nil
                    if  options.source == nil then
                        screenshot, width, height = getimage(options.crds[1],options.crds[2],options.crds[3],options.crds[4], options.window)
                    else
                        screenshot, width, height = options.source[1],options.source[2],options.source[3]
                    end
                    for symbolName, imageAddressArray in pairs(images) do
                        for _, imageAddress in pairs(imageAddressArray) do
                            local tmp = {}
                            findResult = findimage(
                                0 .. " " .. 0 .. " " ..
                                width .. " " .. height .. " " ..
                                "(" .. imageAddress .. ") " ..
                                "%tmp " .. screenshot .. " " .. options.accuracy .. " -1 " .. options.deviation .. " " .. options.abs)
                            --log("symoblName: ".. symbolName .. " findResult: " .. findResult)
                            -- проверяем на возрват нуля или ошбики, со стрингом нормально не сравнить.
                            if  findResult ~= "0" and not string.find(findResult, "-") then
                                catch = 1
                                --log("break")
                                wait(math.floor(options.secondFrame * 1000))
                                break
                            end
                            -- Время на всю функцию истекло
                            if  secondFrameTimeout < os.clock() and options.timeProc ~= -1 then
                                return
                            end
                        end
                        if catch == 1 then break end
                    end
                    if catch == 1 then break end
                end
            end
        end


        -- Ищем изображения
        local crdsRaw={} -- Массив со всеми найденными изображениями, возможны дубли, не сортированный.
        repeat  -- Повторяем пока что-то не найдем или не выйдет время на поиск (options.timeProc).
            -- Получаем изображение с экрана, если источник не указан.
            local screenshot, width, height = nil
            if  options.source == nil then
                screenshot, width, height = getimage(options.crds[1],options.crds[2],options.crds[3],options.crds[4], options.window)
            else
                screenshot, width, height = options.source[1],options.source[2],options.source[3]
            end
            --log(screenshot)
            for symbolName, imageAddressArray in pairs(images) do
                for _, imageAddress in pairs(imageAddressArray) do
                    tmp = {}
                    findResult = findimage(
                        0 .. " " .. 0 .. " " ..
                        width .. " " .. height .. " " ..
                        "(" .. imageAddress .. ") " ..
                        "%tmp " .. screenshot .. " " .. options.accuracy .. " -1 " .. options.deviation .. " " .. options.abs)
                    --log("symoblName: ".. symbolName .. " findResult: " .. findResult)
                    -- проверяем на возрват нуля или ошбики, со стрингом нормально не сравнить.
                    if  findResult ~= "0" and not string.find(findResult, "-") then
                        -- Добавляем найденные значения в общий результат поисков.
                        --table.show(tmp,"tmp")
                        for i = 1, #tmp, 1 do
                            -- Напрямую вернуть таблицу в функцию нельзя из-за синтаксиса.
                            -- FIX. Нужен фикс функции findimage пилота (возвращает координаты стрингом)
                            -- после фикса просто удалить "tonumber(parm)" оставив parm.
                            table.insert(crdsRaw,{x=tonumber(tmp[i][1]),y=tonumber(tmp[i][2]),xEnd=tonumber(tmp[i][3]),symbolName=symbolName})
                        end
                    end
                end
            end

            -- Сохраняем изображение.
            if  options.saveImage ~= nil then
                saveimage(screenshot, options.saveImage)
            end
            -- Удаляем изображение, если получали его из приложения.
            if  options.source == nil then
                deleteimage(screenshot)
            end

            --table.show(images, "images")
            --log (#crdsRaw, timeout, os.clock(), options.timeProc)
            --log ("until")
            local clock = os.clock()
        until not ((#crdsRaw == 0) and (timeout > clock or options.timeProc == -1))
        --table.show(crdsRaw, "crdsRaw")

        --  Изображения не были найдены, выходим из поиска.
        if  #crdsRaw < 1 then
            return nil
        end
        -- Удаляем дубли.
        local crdsClear={} -- Массив без дублей.
        for i=1, #crdsRaw, 1 do
            local catch = 0 -- Флаг найденного дубля.
            for n=i+1, #crdsRaw, 1 do
                --log(
                --  crdsRaw[i].symbolName.." == "..crdsRaw[n].symbolName.." and "..
                --  math.abs(crdsRaw[i].x - crdsRaw[n].x).." <= "..options.repeatImage.." and "..
                --  math.abs(crdsRaw[i].y - crdsRaw[n].y).." <= "..options.repeatImage
                --)
                if  crdsRaw[i].symbolName == crdsRaw[n].symbolName and
                  math.abs(crdsRaw[i].x - crdsRaw[n].x) <= options.repeatImage and
                  math.abs(crdsRaw[i].y - crdsRaw[n].y) <= options.repeatImage then
                    catch = 1
                    break
                end
            end
            --log(catch)
            if  catch == 0 then -- не дубль, копируем значение в чистый массив.
                table.insert(crdsClear,crdsRaw[i])
            end
        end

        -- Сортируем элементы.
        -- Сортировка происходит, как по X координате,
        -- так и по Y учитывая возможность нескольких строк.
        -- Межстрочный интервал задается с помощью options.deltaY.
        -- Для уплотнения поиска options.deltaY может быть отрицательным.
        -- Отрицательный options.deltaY в первую очередь необходим,
        -- если изображения символов содержат сверху и снизу от символа фон.
        -- crdsClear был предварительно очищен от дублей, теперь сортируется.

        --table.show(crdsClear,"crdsClear")
        --table.toInit(crdsClear)
        table.sort(crdsClear,
            function(a,b)
                if  math.abs(a.y - b.y) <= options.deltaY then
                    if  a.x < b.x then
                        return true
                    else
                        return false
                    end
                else
                    if a.y < b.y then
                        return true
                    else
                        return false
                    end
                end
            end
        )
        --table.show(crdsClear,"crdsClear")

        -- Собираем строку
        --log(#crdsClear)
        local result = {{crdsClear[1].symbolName}}
        local resultX, resultY = 1, 1
        for i=2, #crdsClear, 1 do
            -- Добавляем перенос и символ, возрващем каретку.
            if  crdsClear[i-1].y  + options.deltaY < crdsClear[i].y then
                resultX = resultX + 1
                resultY = 1 -- возврат картеки
                result[resultX]={crdsClear[i].symbolName}
            -- Добавляем пробел и символ
            elseif crdsClear[i-1].xEnd  + options.deltaSpace < crdsClear[i].x then
                resultY = resultY + 1
                result[resultX][resultY] = crdsClear[i].symbolName
            -- Добавляем символ
            else
                result[resultX][resultY] = result[resultX][resultY].. crdsClear[i].symbolName
            end
            --table.show(result,"result")
        end
        --table.show(result,"result")
        return result
    end
end

Автор: cirus 27.9.2017, 3:48

Цитата
При втором вызове функции массив с картинками пуст.

Если используется default.path нормально стало. Для default.loadFolder тоже ведь надо.

Автор: DarkMaster 27.9.2017, 13:13

Цитата
Для default.loadFolder тоже ведь надо.

Эмм... там же nil вроде как, что исключает вообще какое-либо копирование. Ну сейчас на всех массивах проставлю.

Распознавание текста Lua
Код
-- Автор скрипта DarkMaster.
-- Написано по мотивам скрипта Cirus.
-- Тестирование Cirus.
-- Вопросы, баги, предложения на форум
-- в специальную тему по этому скрипту
-- https://forum.uokit.com/index.php?showtopic=30000

-- Фикс: символы по умолчанию больше не переписываются, сделано корректное копирование массива.

-- Фикс: флаг чтения подпапок был инвертирован.
-- Фикс: secondFrameTimeout больше не глобальная и используется по назначению.
-- Фикс: При default.timeProc = -1 и default.secondFrame > 0 не выходит преждевременно из функции.
-- Фикс: Почистил отладочные выводы в лог.
-- Добавлено сохранение изображение в котором происходил поиск.

-- Баг:  из-за особенностей костыля финдимиджа создается НЕ локальня переменная tmp.
-- Фикс: изображение не добавлялось в буфер.
-- Фикс: расчет пробела от конечной х координаты.
-- Фикс: очистка буфера после захвата изображения.
-- Фикс: область поиска при источнике из getimage должна быть с нуля.
-- Фикс: искалось только одно изображение из-за недостающего вложенного цикла.
-- Фикс: буфер теперь действительно буферезует.
-- Переработно преобразование из упрощенного синтаксиса в полнеценный. Добавлена защита от дурка (типы данных).
-- Добавлено: загрузка папки с изображениями.
-- Добавлено: ожидание прогрузки изображений (options.secondFrame).
-- Добавлено: чтение из буфера.

do

-- Раскомментировать, если в отладке будет использоват table.show.
--[[do
    local tab = ""
    local deep = 0
    function table.show(t, comment)
        -- Пишем в лог комментарий.
        deep = deep + 1 -- Уровень вложенности вызовов функции.
        --log(comment .. commentSended .. deep)
        if  comment ~= nil and deep == 1 then
            log(comment)
        end


        if     type(t) == "nil"     then log("table is nil")
        elseif type(t) == "string"  then log('table is string: "'..t..'"')
        elseif type(t) == "number"  then log('table is number: '..t)
        elseif type(t) == "table"   then
            local elementsInTable = 0
            for k,v in pairs(t) do
                if  type (v) == "table" then
                    if type(k) == "string" then
                        log(tab..'table: "'..k..'"')
                    else
                        log(tab..'table: '..k)
                    end
                    tab = tab .. "    "
                    table.show(v)
                    tab = string.sub(tab, 1, -5)
                    elementsInTable = elementsInTable + 1
                else
                    elementsInTable = elementsInTable + 1
                    if type(v) == "string" then v = '"'..v..'"' end
                    if type(k) == "string" then k = '"'..k..'"' end
                    log(tab..""..k.." = "..v)
                end
            end
            if elementsInTable == 0 then log("table is empty") end
        else
            log('table is unknow data type')
        end
        -- Пишем в лог комментарий.
        deep = deep - 1 -- Уровень вложенности вызовов функции.
    end
end
]]

function dc(orig)
    local orig_type = type(orig)
    local copy
    if orig_type == 'table' then
        copy = {}
        for orig_key, orig_value in next, orig, nil do
            copy[dc(orig_key)] = dc(orig_value)
        end
        setmetatable(copy, dc(getmetatable(orig)))
    else -- number, string, boolean, etc
        copy = orig
    end
    return copy
end

    -- Символы для поиска.
    -- Возможно указать в двух вариантах синтаксиса: упрощенном и полном.
    -- Упрощенный синтаксис:
    -- В упрощенном варианте синтаксиса допускается не указывать
    -- соответствие имен файлов и строке/символу,
    -- который они обозначают: считается, что они идентичны.
    -- Пример упрощенного синтаксиса:
    -- local symbols = {"0", "1", "2", "3", "a", "b", "c", "test"}
    -- Полный синтаксис:
    -- Полный синтаксис бывает необходим при использовании
    -- нескольких изображений соответсвующих одной и той же строке/символу.
    -- Допускаются переносы строк:
    -- local symbols = {
    --       ["0"] = {"zero1", "zero2"},
    --       ["1"] = {"1a", "1b"},
    --       ["2"] = {"two", "second"}
    --      }
    -- Оба варианта синтаксиса можно сочетать:
    -- local symbols = {"0", "1", ["2"] = {"two", "second"}, "3"}


    local default = {}
    default.crds         = {0, 0, 1920, 1080} -- Координаты поиска
    default.path         = "c:\\image"        -- Папка с картинками
    default.ext          = ".bmp"             -- Расширение картинок
    default.loadFolder   = nil                -- Путь по которому будут загружены все изображения с указанной маской {path=путь, mask=маска, sub=1|0}(sub - подпапки). Имя файла будет соответсвовать имени символа.
    default.deltaY       = 8                  -- Расстояние между строками (можно указать высоту картинок)
    default.deltaSpace   = 2                  -- Допустимое расстояние между цифрами, иначе будет считаться что это не одно число
    default.accuracy     = 95                 -- Точность поиска для Findimage
    default.deviation    = 3                  -- Погрешность оттенка  для Findimage
    default.wait         = 2                  -- Пауза между поиском картинок, если указать меньше искать будет быстрее, но нагрузит процессор
    default.timeProc     = 2                  -- Время в секундах (может быть не целым) для поиска картинок, если -1 не выйдет из процедуры пока не найдётся хотя бы 1 картинка
    default.repeatImage  = 2                  -- Допустимое смещение координат, если используется несколько видов одной картинки
    default.window       = "workwindow"       -- Метод|хендл_окна в котором происходит поиск (если указан источник изображения(source), то параметр будет проигнорирован)
    default.abs          = 0                  -- Использовать abs координаты.
    default.source       = nil                -- Изображение в котором производится поиск. Должен быть задан таблицей {адрес, ширина, высота}, nil вместо таблицы приведет к захвату изображения с экрана.
    default.bufferAddNew = 1                  -- Добавлять изображения в буфер
    default.bufferIgnore = 0                  -- Игнорировать изображения находящиеся в буфере
    default.bufferUpdate = 0                  -- Обновить изображения содержащиеся в буфере.
    default.secondFrame  = 0                  -- Ожидание прогрузки значений. Изображение будет проанализировано только после secondFrame секунд с первой успешной попытки считать любое из избражений.
    default.saveImage    = nil                -- Путь по которому будет сохранено изображение в котором происходит поиск.
    -- набор стандартных символов
    default.symbols      = {["0"]={"0"}, ["1"]={"1"}, ["2"]={"2"}, ["3"]={"3"}, ["4"]={"4"}, ["5"]={"5"}, ["6"]={"6"}, ["7"]={"7"}, ["8"]={"8"}, ["9"]={"9"}}


    -- Буфер
    -- Буфер
    -- Буфер

    local buffer = {} -- Массив с загруженными картинками.
    imageToStringBuffer = {} -- набор функций по управлению буфером.
    -- Полностью очищаем массив.
    function imageToStringBuffer.flush()
        for k,_ in pairs(buffer) do buffer[v] = nil end
    end
    -- Удаляем элемент из буфера
    function imageToStringBuffer.flush(element)
        buffer[element] = nil
    end
    -- Добавляем изображение в буфер
    function imageToStringBuffer.flush(element, val)
        buffer[element] = val
    end
    -- Читаем изображение из буфера
    function imageToStringBuffer.flush(element)
        return buffer[element]
    end


    -- Поиск
    -- Поиск
    -- Поиск

    function imageToString(options)

        -- Проверяем переданные параметры. Если они отсутствуют - подставляем параметры по умолчанию.
        if  options              == nil then local options        = {}                     end
        if  options.crds         == nil then options.crds         = default.crds           end
        if  options.path         == nil then options.path         = default.path           end
        if  options.ext          == nil then options.ext          = default.ext            end
        if  options.loadFolder   == nil then options.loadFolder   = dc(default.loadFolder) end
        if  options.deltaY       == nil then options.deltaY       = default.deltaY         end
        if  options.deltaSpace   == nil then options.deltaSpace   = default.deltaSpace     end
        if  options.accuracy     == nil then options.accuracy     = default.accuracy       end
        if  options.deviation    == nil then options.deviation    = default.deviation      end
        if  options.wait         == nil then options.wait         = default.wait           end
        if  options.timeProc     == nil then options.timeProc     = default.timeProc       end
        if  options.repeatImage  == nil then options.repeatImage  = default.repeatImage    end
        if  options.window       == nil then options.window       = default.window         end
        if  options.abs          == nil then options.abs          = default.abs            end
        if  options.source       == nil then options.source       = dc(default.source)     end
        if  options.bufferAddNew == nil then options.bufferAddNew = default.bufferAddNew   end
        if  options.bufferIgnore == nil then options.bufferIgnore = default.bufferIgnore   end
        if  options.bufferUpdate == nil then options.bufferUpdate = default.bufferUpdate   end
        if  options.secondFrame  == nil then options.secondFrame  = default.secondFrame    end
        if  options.saveImage    == nil then options.saveImage    = default.saveImage      end
        if  options.symbols      == nil then
            if  options.loadFolder   == nil then
                options.symbols = dc(default.symbols)
            else
                options.symbols = {}
            end
        end

        --Добавляем при необходимости обратный слэш в путь.
        if  string.sub(options.path, -1) ~= "\\" then options.path = options.path .. "\\" end

        -- Папка для загрузки изображений не задана, загружаем обычным методом.
        if  options.loadFolder == nil then
            -- Преобразуем урощенный синтаксис в полноценный, преобразуем пути в полные.
            do
                local tmp = {} --Массив в который временно помещаются преобразованные данные.
                for symbolName, imageName in pairs(options.symbols) do
                    -- Если занчение задано строкой/числом, приводим его к таблице, дописываем путь до полного.
                    if  type(options.symbols[symbolName]) == "number" then
                        options.symbols[symbolName] = {options.path..tostring(imageName)..options.ext}
                    elseif  type(options.symbols[symbolName]) == "string" then
                        options.symbols[symbolName] = {options.path..imageName..options.ext}
                    --  Значение задано таблицей, преобразоываем числа в строки, дописываем путь до полного.
                    elseif  type(options.symbols[symbolName]) == "table" then
                        for n=1, #options.symbols[symbolName] do
                            if  type(options.symbols[symbolName][n]) == "number" then
                                options.symbols[symbolName][n] = options.path..tostring(options.symbols[symbolName][n])..options.ext
                            elseif  type(options.symbols[symbolName][n]) == "string" then
                                options.symbols[symbolName][n] = options.path..options.symbols[symbolName][n]..options.ext
                            else
                                msg ("Ошибочный тип значения картинок символов в таблице. Остановка скрипта")
                                stop_script()
                            end
                        end
                    else
                        msg ("Ошибочный тип значения картинок символов. Остановка скрипта")
                        stop_script()
                    end

                    -- Если ключ цифровой, преобразуем к строке
                    if  type(symbolName) == "number" then
                        tmp[tostring(symbolName)] = options.symbols[symbolName]
                    elseif  type(symbolName) == "string" then
                        tmp[symbolName] = options.symbols[symbolName]
                    else
                        msg ("Ошибочный тип ключа символов. Остановка скрипта")
                        stop_script()
                    end
                end
                options.symbols = tmp
            end
        else
            -- Загружаем папку с изображениями.
            -- Имя файла = имя символа.
            -- Допускается несколько одинаковых символов в различных подпапках.
            -- Приводим к понятному для пилота виду флаг чтение подпапок.

            -- Прилепляем кавычки к пути чтобы пилот не путал путь и маску.
            options.loadFolder.path = '"'..options.loadFolder.path..'"'
            if options.loadFolder.sub == 1 then options.loadFolder.sub = nil else options.loadFolder.sub = "norecursion" end
            -- Приводим маску к надлежащему виду, если она не задана.
            if options.loadFolder.mask == nil then options.loadFolder.mask = "*" end
            fileList = dir(options.loadFolder.path, options.loadFolder.mask, options.loadFolder.sub)
            --table.show(fileList, "fileList")
            for k, v in pairs (fileList) do
                -- символ уже существует (несколько вариантов изображения)
                if  options.symbols[v[3]] ~= nil then
                    table.insert(options.symbols[v[3]], v[1])
                else
                    options.symbols[v[3]] = {v[1]}
                end
            end
        end
        --table.show(options.symbols)


        -- Приводим options.abs к виду пригодному для финдимиджа.
        if      options.abs == 1 then options.abs = "abs"
        elseif  options.abs == 0 then options.abs = ""
        end


        -- Загрузка картинок
        local images={}     --Загружает в память изображения {имя символа, {адреса в памяти}}
        local loadError = 0
        for symbolName, fileList in pairs(options.symbols) do
            images[symbolName] = {}
            for i=1, #fileList, 1 do
                -- Загружен ли файл в буфер, если нет, то подгружаем.
                local filePath = fileList[i]
                if  options.bufferIgnore == 0 and options.bufferUpdate == 0 and buffer[filePath] ~= nil then
                    images[symbolName][i] = buffer[filePath]
                else
                    -- В буфере изображения нет, загружаем с диска.
                    --log(filePath.."В буфере изображения нет, загружаем с диска.")
                    images[symbolName][i] = loadimage(filePath)
                    -- Обновляем загруженное в буфер изображение
                    if  buffer[filePath] ~= nil then
                        deleteimage(buffer[filePath])
                        buffer[filePath] =  images[symbolName][i]
                    elseif options.bufferAddNew == 1 and options.bufferIgnore == 0 then
                        -- Добавляем в буфер новое изображение.
                        buffer[filePath] = images[symbolName][i]
                    end
                end
                -- Поиск ошибок загрузки.
                if images[symbolName][i] < 0  then
                    loadError = loadError + 1
                    log("Image loading fail. Error file: "..filePath..'.')
                end
            end
        end
        -- При загрузке изображений произошли ошибки. Останавливаем скрипт.
        if  loadError > 0 then
            log("Error loading count: "..loadError..'.')
            stop_script()
        end
        if  images == nil then
            log("Файлы изображений не найдены. Скрипт остановлен.")
            stop_script()
        end
        --table.show(images,"images")


        local timeout = os.clock() + options.timeProc


        -- log(options.secondFrame)
        -- Таймаут на прогрузку. Поиск для детекта изображений.
        if options.secondFrame > 0 then
            -- Создаем карман области видимости.
            -- Реузльататы блока не нужны для остального скрипта.
            do
                local catch = 0
                -- Если вермя ожидания после детекта не уложится в общий
                -- таймаут, то выходим из цикла без дальшейших попыток найти изображение.
                local secondFrameTimeout = timeout - options.secondFrame
                while true do -- выход внутри цикла  timeout < os.clock()
                    local screenshot, width, height = nil, nil, nil
                    if  options.source == nil then
                        screenshot, width, height = getimage(options.crds[1],options.crds[2],options.crds[3],options.crds[4], options.window)
                    else
                        screenshot, width, height = options.source[1],options.source[2],options.source[3]
                    end
                    for symbolName, imageAddressArray in pairs(images) do
                        for _, imageAddress in pairs(imageAddressArray) do
                            local tmp = {}
                            findResult = findimage(
                                0 .. " " .. 0 .. " " ..
                                width .. " " .. height .. " " ..
                                "(" .. imageAddress .. ") " ..
                                "%tmp " .. screenshot .. " " .. options.accuracy .. " -1 " .. options.deviation .. " " .. options.abs)
                            --log("symoblName: ".. symbolName .. " findResult: " .. findResult)
                            -- проверяем на возрват нуля или ошбики, со стрингом нормально не сравнить.
                            if  findResult ~= "0" and not string.find(findResult, "-") then
                                catch = 1
                                --log("break")
                                wait(math.floor(options.secondFrame * 1000))
                                break
                            end
                            -- Время на всю функцию истекло
                            if  secondFrameTimeout < os.clock() and options.timeProc ~= -1 then
                                return
                            end
                        end
                        if catch == 1 then break end
                    end
                    if catch == 1 then break end
                end
            end
        end


        -- Ищем изображения
        local crdsRaw={} -- Массив со всеми найденными изображениями, возможны дубли, не сортированный.
        repeat  -- Повторяем пока что-то не найдем или не выйдет время на поиск (options.timeProc).
            -- Получаем изображение с экрана, если источник не указан.
            local screenshot, width, height = nil
            if  options.source == nil then
                screenshot, width, height = getimage(options.crds[1],options.crds[2],options.crds[3],options.crds[4], options.window)
            else
                screenshot, width, height = options.source[1],options.source[2],options.source[3]
            end
            --log(screenshot)
            for symbolName, imageAddressArray in pairs(images) do
                for _, imageAddress in pairs(imageAddressArray) do
                    tmp = {}
                    findResult = findimage(
                        0 .. " " .. 0 .. " " ..
                        width .. " " .. height .. " " ..
                        "(" .. imageAddress .. ") " ..
                        "%tmp " .. screenshot .. " " .. options.accuracy .. " -1 " .. options.deviation .. " " .. options.abs)
                    --log("symoblName: ".. symbolName .. " findResult: " .. findResult)
                    -- проверяем на возрват нуля или ошбики, со стрингом нормально не сравнить.
                    if  findResult ~= "0" and not string.find(findResult, "-") then
                        -- Добавляем найденные значения в общий результат поисков.
                        --table.show(tmp,"tmp")
                        for i = 1, #tmp, 1 do
                            -- Напрямую вернуть таблицу в функцию нельзя из-за синтаксиса.
                            -- FIX. Нужен фикс функции findimage пилота (возвращает координаты стрингом)
                            -- после фикса просто удалить "tonumber(parm)" оставив parm.
                            table.insert(crdsRaw,{x=tonumber(tmp[i][1]),y=tonumber(tmp[i][2]),xEnd=tonumber(tmp[i][3]),symbolName=symbolName})
                        end
                    end
                end
            end

            -- Сохраняем изображение.
            if  options.saveImage ~= nil then
                saveimage(screenshot, options.saveImage)
            end
            -- Удаляем изображение, если получали его из приложения.
            if  options.source == nil then
                deleteimage(screenshot)
            end

            --table.show(images, "images")
            --log (#crdsRaw, timeout, os.clock(), options.timeProc)
            --log ("until")
            local clock = os.clock()
        until not ((#crdsRaw == 0) and (timeout > clock or options.timeProc == -1))
        --table.show(crdsRaw, "crdsRaw")

        --  Изображения не были найдены, выходим из поиска.
        if  #crdsRaw < 1 then
            return nil
        end
        -- Удаляем дубли.
        local crdsClear={} -- Массив без дублей.
        for i=1, #crdsRaw, 1 do
            local catch = 0 -- Флаг найденного дубля.
            for n=i+1, #crdsRaw, 1 do
                --log(
                --  crdsRaw[i].symbolName.." == "..crdsRaw[n].symbolName.." and "..
                --  math.abs(crdsRaw[i].x - crdsRaw[n].x).." <= "..options.repeatImage.." and "..
                --  math.abs(crdsRaw[i].y - crdsRaw[n].y).." <= "..options.repeatImage
                --)
                if  crdsRaw[i].symbolName == crdsRaw[n].symbolName and
                  math.abs(crdsRaw[i].x - crdsRaw[n].x) <= options.repeatImage and
                  math.abs(crdsRaw[i].y - crdsRaw[n].y) <= options.repeatImage then
                    catch = 1
                    break
                end
            end
            --log(catch)
            if  catch == 0 then -- не дубль, копируем значение в чистый массив.
                table.insert(crdsClear,crdsRaw[i])
            end
        end

        -- Сортируем элементы.
        -- Сортировка происходит, как по X координате,
        -- так и по Y учитывая возможность нескольких строк.
        -- Межстрочный интервал задается с помощью options.deltaY.
        -- Для уплотнения поиска options.deltaY может быть отрицательным.
        -- Отрицательный options.deltaY в первую очередь необходим,
        -- если изображения символов содержат сверху и снизу от символа фон.
        -- crdsClear был предварительно очищен от дублей, теперь сортируется.

        --table.show(crdsClear,"crdsClear")
        --table.toInit(crdsClear)
        table.sort(crdsClear,
            function(a,b)
                if  math.abs(a.y - b.y) <= options.deltaY then
                    if  a.x < b.x then
                        return true
                    else
                        return false
                    end
                else
                    if a.y < b.y then
                        return true
                    else
                        return false
                    end
                end
            end
        )
        --table.show(crdsClear,"crdsClear")

        -- Собираем строку
        --log(#crdsClear)
        local result = {{crdsClear[1].symbolName}}
        local resultX, resultY = 1, 1
        for i=2, #crdsClear, 1 do
            -- Добавляем перенос и символ, возрващем каретку.
            if  crdsClear[i-1].y  + options.deltaY < crdsClear[i].y then
                resultX = resultX + 1
                resultY = 1 -- возврат картеки
                result[resultX]={crdsClear[i].symbolName}
            -- Добавляем пробел и символ
            elseif crdsClear[i-1].xEnd  + options.deltaSpace < crdsClear[i].x then
                resultY = resultY + 1
                result[resultX][resultY] = crdsClear[i].symbolName
            -- Добавляем символ
            else
                result[resultX][resultY] = result[resultX][resultY].. crdsClear[i].symbolName
            end
            --table.show(result,"result")
        end
        --table.show(result,"result")
        return result
    end
end

Автор: cirus 27.9.2017, 13:19

Если так понятнее:

Код
result = imageToString{crds={33, 189, 292, 255},
                       loadFolder = {path="C:\\l2number3", mask="*bmp", sub=1}}

Автор: DarkMaster 27.9.2017, 13:27

Эмм? И как это может привести к перезаписи значений по умолчанию? Более того у меня два подобных вызова подряд стоят еще с прошлого теста (т.е. всего 4: два на символы, два на папки).

Вообще проблема была вызвана обработкой при которой синтаксис приводился к единообразию и это единообразие запихивалось в умлочание. С остальными таблицами этого даже представить не могу, т.к. их значения нигде не изменяются и ссылки там на самом деле достаточно. Даже если в умлочаниях вместо nil'ов что-то задать, то это не приведет как каким-то последствиям. Там весь скрипт общается с переданными параметрами только в режиме read-only. Исключение было в символах и это даже где-то ошибка проектирования ибо входящие параметры в моем понимании скорее не стоит изменять и проще завести новый массив под это дело, но проблему бы это не решило, т.к. все равно пришлось бы копирование прикручивать.

Автор: cirus 27.9.2017, 14:06

Цитата
Даже если в умлочаниях вместо nil'ов что-то задать, то это не приведет как каким-то последствиям.

Код
result = imageToString{crds={33, 189, 292, 255},
                       loadFolder = {path="C:\\l2number3", mask="*bmp", sub=1}}

Так нормально.
Я думал нет никакой разницы передать в качестве параметра или сразу задать по умолчанию
Код
default.loadFolder = {path="C:\\l2number3", mask="*bmp", sub=1}

Автор: DarkMaster 27.9.2017, 16:25

проблемы какие-то остались? копирование остальных массивов чем-то обусловлено кроме подозрений?

Автор: DarkMaster 27.9.2017, 22:27

Цитата
Я думал нет никакой разницы передать в качестве параметра или сразу задать по умолчанию

По сути ее и нет. Это был частный случай поскольку переданный параметр не только считывался для организации логики, но и преобразовывался (дописывался полный путь).

Автор: cirus 28.9.2017, 3:34

Цитата
проблемы какие-то остались?

Работает нормально, но ещё не всё успел потестить. Если что-то найдётся, то напишу.
Цитата
Раскомментировать, если в отладке будет использоват table.show.

Проще оставить не закомментированным.


Автор: DarkMaster 28.9.2017, 12:26

Цитата
Проще оставить не закомментированным.

Table системная библиотека, по сути я ее расширяю. Оставлено в первую очередь чтобы не затерялось. Я старался по минимуму оставлять что-либо видное снаружи, буфер бы тоже в какое-то пространство имен общее с основной функцией, но уж больно несуразно тогда выглядит вызов. Релизить буду предпоследнюю версию без лишних копирований массива.

Автор: DarkMaster 30.9.2017, 4:09

Данный скрипт предназначен для распознавания чисел, текста и различных символов (например, значков серебра, голда). Скрипт учитывает возможные пробелы и переносы строк. Параметры в квадратных [] скобках являются не обязательными, параметры в угловых скобках <> указываются всегда. Квадратные и фигурные скобки при вызове функций не пишутся, они лишь указывают возможность не задавать параметр. Фигурные {} и круглые () скобки пишутся, там где указаны. Символ '|' означает исключающее или, например, sub=0|1 означает, что значение sub может быть равно либо 0, либо 1.


Скрипт включает в себя следующие функции:

Код
--Получение текста из изображения:
t = imageToString.get({[parms],[parms],[parms],...})

--Управление буфером:
--Получение адреса в памяти загруженного в буфер изображения:
imageToString.buffer.get(<путь>)

--Добавление изображения в буфер:
imageToString.buffer.add(<путь>, [адрес])

--Удаление изображения из буфера:
imageToString.buffer.delete(<путь>)

--Полная очистка буфера:
imageToString.buffer.flush()



Результат при поиске текста:
Код
t = imageToString.get{[parms],[parms],[parms],...}

Функция возвращает двумерную таблицу, где первый индекс является номером строки, второй номером слова. Если ничего не найдет, вернет nil. Например, при распознавании текста:
Код
Съешь еще
этих
мягких французских булок.

Массив будет содержать следующие значения:
Код
t[1][1] -- Съешь
t[1][2] -- еще
t[2][1] -- этих
t[3][1] -- мягких
t[3][2] -- французских
t[3][3] -- булок



Известные проблемы:
1.Упрощенный вызов фунции func{} не работает, вызов только через func({}) (ограничено пилотом).
2.Переделать default.crds на get windowpos (ограничено пилотом).
3.Подчитсить findimage (ограничено пилотом).
4.Из-за особенностей костыля финдимиджа создается НЕ локальня переменная tmpOtNiAotNiaorNCOsnaOT.(огрничено пилотом).
5.При передаче источника поиск происходит в ошибочных координатах. Для компенсации конечная X координата задается, как:
options.crds[3] - options.crds[1]
Данная проблема присутствует на версии пилота 2.39 beta10. Если вы используете более свежую версию, то
options.crds[3] - options.crds[1]
может быть необходимо заменить в двух местах на:
options.crds[3]


Параметры при поиске текста:

Данный оператор имеет большое количество возможных параметров, все они необязательными. В теле скрипта есть блок значений параметров используемых по умолчанию, которые вы при желании можете изменить (таблица default).

window=<хендл|метод>
Хендл окна в котором происходит поиск либо метод 1|2. Поиск в перекрытых окнах происходит только при указании хендла. При указании хендла для корректного считывания изображения может понадобиться указывать хендл родительского окна. Значение по умолчанию: workwindow.

loadFolder={<path="путь">, [mask="маска"], [sub=0|1]}
Загрузка всех изображений из указанной папки. Имена файлов должны соответствовать символу который они означают (расширение не учитывается). Допускаются файлы с одинаковым именем в разных папках.
<path="путь"> - абсолютный путь по которому находится папка. Для преобразования относительного пути в абсолютный можно использовать конструкцию path=homepath .. "относительный путь".
[mask="маска"] - маска по которой будут загружены файлы. Допускается использование символов '?' и '*'. ? - означает один любой символ, * - любое количество неизвестных символов. Обратите внимание, что mask=".bmp" означает означает точное совпадение полного имени файла с указанной маской, т.к. символы подстановки не использованы. Если же указать mask="*.bmp", то будут загружены все файлы заканчивающиеся ".bmp".
[sub=0|1] - флаг указывающий, что изображения должны быть загружены в том числе из подпапок.
При указании loadFolder будут проигнорированы параметры: symbols, path, ext. Значение по умолчанию: nil.

symbols={}
Cимволы для поиска. Возможно указать в двух вариантах синтаксиса: упрощенном и полном.
Упрощенный вариант синтаксиса допускает не указывать соответствие имен файлов и строке/символу, который они обозначают: считается, что они идентичны. Пример упрощенного синтаксиса:
local symbols = {"0", "1", "2", "3", "a", "b", "c", "test"}
Полный синтаксис бывает необходим при использовании нескольких изображений соответствующих одной и той же строке/символу. Допускаются переносы строк:
local symbols = {
["0"] = {"zero1", "zero2"},
["1"] = {"1a", "1b"},
["2"] = {"two", "second"}
}
Оба варианта синтаксиса можно сочетать:
local symbols = {"0", "1", ["2"] = {"two", "second"}, "3"}
Данный параметр игнорируется, если указана загрузка папки (loadFolder).
Значение по умолчанию: {["1"]={"1"}, ["2"]={"2"}, ["3"]={"3"}, ["4"]={"4"}, ["5"]={"5"}, ["6"]={"6"}, ["7"]={"7"}, ["8"]={"8"}, ["9"]={"9"}, ["0"]={"0"}}

path=<"путь">
Путь по которому находятся изображения указанные в symbols. Путь может быть задан относительным или абсолютным. Данный параметр игнорируется, если указана загрузка папки (loadFolder). Все символы '\' должны быть удвоены (escape-последовательность), например, path="c:\\image.bmp". Если путь будет начинаться с символа '\', то он будет восприниматься относительно корня диска, например, если пилот находится по адресу d:\uopilot\uopilot.exe, то параметр path="\\myFolder" будет указывать на папку d:\myFolder. Значение по умолчанию: "images\\". Это относительный путь указывающий на папку images, которая находится рядом с exe пилота (создается пользователем).

ext=<"расширение">
Расширение картинок указанных в symbols. Данный параметр игнорируется, если указана загрузка папки (loadFolder). Значение по умолчанию: ".bmp".

crds={<xStart>, <yStart>, <xEnd>, <yEnd>, [abs=0|1]}
Координаты в которых необходимо производить поиск. При указании флага abs=1 координаты будут считаться относительно левого верхнего угла экрана, в противном случае координаты рассчитываются относительно левого верхнего угла приложения. Значение по умолчанию: 0, 0, 1919, 1079, abs=0.

accuracy=<число>
Точность поиска изображений. Для текста рекомендуется указывать 95-100. Значение по умолчанию: 95.

deviation=<число>
Допустимое отклонение оттенка в процентах (255/100*deviation). Если цвет 50 100 150, то при указании deviation=2 допустимыми значениями будут являться 45-55 95-105 145-155. Дробная часть при вычислении диапазона не округляется, а отбрасывается. Значение по умолчанию: 2.

deltaSpace=<число>
Допустимое расстояние по горизонтали между изображениями. Если значение превышено считается, что началось новое слово (присутствует пробел). Значение по умолчанию: 2.

deltaY=<число>
Смещение по высоте при превышении которого считается, что символы принадлежат к разным строкам. Значение по умолчанию: 8.

dupImage=<число>
Смещение при котором два найденных изображения будут считаться дубликатом одного. Значение по умолчанию: 3.

source={<address>, <width>, <height>}
Источник загруженного в память изображения в котором производить поиск.
<address> - адрес в памяти
<width> - ширина изображения
<height> - высота изображения
Изображение возможно загрузить в память при помощи getimage() или loadimage(). Значение по умолчанию: nil.

saveImage=<"путь">
Путь по которому будет сохранено изображение в котором происходил поиск. Значение по умолчанию: nil.

wait=<число>
Пауза в миллисекундах (1000мс=1сек) между поиском изображений. Используется для снижения нагрузки на процессор ценой увеличения времени поиска. Значение по умолчанию: 2.

durationMax=<число>
Время в течении которого будут происходить повторные попытки найти изображение. Значение может быть дробным, например, durationMax=2.5. При указании durationMax=-1 поиск будет происходить бесконечно до тех пор пока изображение не будет найдено. Если первое изображение было найдено, то остальные будут обработаны полностью вне зависимости от таймера, т.е. вы не получите обрезанный текст. При первом успешном распознавании текста функция завершит работу и передаст результат не дожидаясь окончания таймера. Значение по умолчанию: 0.

secondFrame=<число>
Параметр позволяет задать паузу между первым нахождением изображения и началом считывания изображений для распознавания текста. Позволяет дождаться полной прогрузки текста перед обработкой. Обратите внимание, что параметр durationMax учитывает значение secondFrame и не позволит функции работать дольше, чем указано в durationMax. Значение по умолчанию:0.

bufferAddNew=<0|1>
Флаг разрешающий добавлять в память буфера изображения, которые отсутствовали в буфере и были считаны с диска. Данный параметр игнорируется, если указан bufferIgnore=1. Значение по умолчанию: 1.

bufferUpdate=<0|1>
Флаг указывающий на то, что изображения в буфере должны быть обновлены. Они будут считаны с диска заново. Обновятся только те изображения, которые будут учавствовать в поиске. Данный параметр игнорируется, если указан bufferIgnore=1. Значение по умолчанию: 0.

bufferIgnore=<0|1>
Флаг запрещающий работать с буфером. Данный из буфера считаны не будут, загрузка искомых изображений произойдет с диска. Никаких данных в буфер не сохраняется. Значение по умолчанию: 0.

Автор: cirus 30.9.2017, 12:01

Цитата
table[1][1] -- Съешь

Не самое удачное имя для таблицы.
Код
--lua
table = {}
table.insert (table, 10)  -- получим ошибку

Автор: DarkMaster 4.10.2017, 4:51

Что-то накалялкал. И даже почти все тодо сделал.

Осталось понять, что за бред с вызовами a ={params}. Возможно придется скобки лепить...

Автор: cirus 4.10.2017, 14:46

Цитата
Уточнить при deviation происходит trunc() или round().

Если верить вики, то trunc.
Цитата
Пример: есть погрешность 3%. точка имеет цвет 100 120 130, 255*3%=7.

Т. е. 7.65 = 7.
Цитата
timeProc=<число>
т.е. вы не получите обрезанный тест.

текст
Может в timeFunc переименовать, понятнее будет.
Цитата
source
Изображение возможно загрузить в память при помощи getimage() или loadimage()

Тут есть нюанс. Если передавать изображение, то не нужно указывать crds. Искать будет на всём скрине, т. к. findimage (0, 0 width, height ....

options.abs не в getimage должен быть? По идее нужно скрин получать в abs координатах. В findimage он никакой роли не играет, ищем же на скрине.

Автор: DarkMaster 5.10.2017, 6:03

Скачать скрипт: Прикрепленный файл  FindString.lua_1.0.zip ( 9,55 килобайт ) Кол-во скачиваний: 232

Мануал
Данный скрипт предназначен для распознавания чисел, текста и различных символов (например, значков серебра, голда). Скрипт учитывает возможные пробелы и переносы строк. Параметры в квадратных [] скобках являются не обязательными, параметры в угловых скобках <> указываются всегда. Квадратные и фигурные скобки при вызове функций не пишутся, они лишь указывают на возможность не задавать параметр. Фигурные {} и круглые () скобки пишутся, там где указаны. Символ '|' означает исключающее или, например, sub=0|1 означает, что значение sub может быть равно либо 0, либо 1.


Известные проблемы:
1. Упрощенный вызов фунции func{} не работает, вызов только через func({}) (ограничено пилотом).
2. Переделать default.crds на get windowpos (ограничено пилотом).
3. Подчитсить findimage (ограничено пилотом).
4. Из-за особенностей костыля финдимиджа создается НЕ локальня переменная tmpOtNiAotNiaorNCOsnaOT (огрничено пилотом).
5. При передаче источника поиск происходит в ошибочных координатах. Данная проблема обусловлена багом финдимиджа. После фикса пилота следовать инструкциям в коде после фразы "Фикс финдимиджа" (всего три правки).
6.Из-за фантазий разработчика CrystalLua при вызове функции со вложенностью происходит передача массива в котором содержится функция.
Т.е. при вызове:
imageToString.buffer.get ("d:\\test.bmp")
на самом деле произойдет вызов:
imageToString.buffer.get (imageToString.buffer, "d:\\test.bmp")
НО при вызове:
imageToString.buffer.get "d:\\test.bmp"
будет произведен корректный вызов:
imageToString.buffer.get "d:\\test.bmp"
Для ликвидации этих фантазий введен дополнительный параметр функциях: bugFix, а так же смещение параметров. После фикса необходимо будет удалить помеченные строки:
Следующая строка должна быть удалена при фиксе пиота. Параметр функции bugFix так же должен быть удален. Всего три правки.


Установка:
Для удобства использования необходимо скачать и сохранить скрипт в отдельный файл и подгружать в начале вашего скрипта:
imageToString = require("luaPlugins\\FindString")
Вызов данной команды загрузит модуль FindString.lua из папки luaPlugins, расположенной рядом с пилотом. Т.е. "luaPlugins\FindString.lua".


Скрипт включает в себя следующие функции:
Код
--Получение текста из изображения:
t = imageToString.get{[parms],[parms],[parms],...}

--Управление буфером:
--Добавление изображения в буфер (вернет адрес):
imageToString.buffer.add(<путь>, [адрес])

--Получение адреса в памяти загруженного в буфер изображения:
imageToString.buffer.get(<путь>)

--Удаление изображения из буфера:
imageToString.buffer.delete(<путь>)

--Полная очистка буфера:
imageToString.buffer.flush()



Результат при поиске текста:
Код
t = imageToString.get{[parms],[parms],[parms],...}

Функция возвращает двумерную таблицу, где первый индекс является номером строки, второй номером слова. Если ничего не найдет, вернет nil. Например, при распознавании текста:
Код
Съешь еще
этих
мягких французских булок.

Массив будет содержать следующие значения:
Код
t[1][1] -- Съешь
t[1][2] -- еще
t[2][1] -- этих
t[3][1] -- мягких
t[3][2] -- французских
t[3][3] -- булок



Параметры при поиске текста:

Данный оператор имеет большое количество возможных параметров, все они являются необязательными. В теле скрипта есть блок значений параметров используемых по умолчанию, которые вы при желании можете изменить (таблица default).

window=<хендл|метод>
Хендл окна в котором происходит поиск либо метод 1|2. Поиск в перекрытых окнах происходит только при указании хендла. При указании хендла для корректного считывания изображения может понадобиться указывать хендл родительского окна. Значение по умолчанию: workwindow.

loadFolder={<path="путь">, [mask="маска"], [sub=0|1]}
Загрузка всех изображений из указанной папки. Имена файлов должны соответствовать символу который они означают (расширение не учитывается). Допускаются файлы с одинаковым именем в разных папках.
<path="путь"> - абсолютный путь по которому находится папка. Для преобразования относительного пути в абсолютный можно использовать конструкцию: path=homepath .. "относительный путь".
[mask="маска"] - маска по которой будут загружены файлы. Допускается использование символов '?' и '*'. ? - означает один любой символ, * - любое количество неизвестных символов. Обратите внимание, что mask=".bmp" означает означает точное совпадение полного имени файла с указанной маской, т.к. символы подстановки не использованы. Если же указать mask="*.bmp", то будут загружены все файлы заканчивающиеся сочетанием ".bmp".
[sub=0|1] - флаг указывающий на загрузку изображений, в том числе из подпапок.
При указании loadFolder будут проигнорированы параметры: symbols, path, ext. Значение по умолчанию: nil.

symbols={}
Cимволы для поиска. Набор символов возможно указать в двух вариантах синтаксиса:
Упрощенный вариант синтаксиса допускает не указывать соответствие имен файлов и строке/символу, который они обозначают: считается, что они идентичны. Пример упрощенного синтаксиса:
local symbols = {"0", "1", "2", "3", "a", "b", "c", "test"}
Полный синтаксис бывает необходим при использовании нескольких изображений соответствующих одной и той же строке/символу. Допускаются переносы строк:
local symbols = {
["0"] = {"zero1", "zero2"},
["1"] = {"1a", "1b"},
["2"] = {"two", "second"}
}
Оба варианта синтаксиса можно сочетать:
local symbols = {"0", "1", ["2"] = {"two", "second"}, "3"}
Данный параметр игнорируется, если указана загрузка папки (loadFolder).
Значение по умолчанию: {["1"]={"1"}, ["2"]={"2"}, ["3"]={"3"}, ["4"]={"4"}, ["5"]={"5"}, ["6"]={"6"}, ["7"]={"7"}, ["8"]={"8"}, ["9"]={"9"}, ["0"]={"0"}}

path=<"путь">
Путь по которому находятся изображения указанные в symbols. Путь может быть задан относительным или абсолютным. Данный параметр игнорируется, если указана загрузка папки (loadFolder). Все символы '\' должны быть удвоены (escape-последовательность), например, path="c:\\image.bmp". Если путь будет начинаться с символа '\', то он будет восприниматься относительно корня диска, например, если пилот находится по адресу d:\uopilot\uopilot.exe, то параметр path="\\myFolder" будет указывать на папку d:\myFolder. Значение по умолчанию: "images\\". Это относительный путь указывающий на папку images, которая находится рядом с .exe пилота (создается пользователем).

ext=<"расширение">
Расширение картинок указанных в symbols. Данный параметр игнорируется, если указана загрузка папки (loadFolder). Значение по умолчанию: ".bmp".

crds={<xStart>, <yStart>, <xEnd>, <yEnd>, [abs=0|1]}
Координаты в которых необходимо производить поиск. При указании флага abs=1 координаты будут считаться относительно левого верхнего угла экрана, в противном случае координаты рассчитываются относительно левого верхнего угла приложения. Значение по умолчанию: 0, 0, 1919, 1079, abs=0.

accuracy=<число>
Точность поиска изображений. Для текста рекомендуется указывать 95-100. Значение по умолчанию: 95.

deviation=<число>
Допустимое отклонение оттенка в процентах (255/100*deviation). Если цвет 50 100 150, то при указании deviation=2 допустимыми значениями будут являться 45-55 95-105 145-155. Дробная часть при вычислении диапазона не округляется, а отбрасывается. Значение по умолчанию: 2.

deltaSpace=<число>
Допустимое расстояние по горизонтали между изображениями. Если значение превышено считается, что началось новое слово (присутствует пробел). Значение по умолчанию: 2.

deltaY=<число>
Смещение по высоте при превышении которого считается, что символы принадлежат к разным строкам. Значение по умолчанию: 8.

dupImage=<число>
Смещение при котором два найденных изображения будут считаться дубликатом одного. Значение по умолчанию: 3.

toNumber=<0|1>
Флаг при котором слова состоящие только из цифр будут преобразованы из строки в числовой тип данных. Это необходимо для арифметических действий, а так же для сравнения чисел.

source={<address>, <width>, <height>}
Источник загруженного в память изображения в котором производить поиск.
<address> - адрес в памяти
<width> - ширина изображения
<height> - высота изображения
Изображение возможно загрузить в память при помощи getimage() или loadimage(). Значение по умолчанию: nil.

saveImage=<"путь">
Путь по которому будет сохранено изображение в котором происходил поиск. Значение по умолчанию: nil.

wait=<число>
Пауза в миллисекундах (1000мс=1сек) между поиском изображений. Используется для снижения нагрузки на процессор ценой увеличения времени поиска. Значение по умолчанию: 2.

durationMax=<число>
Время в течении которого будут происходить повторные попытки найти изображение. Значение может быть дробным, например, durationMax=2.5. При указании durationMax=-1 поиск будет происходить бесконечно до тех пор пока изображение не будет найдено. Если первое изображение было найдено, то остальные будут обработаны полностью вне зависимости от таймера, т.е. вы не получите обрезанный текст. При первом успешном распознавании текста функция завершит работу и передаст результат не дожидаясь окончания таймера. Значение по умолчанию: 0.

secondFrame=<число>
Параметр позволяет задать паузу между первым нахождением изображения и началом считывания изображений для распознавания текста. Позволяет дождаться полной прогрузки текста перед обработкой. Обратите внимание, что параметр durationMax учитывает значение secondFrame и не позволит функции работать дольше, чем указано в durationMax. Значение по умолчанию:0.

bufferAddNew=<0|1>
Флаг разрешающий добавлять в память буфера изображения, которые отсутствовали в буфере и были считаны с диска. Данный параметр игнорируется, если указан bufferIgnore=1. Значение по умолчанию: 1.

bufferUpdate=<0|1>
Флаг указывающий на то, что изображения в буфере должны быть обновлены. Они будут считаны с диска заново. Обновятся только те изображения, которые будут учавствовать в поиске. Данный параметр игнорируется, если указан bufferIgnore=1. Значение по умолчанию: 0.

bufferIgnore=<0|1>
Флаг запрещающий работать с буфером. Данный из буфера считаны не будут, загрузка искомых изображений произойдет с диска. Никаких данных в буфер не сохраняется. Значение по умолчанию: 0.


Если каких замечаний нет, то можешь релизить, да тему почищу.


Прикрепленные файлы
Прикрепленный файл  FindString_1.0.4.zip ( 10,52 килобайт ) Кол-во скачиваний: 152
Прикрепленный файл  FindString_1.0.5.zip ( 10,53 килобайт ) Кол-во скачиваний: 140

Автор: cirus 5.10.2017, 12:08

Цитата
Фикс: при передаче источника изображения (source) игнорировались координаты поиска.

Не поможет пока Кнайт не исправит https://forum.uokit.com/index.php?s=&showtopic=67903&view=findpost&p=419338. Или ничего не найдётся, или найдётся не то что надо.
Как временное решение: можно искать на всём скрине и удалить всё что не входит в указанную в crds область.
Цитата
Таймаут на прогрузку. Поиск для детекта изображений.

В этом блоке options.crds.abs тоже надо перенести в getimage.

Автор: DarkMaster 5.10.2017, 19:27

Цитата
Не поможет пока Кнайт не исправит этот баг. Или ничего не найдётся, или найдётся не то что надо.

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

Автор: cirus 6.10.2017, 2:18

Потестил этот баг.
1. Ищет не от левого верхнего угла, а от левого нижнего.
2. endX = endX - startX

Автор: DarkMaster 6.10.2017, 7:51

Ну переворачивать весь массив в обратную сторону смысла слава богу нет - сам перевернется при сортировке.
Координату костыль прилепил. В описании сделал пометку.


Прикрепленные файлы
Прикрепленный файл  FindString.lua_1.0.1.zip ( 9,69 килобайт ) Кол-во скачиваний: 152

Автор: cirus 6.10.2017, 13:20

Начальную координату X нужно прибавлять к конечной, т. к. findimage её отнимет. С координатой X решилось, а вот с Y всё не так просто. Там такой же косяк с вычитанием начальной координаты, но даже не это главное. Ищет снизу, т. е получается вот такая фигня:
Прикрепленное изображение
В общем что-то там напутано с Y, я так и не понял до конца как оно ищет.

Автор: cirus 6.10.2017, 15:09

Исправил:

Код
startX, startY, endX, endY = options.crds[1], 0, options.crds[3] + options.crds[1], height

Если передано изображение source, то по Y ищет на всём скрине.
Добавлен блок для удаления того что не входит в область указанную в crds.
Код
-- Удаление лишнего по Y если передано изображение source
-- Убрать после исправления бага FindImage, искал снизу вверх
if  options.source then
    for i = #crdsRaw, 1, -1 do
        if crdsRaw[i].y < options.crds[2] or crdsRaw[i].y > options.crds[4] then
            table.remove(crdsRaw, i)
        end
    end
end

Прикрепленный файл  FindString.lua_1.0.2.zip ( 10,04 килобайт ) Кол-во скачиваний: 206

В выходные ещё погоняю, если будет нормально, то можно будет в первый пост добавить.


Автор: cirus 7.10.2017, 23:16

Цитата
Если передано изображение source, то по Y ищет на всём скрине.

В общем с координатой X тоже приколы какие-то, так что при передаче изображения source придётся искать на всем скрине, а потом лишнее удалять. Это я переделал.
Цитата
--Получение адреса в памяти загруженного в буфер изображения:
imageToString.buffer.get(<путь>)

А оно так работает?
Код
imageToString["buffer"]["get"]("C:\\l2number\\1.bmp")

Так нормально.
Цитата
--Получение текста из изображения:
t = imageToString.get({[parms],[parms],[parms],...})
Результат при поиске текста:
t = imageToString.get{[parms],[parms],[parms],...}

В одном случае со скобками (), в другом без.
Без скобок нормально работает. Или есть какая-то разница?

Автор: DarkMaster 8.10.2017, 6:19

Цитата
Без скобок нормально работает. Или есть какая-то разница?

Разница том, что я уже за*бался с тем, что тут почему-то половина синтаксиса не работает, если начинаются сложные конструкции. Я так подозреваю это из-за crystal lua.
Там эти скобки нахрен не нужны в нормальном виде и квадратные с кавычками тоже. Надо убрать вложенность. Массив buffer{} сделать обратно префиксом типа bufferGet()

Автор: DarkMaster 9.10.2017, 11:49

Правок больше не будет? X, Y все поправлено? Переименовываю функции и все?

Автор: cirus 9.10.2017, 12:28

Цитата
Правок больше не будет? X, Y все поправлено?

Вроде всё работает. X, Y подправил.
При передаче source ищет на всём скрине, что не входит в crds удаляется.
Исправлено:
Код
screenshot, width, height = options.source[1],options.source[2],options.source[3]
startX, startY, endX, endY = 0, 0, width, height   -- чтобы искало на всём скрине

Код
-- Если передано изображение source удаляем из crdsRaw всё что не входит в область crds
-- Убрать после исправления багов FindImage
if  options.source then
    for i = #crdsRaw, 1, -1 do
        if crdsRaw[i].y < options.crds[2] or crdsRaw[i].y > options.crds[4] or crdsRaw[i].x < options.crds[1] or crdsRaw[i].x > options.crds[3] then
            table.remove(crdsRaw, i)
        end
    end
    if  #crdsRaw < 1 then  
        return nil
    end
end
------------

Прикрепленный файл  FindString.zip ( 10,04 килобайт ) Кол-во скачиваний: 191

Автор: DarkMaster 10.10.2017, 15:14

Ну что... Опять что попало...
Кароче говоря он не хочет нормально вложенные функции воспринимать нормальным синтаксисом. Только через доп скобки квадратные/круглые.
Проблема в том, что как только ты подключаешь это дело через require, то уровень вложенности сразу на единичку повышается. Суть проблемы:
imageToString.get - без require работает
imageToString["get"] - с require только так
С буфером подавно проблемы, т.к. там вложенность еще больше. И че делать будем?

Автор: cirus 10.10.2017, 15:34

У меня так работает без проблем.

код
Код
--lua
require ("FindString")
log ("clear") log ("mode compact")

t = imageToString.get{path="C:\\l2number",
                      crds={104, 278, 156, 368},
                      deltaSpace = 5,
                      durationMax = 0
                      }
if t then
    for i= 1, #t do
        log (table.concat(t[i], "  "))
    end
else
    hint (t)
end

a = imageToString.buffer.get "C:\\l2number\\1.bmp"    -- вообще без скобок
log (a)

В любом случае лучше делать чтоб работало с require.
P.S. Ушёл на работу.

Автор: DarkMaster 10.10.2017, 20:47

Мде... У меня подобные финты не проходят. Ничего не понимаю...

Кстати мы два балбеса) Тесты вдоль и поперек. Вот только числа стрингом возвращает)) Ща серьезный тест дал в реальных условиях и никак понять не мог почему сравнение чисел идет ошибочное. Причем собака на 164 предмете сбилось)) Надо прикрутить конвертацию опциональную.

Автор: cirus 11.10.2017, 2:54

Код
            if  options.loadFolder   == nil then
                options.symbols = deepcopy(default.symbols)
            else
--                options.symbols = {}
            end

Закомментированная строка нужна?

Ещё можно добавить опцию для отладки, т. к. ползти в файл с функцией и раскомментировать нужные строки как-то не очень удобно.
Что-то вроде:
Код
t = imageToString.get{path="C:\\l2number",
                      debug = {"options.symbols", "images", "fileList"}  -- какие выводить массивы
                      }


Автор: DarkMaster 11.10.2017, 7:10

Цитата
Закомментированная строка нужна?

Она уже раскомментирована. Тест был.

Автор: cirus 11.10.2017, 11:46

Цитата
default.window = "workwindow"

Может лучше 2? Потом придётся каждому отвечать на вопрос: "Памагите ничего не находит, ааааа". Не все знают что перекрытие работает не везде, часто надо передавать не рабочее окно, а родительское, иногда бывает смещение координат.

Автор: DarkMaster 11.10.2017, 12:37

Можно и 2. У меня все равно будет workwindow) Но для остальных это может быть действительно правильным.

Автор: DarkMaster 13.10.2017, 15:22

Обновил мануал, там же новая версия с преобразованием и новыми костылями.

Автор: DarkMaster 13.10.2017, 20:23

подчистил вывод в лог.
buffer.add возвращает адрес.

Автор: cirus 14.10.2017, 3:01

Я так и не понял как теперь imageToString.get вызывается.

Автор: DarkMaster 14.10.2017, 6:57

через фигурные скобки.

Автор: cirus 14.10.2017, 10:09

Код
--lua
require ("FindString")
t = imageToString.get{path="C:\l2number"}

Пишет глобальная переменная imageToString не найдена.

Автор: DarkMaster 14.10.2017, 11:48

там реквайр теперь другой. теперь только чистая функция. Поддерживать два синтсаксиса, каждый из которых с багами нереально. Возможно будет замена crystal lua на luajit, но там писанины много относительно кристал. Проблемы с прослойкой между пилотом и либой.

Мануал вроде прилизывал под все вызовы, чтобы как раз проблем не было.

Автор: cirus 14.10.2017, 20:22

Цитата
там реквайр теперь другой

Не обратил внимания. Работает.
Толком не тестил. Завтра проверю.

Автор: cirus 14.10.2017, 23:07

Исправь default.window на 2.

Цитата
-- Преобразовываем строки в числа, если это возможно.

Не хватает:
Код
if options.toNumber == 1 then

Цитата
toNumber=<0|1>
Флаг при котором слова состоящие только из цифр будут преобразованы из строки в числовой тип данных. Это необходимо для арифметических действий, а так же для сравнения чисел.

Дописать: Значение по умолчанию: 1.

Орфографию и пунктуацию будешь исправлять? smile.gif


Автор: DarkMaster 15.10.2017, 2:05

Цитата
Орфографию и пунктуацию будешь исправлять? smile.gif

Если с русским языком хорошо - можешь не спрашивать, а просто указывать на ошибки) У меня не без проблем... тем более обороты.

Автор: cirus 15.10.2017, 13:45

Цитата
просто указывать на ошибки

Проще самому исправить.
Исправлена орфография и пунктуация, большего ничего не менял.
Прикрепленный файл  FindString_1.0.6.zip ( 10,75 килобайт ) Кол-во скачиваний: 268


Автор: cirus 15.10.2017, 18:40

Код
-- Полностью очищаем массив.
function imageToString.buffer.flush()
    for k,_ in pairs(buffer) do buffer[v] = nil end
end

Очищаем буфер, а не массив.
Вместо buffer[v] должно быть buffer[k].

Автор: DarkMaster 15.10.2017, 19:32

либо
_, v
v = nil
это шустрее должно быть кстати.

Автор: cirus 15.10.2017, 22:50

Цитата
это шустрее должно быть кстати.

В данном случае это не актуально. Не думаю что кто-то будет загружать 100500 картинок.
Вроде всё работает.
В мануал надо дописать что durationMax и secondFrame указываются в секундах.
Первый пост немного отредактировал. Тему переименовать в "Распознавание текста с помощью Findimage"? Или переименуй как надо.
Добавишь скрипт и мануал в первый пост? Должен влезть, в сообщении допускается где-то 500-600 строк, если что, мой скрипт можно будет в архив закинуть.
Тему можно почистить.

Ещё бы Кнайт починил сломанный в 11 бетке findimage.

Автор: WKnight 23.10.2017, 14:33

Цитата
Исправил в 'findimage' поиск запомненной картинки в загруженной области.
Это откатил до десятой беты. Доступно в нестабильной сборке http://uopilot.uokit.com/dld.php

Автор: cirus 23.10.2017, 14:58

Цитата
Доступно в нестабильной сборке http://uopilot.uokit.com/dld.php

Что-то не то выложил. Размер 22 байта.

Автор: WKnight 24.10.2017, 20:30

Пасиб, починил.

Автор: Alex83 27.10.2017, 0:29

доброго времени, попробовал как работает на этом примере, но что то не оч получилось не находит искомое, или я чтот не так делаю, в этом месте (C:\мойкомпьютер.bmp) должна находится картинка или нет и обязательно ли писать .bmp, после того что хотим найти
// Пример 6
//Чтобы понять как работает поиск можно попробовать на рабочем столе найти значок 'Мой компьютер'.
//Делаем картинку значка в формате bmp, называем 'мойкомпьютер' (без кавычек), закидываем на диск 'C:'.
//При этом можно перекрыть значок каким-нибудь окном.

//Не забываем сделать привязку Ctrl + A.
set #a FindImage(0 0 1920 1080 (C:\мойкомпьютер.bmp) %arr workwindow)
if #a > 0
log Картинка найдена. Наведём на неё курсор.
move %arr [1 1] %arr [1 2]
End_script
else
msg Картинка не найдена.
end_if

Автор: cirus 27.10.2017, 2:04

Давайте не будем засорять тему вопросами, которые не имеют отношения к данному скрипту.
Лучше создать отдельную тему.

Автор: Alex83 27.10.2017, 11:56

Цитата(cirus @ 23.10.2017, 14:58) *

Что-то не то выложил. Размер 22 байта.

доброго времени, подскажите пож для данного скрипта что бы он распознал комбинацию цифер, допустим нужно найти число 46, для этого нужно делать 2 картинки с цифрами 4 и 6 или сразу 46 одной картинкой, заранее спс.

Автор: cirus 27.10.2017, 12:09

Цитата
допустим нужно найти число 46, для этого нужно делать 2 картинки с цифрами 4 и 6 или сразу 46 одной картинкой, заранее спс.

Если всегда надо искать число 46, то можно одну картинку. Тогда не потребуется этот скрипт.
Если нужно искать разные числа, то надо делать картинки всех цифр.

Автор: DarkMaster 5.2.2018, 11:18

Собственно совсем забылось. Прикрепи в первый пост, тему помню ты хотел почистить, если есть желание.


Прикрепленные файлы
Прикрепленный файл  FindString.lua ( 40,39 килобайт ) Кол-во скачиваний: 302

Автор: cirus 5.2.2018, 12:23

Цитата
Прикрепи в первый пост

Прикрепил. Потом добавлю примеры вызова.
Цитата
тему помню ты хотел почистить, если есть желание

Изначально я предлагал сделать отдельную тему, чтоб эту не чистить smile.gif
Почищу как время будет. Я так понимаю права нужны.

Автор: FREEON 28.9.2018, 15:42

Как с помощью данного скрипта вывести значения картнок в таблицу из массива?
Прикрепленное изображение
Есть стандартное поле с условно-рандомно генерируемых цифр разделенных сеткой
нужно записать значение по боксам
set %arr [ 1 1] число из 1 строки 1столбца
set %arr [ 1 2] число из 1 строки 2столбца
set %arr [ 1 3] число из 1 строки 3столбца
set %arr [ 1 4] число из 1 строки 4столбца
set %arr [ 2 1] число из 2 строки 1столбца
set %arr [ 2 2] число из 2 строки 2столбца
set %arr [ 2 3] число из 2 строки 3столбца
set %arr [ 2 4] число из 2 строки 4столбца
set %arr [ 3 1] число из 3 строки 1столбца
set %arr [ 3 2] число из 3 строки 2столбца
set %arr [ 3 3] число из 3 строки 3столбца
set %arr [ 3 4] число из 3 строки 4столбца
set %arr [ 4 1] число из 4 строки 1столбца
set %arr [ 4 2] число из 4 строки 2столбца
set %arr [ 4 3] число из 4 строки 3столбца
set %arr [ 4 4] число из 4 строки 4столбца
Нужно ли прописывать для каждой ячейки область поиска или можно сделать лишь задав одну, а найденные изображения(цифры) можно будет записать с лево на право и с верху вниз???

Автор: DarkMaster 28.9.2018, 16:06

Можно обойтись одной областью, но скрипт нужно обновить. У меня походу монитор накрылся... Не могу сделать это прямо сейчас...

Автор: DarkMaster 30.9.2018, 17:07

Скрипт из нестабильной версии. Вроде был рабочий =)


Прикрепленные файлы
Прикрепленный файл  FindStringDev.lua ( 40,94 килобайт ) Кол-во скачиваний: 223

Автор: FREEON 30.9.2018, 21:44

Цитата(DarkMaster @ 30.9.2018, 17:07) *

Скрипт из нестабильной версии. Вроде был рабочий =)

где задаются координаты поиска? в коментарии есть строчка crds={<xStart>, <yStart>, <xEnd>, <yEnd>, [abs=0|1]} которая хадает облость поиска, но в рабочей части только есть эта строка default.crds = function(window) -- Координаты поиска.

При попытке запустить выдает ошибку версия нестабильная.
syntax error during precompilation. 95: invalid escape sequence near "t> ~lua
do
function table.show(data, comment)
правки которые делал в файле:
Код

local default = {}
    default.window       = function() return workwindow() end   -- Метод|хендл_окна в котором происходит поиск (если указан источник изображения(source), то параметр будет проигнорирован).
    default.loadFolder   = nil      -- Путь, по которому будут загружены все изображения с указанной маской {path=путь, mask=маска, sub=1|0}(sub - подпапки). Имя файла будет соответсвовать имени символа.
                                            -- Набор стандартных символов.
    default.symbols      = {["0"]={"0"}, ["2"]={"2"}, ["4"]={"4"}, ["8"]={"8"}, ["16"]={"16"}, ["32"]={"32"}, ["64"]={"64"}, ["128"]={"128"}, ["256"]={"256"}}
    default.path         = "D:\_UOPilot\_2048"       -- Папка с картинками.
    default.ext          = ".bmp"           -- Расширение картинок.
    default.crds         = function(window) -- Координаты поиска.

ну и первый комент подчистил для уменьшения объема

Автор: DarkMaster 1.10.2018, 5:54

Цитата
local default = {}

Это таблица умолчаний. Т.е. если не заданы какие-либо параметры, то они берутся отсюда. Это править можно, но нужно понимать, что это это едва ли то, что нужно делать первый раз увидев скрипт. Для начала сделайте обычный вызов функции. Картинки рекомендую подгружать через loadFolder.

Автор: FREEON 1.10.2018, 20:31

В общем понял, что ничего не понял...язык пилота мне понятнее.

Cirus что может быть запускаю скрипт на языке пилота доходит до строчки:

Код
call test %picture %symbol %GetImage %path #deltaY #deltaspace #accuracy #deviation #wait #timeproc #repeatimage    // процедура поиска

и далее ничего не происходит и не стопоритя и ошибок не выбивает и до вывода результата с if также не даходит. Включал слежку за строками он доходит до вызова процедуры(код строки выше) и все никуда больше не на выполнение процедуры не переходит и дальше на if тоже не переходит. Попробовал взять в скобки то что находится после test вроде как проскакивает на выполнение и потом назад... можэ что там смесь % и # данных ohmy.gif .... Помоги разобраца mellow.gif

Автор: cirus 2.10.2018, 11:19

Цитата
Как с помощью данного скрипта вывести значения картнок в таблицу из массива?

Для этой задачи не нужен этот скрипт. Т. к. часть фишек могут отсутствовать, всё равно придётся играться с координатами, чтобы заполнить массив.
Допустим поле 4*4 размером 400*400, нашли картинку цифры 2 в координатах 120, 215. Значит цифру надо записать в arr[2][3]. Т. к. размеры клетки 100*100, то координаты от 0 до 100 это первая строка/столбец, 100-200 вторая и т. д.

Автор: FREEON 2.10.2018, 11:47

Цитата(cirus @ 2.10.2018, 11:19) *

Для этой задачи не нужен этот скрипт. Т. к. часть фишек могут отсутствовать, всё равно придётся играться с координатами, чтобы заполнить массив.
Допустим поле 4*4 размером 400*400, нашли картинку цифры 2 в координатах 120, 215. Значит цифру надо записать в arr[2][3]. Т. к. размеры клетки 100*100, то координаты от 0 до 100 это первая строка/столбец, 100-200 вторая и т. д.

Ну с утра тоже думаю просто сделать по координатам, написать простой скрипт типа по точкам где присваются значения (состоящая из точек) и процедура где есть все значения от 0 до 2048. И ужэ условно производить по очереди перебор значений. Но пака есчо перевариваю как это лучше сворганить.

Автор: FREEON 9.10.2018, 22:04

Цитата(cirus @ 2.10.2018, 11:19) *

Для этой задачи не нужен этот скрипт. Т. к. часть фишек могут отсутствовать, всё равно придётся играться с координатами, чтобы заполнить массив.

Если ты имеешь в виду пустые плитки то их значение делаем 0(т.е пустую плитку делаем картинку с именем 0.bmp). Если имеешь в виду к примеру большие числа 4 ... 512 1024 и 2048 то и буквы и цифры тоже не всегда появляется на экране, не думаю что это как-то критично. наша задача найти из того что есть и присвоить значения. Грубо говоря все в рамках есть картина состоящая из стандартных кусков(картинок) которые то появляются то передвигаются, других нестандартных кусков нет.

Цитата

Допустим поле 4*4 размером 400*400, нашли картинку цифры 2 в координатах 120, 215. Значит цифру надо записать в arr[2][3]. Т. к. размеры клетки 100*100, то координаты от 0 до 100 это первая строка/столбец, 100-200 вторая и т. д.

Есть вопросы...не совсем понятно какой код нужен что бы связать поиск с присвоением значением массива?
Код

set linedelay 0
log clear
log mode compact
set $path "D:\_UOPilot\_2048" // папка с картинками
//init_arr %image 0 2 4 8 16 32 64 128 256 512 1024 2048    //имена картинок (0.bmp, 1.bmp и т.д.)
//init_arr %bukva 0 2 4 8 16 32 64 128 256 512 1024 2048   // цифра
set delimiter ' '
dir (%image $path *.bmp*)   // поиск картинок в папке и загрузка их в массив
log В папке найдено: size(%image) картинок
//дописать процесс поиска по облостям
for #i 1 size(%image)   // цикл для поиска картинок (дописать)
    set #x11 findimage( координаты 1.2  #startX #startY #endX #endY) поиск нужной? // область поиска ячейка 1- 1
    if  #x11 > 0 //если в ячейке 1 1 нашлась картинка присвоить значение
        set %arr [1 1] присвоить число картинки
    end_if
    set #x12 findimage( координаты 1.2  #startX #startY #endX #endY) поиск нужной? // область поиска ячейка 1- 2
    if  #x12 > 0 //если в ячейке 1 1 нашлась картинка присвоить значение
        set %arr [1 2] присвоить число картинки
    end_if
    //анологично для остальных
    set #x44 findimage( координаты 4.4  #startX #startY #endX #endY) поиск нужной? // область поиска ячейка 4- 4
    if  #x44 > 0 //если в ячейке 4 4 нашлась картинка присвоить значение
        set %arr [4 4] присвоить число картинки
    end_if
    //сделать проверку если все значение заданы перейти то выйти из цикла и перейти к поиску и просчету хода
    if все значения if> 0
        log %arr [1 1] %arr [1 2] и т.д
       Break
    end_if
end_for
end_script

или
Код

set linedelay 0
log clear
log mode compact
set $path "D:\_UOPilot\_2048" // папка с картинками
//init_arr %image 0 2 4 8 16 32 64 128 256 512 1024 2048    //имена картинок (0.bmp, 1.bmp и т.д.)
//init_arr %bukva 0 2 4 8 16 32 64 128 256 512 1024 2048    // цифра
set delimiter ' '
dir (%image $path *.bmp*)   // поиск картинок в папке и загрузка их в массив
log В папке найдено: size(%image) картинок
//дописать процесс поиска по облостям
for #i 1 size(%image)   // цикл для поиска картинок (дописать)
    //присвоение значений по сетке поле 4*4 размером 400*400
    //код?
end_for
end_script

Автор: cirus 10.10.2018, 2:18

Цитата
какой код нужен что бы связать поиск с присвоением значением массива?

код
Код
init_arr %image 2 4 8 16 32 64  // имена картинок
set $path "D:\_UOPilot\_2048\"    // путь к картинкам
init_arr %coord 403, 236 882, 713  // координаты для findimage


set #stepX (%coord [3] - %coord [1]) / 4   // шаг по X
set #stepY (%coord [4] - %coord [2]) / 4   // шаг по Y
set #z 0
for #i 1 size(%image)   // поиск картинок
    set #a findimage(%coord [1] %coord [2] %coord [3] %coord [4] ($path%image[#i].bmp) %arr 2 90 -1 3)
    if  #a > 0
        for #j 1 size(%arr)
            set #z #z + 1
            init_arr %temp (#z) %arr [#j 1] %arr [#j 2] %image[#i] // добавить в массив координаты и имя картинки
        end_for
    end_if
end_for

for #i 1 4   // заполнить массив 4*4 нулями
    init_arr %field (#i) 0 0 0 0
end_for

for #i 1 #z  // подсчёт позиции картинки на поле
    set #x (%temp [#i 1] - %coord [1]) / #stepX + 1
    set #y (%temp [#i 2] - %coord [2]) / #stepY + 1
    set %field [#y #x] %temp [#i 3]  // имя картинки в нужный элемент массива
end_for


log clear
log mode compact
set delimiter ' '
for #i 1 4            // вывод в лог
    log %field [#i]
end_for
set delimiter
end_script

Чтобы быстрее работало загрузить картинки в массив, сделать скрин и на нём искать картинки.

Автор: NoName212 4.1.2019, 6:03

Можно ли возвращать результат работы скрипта(числа) через вызов процедуры? Отправить скрипту координаты, он находит числа и возвращает строку

Код

set #x 30, 17
set #y 42, 113
call Number_meat #x #y

if $Number_meat > 200
  ...
if $Number_meat > 100
   ...
  if $Number_meat > 50
   ...
   if $Number_meat > 10
   ...
   end_if
  end_if
end_if
end_if


как то так ... smile.gif

один proc в котором скрипт, и 5-10 call'ов или сколько нужно... или только так можно: 1 proc - 1 call ?

___________

хотя можно по нескольким вкладкам скрипты разнеси останавливать их включать и т.д.


Эскизы прикрепленных изображений
Прикрепленное изображение

Автор: xolost 27.2.2019, 11:53

Не совсем понял почему в скрипте на пилоте так много букв!?

Код

set #s 1
for #step 0 9
    // Поиск изображений
    set $check findimage (0 0 1280 1024 (C:\цифры\#step$bmp) %crds 2 100 -1)
    // Проверка на наличие
    if $check > 0
        set #size size (%crds)
        for #i 1 #size
            // Запись в массив %m[#s 1] числа, %m[#s 2]координаты
            set %m[#s 2] #step
            set %m[#s 1] %crds[#i 1]
            set #s #s + 1
        end_for
    end_if
end_for

// Присваиваем переменной размер массива
set #n size (%m)
// Сортируем массив
for #i 1 #n
    set #min %m[#i 1]
    set #imin #i
    set #ii #i + 1
    for #j #ii #n
        if %m[#j 1] < #min
            set #min %m[#j 1]
            set #imin #j
        end_if
    end_for
    // меняем местами минимальный элемент с текущим, используя промежуточную #z
    set #z %m[#i 1]
    set %m[#i 1] %m[#imin 1]
    set %m[#imin 1] #z
    set #z %m[#i 2]
    set %m[#i 2] %m[#imin 2]
    set %m[#imin 2] #z
end_for
// Соберем все элементы в одну текстовую строку
set $s // пустая строка
for #i 1 #n
    set $s $s%m[#i 2] //(X= %m[#i 1]) // добавляем каждый элемент в конец строки
end_for
set size ( %m )
set size ( %crds )




Пользуюсь этим скриптом по сей день. Написал его по-моему Дарк или Зилекс. Лет 10 назад.
Отлично работает.

Автор: cirus 27.2.2019, 12:16

Цитата
Не совсем понял почему в скрипте на пилоте так много букв!?

Если искать 1 число или слово, то можно и так. Можно даже короче написать с учётом что уже давно появилась сортировка массивов. На луа этот скрипт вообще несколько строчек займёт.
Скрипты из первого поста позволяют найти несколько чисел/слов за 1 поиск.


DarkMaster, функцию надо бы подправить, там же создавался глобальный массив:
Цитата
массив НЕ локальная переменная tmpOtNiAotNiaorNCOsnaOT (ограничено пилотом).

Автор: xolost 27.2.2019, 12:47

Цитата(cirus @ 27.2.2019, 12:16) *

Скрипты из первого поста позволяют найти несколько чисел/слов за 1 поиск.

Замечательно, но зачем это нужно?
Вот есть функция которая ищет одно число.
Задаем зону для поиска - нашли.
Нужно ещё число найти другое? задаем диапазон поиска для другого числа.
В моем случае я обычно делал - ищу картинку, рядом с которой это число всегда, и от неё строю диапазон. Ну и всё, 1 функция для любого кол-во чисел.
Просто не вижу практического смысла в таком объеме, который ничего и не выигрывает по-сути.

Про сортировку да, я когда начал питон изучать, узнал что сщуестует сортировка. 1 строчкой за 0.00001 секунду тысячи данных. В пилоте на тот же объем куча строчек и несколько минут работы скрипта. Было грустно очень

Автор: FREEON 19.5.2019, 17:17

Встроил в скрипт часть кода для проверки баланса на персах, но есть ошибки в его работе... Когда этот код работает сам по себе то нормально распознает значения. Но если его встроить то сперва работает нормально, но спустя некоторое время дает неверные значение. Если число баланса состоит равно или больше из трех цифр то все четко, но если число менее 2х цифр он дает косяк и приписывает есче одну цифру с воздуха, хотя сразу работал корректно. Имена переменных и "буквы" счетчиков проверял, они не пересекаются...не знаю в чем проблема, может есть какие решения?

Код

log clear
log mode compact
log open 0 630 200 150
//---
set #obsciy 0  // переменная для подсчета общего баланса
set #schet 1 // ВКЛ ВЫКЛ проверить баланс 1 - проверить, 0 - не проверять
//---
if  #schet = 1
    set #balans 0 //переменная для подсчета(сброса) текущего баланса
    init_arr %image 0 1 2 3 4 5 6 7 8 9  // имена картинок
    set $path "D:\_UOPilot\newimage\balans\"    // путь к картинкам
    init_arr %coord 136, 145 176, 153   // координаты "кошелька" для findimage
    //размер цифр 6х8
    set #stepX (%coord [3] - %coord [1]) / 6   // шаг по X, ширина одной цифры-картинки 6 пикселей(отступа между ими нет)
    set #stepY (%coord [4] - %coord [2])    // шаг по Y  не нужен т.к. одна стока
    set #z 0
    for #q 1 size(%image)   // поиск картинок
        set #bb findimage(%coord [1] %coord [2] %coord [3] %coord [4] ($path%image[#q].bmp) %arr 2 90 -1 3)
        if  #bb > 0
            for #w 1 size(%arr)
                set #z #z + 1
                init_arr %temp (#z) %arr [#w 1] %arr [#w 2] %image[#q] // добавить в массив координаты и имя картинки
            end_for
        end_if
    end_for

    for #q 1 #z  // подсчёт позиции картинки на поле
        set #x (%temp [#q 1] - %coord [1]) / #stepX + 1
        set #y (%temp [#q 2] - %coord [2]) / #stepY + 1
        set %field [#y #x] %temp [#q 3]  // имя картинки в нужный элемент массива
    end_for
    set #balans %field [1] //вывести текущее состояние счета
    set #obsciy #obsciy + #balans //подсчет общего счета
    log На счету #balans баленов.
    log ОБЩИЙ БАЛАНС: #obsciy
end_if
end_script

Автор: cirus 19.5.2019, 17:32

Перед этой строкой:

Цитата
for #q 1 #z // подсчёт позиции картинки на поле

Код
set size(%field) // удалить массив 

Скорее всего, лишние цифры это то что осталось от прошлого числа. К примеру, сначала нашли 123, потом нашли 45, в итоге выдаст 453, т. е. 3 это то что осталось в массиве от 123

Автор: Automaton 19.12.2019, 15:38

Cirus, настроил в вашем варианте очень маленький диапазон поиска цифр: init_arr %GetImage (1) 949 269 1004 289 а выдал он цифр во всплывающем окошке, гораздо больше чем там в действительности:

скрин области и результата

Изображение

Картинки с цифрами 5х8 пикселей, настройки в скрипте такие:
Настройки скрипта

set linedelay 0
init_arr %picture 0 1 2 3 4 5 6 7 8 9 // имена картинок (0.bmp, 1.bmp и т. д.)
init_arr %symbol 0 1 2 3 4 5 6 7 8 9 // символ соответствующий имени, т. е. картинка 0.bmp соответствует 0
set $path "C:\UO Pilot" // папка с картинками
set $bmp "*.bmp*" // формат картинок
set #deltaY 8 // расстояние между строками (можно указать высоту картинок)
set #deltaspace 12 // допустимое расстояние между цифрами, иначе будет считаться что это не одно число
set #accuracy 90 // точность поиска для Findimage
set #deviation 6 // погрешность оттенка для Findimage
set #wait 2 // пауза между поиском картинок, если указать меньше искать будет быстрее, но нагрузит процессор
set #timeproc 2000 // время (в мсек) для поиска картинок, если 0 не выйдет из процедуры пока не найдётся хотя бы 1 картинка
set #repeatimage 2 // допустимое смещение координат, если используется несколько видов одной картинки

Автор: apaul 19.9.2021, 20:52

Добрый день. А можно попросить боевой рабочий пример использования этого скрипта в варианте lua?
А то что-то с циферками из блокнота не выходит - плюется в меня рантайм-еррором sad.gif.
На всякий случай цепляю тестовый шот из блокнота и вырезанные оттуда циферки.
Прикрепленный файл  test.zip ( 43,35 килобайт ) Кол-во скачиваний: 421

Автор: DarkMaster 22.9.2021, 15:37

Можно ваш вызов увидеть?

Автор: apaul 18.10.2021, 1:52

Цитата(DarkMaster @ 22.9.2021, 15:37) *

Можно ваш вызов увидеть?

Не дает мне покоя столь удобная функция, уж очень не охота изобретать свой велосипед unsure.gif
Падать вроде перестала, но и работать как дОлжно отказывается. Вот такой вызов:
Код

local sy = {
        ["0"] = {"0a"},
        ["1"] = {"1a"},
    }
local pa="test\\"
local cr={674, 421, 709, 443}
local t = imageToString. get{symbols=sy,path=pa,crds=cr,accuracy=80,deviation=8,deltaSpace=1,toNumber=0,d
urationMax=0}
log(#t, t[1][1])

На экране в заданных координатах присутствует цифра 10. Но функция упорно отказывается искать более 1 символа. Если в symbols лежат обе цифры - ищется первая "1", если убираем из symbols "1", то ищется "0". Как уговорить его искать все цифры, дабы увидеть на выходе "10"? Что я упустил?

Автор: pioner 16.11.2021, 11:41

Добрый день. Не могу разобраться с пробелами- в result111.txt и в лог записывает слово и цифру слитно. Как разбить, помогите, пожалуйста!

Разобрался, ссори

Автор: DarkMaster 10.4.2022, 9:37

Lua версия скрипта обновлена до версии 1.0.8

Автор: aboba 21.4.2022, 19:45

Цитата(DarkMaster @ 10.4.2022, 9:37) *

Lua версия скрипта обновлена до версии 1.0.8

Не понимаю, почему у меня не работает. Зависает на 21 строчке. Функция findcolor тоже не работает(


Эскизы прикрепленных изображений
Прикрепленное изображение

Автор: DarkMaster 21.4.2022, 22:43

Я обновлял версию для луа. У вас вопрос версии для старого синтаксиса судя по скриншоту. Это два разных скрипта smile.gif Вас какой именно интересует?

Автор: DarkMaster 24.11.2022, 9:02

Lua версия обновлена.
1.0.9
Добавлено: установление приоритетов символов при удалении дублей. 4 и 1 - будет удалено 1, O и Q удалено O и т.д.
Добавлено: пример вызова, пример для сбора табличных данных.
Фикс: исправлены проблемы findimage пилота при поиске в уже загруженном изображении (getimage/loadimage)

Автор: Cockney 24.11.2022, 11:43

в другом решении видел фичу обучения распознавания. У нас не планируется подобное ? С дублями может помочь ну и при большом наборе обучающей выборки (а ее можно делать автоматически) точность хорошая будет.

Автор: DarkMaster 24.11.2022, 17:04

Цитата
У нас не планируется подобное ?

Планы были и есть теоретически есть, со временем проблемы. Даже продумывал, как все это реализовать красиво. Были мысли прикручивать OCR. Там проблемы откроваенные. 10 раз норм наспознает, на 11 его переклинит и ерунду дикую выдаст. Причем результат может быть иным от, например, фона где-то в незначащем куске. Ну и OCR откровенный тормоз. Тут даже на старом имидже намного быстрее.

Автор: Cockney 24.11.2022, 23:11

Цитата(DarkMaster @ 24.11.2022, 17:04) *

Планы были и есть теоретически есть, со временем проблемы. Даже продумывал, как все это реализовать красиво. Были мысли прикручивать OCR. Там проблемы откроваенные. 10 раз норм наспознает, на 11 его переклинит и ерунду дикую выдаст. Причем результат может быть иным от, например, фона где-то в незначащем куске. Ну и OCR откровенный тормоз. Тут даже на старом имидже намного быстрее.



ты видимо про какое-то готовое решение, а я про самописное. готовое слишком унифицировано, поэтому и медленно. а своя поделка - внутри простой статистический аппарат, который +- быстро по статистике определит символ на любом почти фоне

Автор: DarkMaster 25.11.2022, 5:43

Я про оба варианта. OCR имхо не имеет существенного смысла ввиду нестабильности. Мой вариант поэтом жив и боюсь будет жить еще очень долго. Вопрос во времени для развития.

Автор: Skylos 3.8.2023, 22:54

Пробую скрипт на языке пилота
Не могу понять как указать регион поиска чисел.
Почему- то всегда ищет по всему окну неважно какой регион поиска укажу.
У меня список из 14 чисел, и всегда выдает все 14.

init_arr %GetImage (1) 33, 218 133, 271

Поиграв немного с цифрами, в итоге нашел нужные мне координаты для одной строки. Координаты по X правильно работают, а вот по Y вообще минусовой пришлось указать (и то только стартовый указал, а второй оставил 0). Не совсем понятно почему так
init_arr %GetImage (1) 40, -1100 115, 0

Автор: DarkMaster 6.8.2023, 17:49

минусовые бывают при нескольких мониторах.

Автор: Skylos 8.8.2023, 17:42

Цитата(DarkMaster @ 6.8.2023, 20:49) *

минусовые бывают при нескольких мониторах.

У меня стояло 2 монитора может недели 2 назад. Но координаты на втором мониторе просто в +Х уходили.
А сейчас стоит только один, что то странное.
по цветам координаты все правильно находит

Автор: DarkMaster 15.8.2023, 18:37

А версия пилота последняя? А то там баг был в пилоте с координатами, ранние версии текущего скрипта их компенсировали, потом эта компенсация была убрана при фиксе пилота. Возможно просто несоответсвие версий. Скачайте последние, если у вас не таковвые.

Автор: Skylos 21.8.2023, 3:37

Цитата(DarkMaster @ 15.8.2023, 21:37) *

А версия пилота последняя? А то там баг был в пилоте с координатами, ранние версии текущего скрипта их компенсировали, потом эта компенсация была убрана при фиксе пилота. Возможно просто несоответсвие версий. Скачайте последние, если у вас не таковвые.

Скачал разные версии
Версия 2.42 (15.05.2021)
Также пробовал 2.40 и 2.41 и Nightversion
Все одинакаво

А вот скачал 2.40 b010
И все нормально отрабатывать стала, спасибо.

Автор: DarkMaster 21.8.2023, 16:26

а версия скрипта последняя? надо понять где расхождение пошло и фикс выложить(

Автор: Skylos 21.8.2023, 16:29

Цитата(DarkMaster @ 21.8.2023, 19:26) *

а версия скрипта последняя? надо понять где расхождение пошло и фикс выложить(

Версия скрипта та что в шапке
Поиск числа с помощью Findimage 4.0 (на языке пилота)

Автор: DarkMaster 21.8.2023, 16:35

Цитата
Поиск числа с помощью Findimage 4.0 (на языке пилота)

Понятно. Я эти моменты в lua версии фиксил. Сюда руки не совал - чужой код портить не есть правильно.

Автор: Edik2323 28.2.2024, 10:40

Добрый день!
Прошу помощи, почему вот на такой код, загрузка происходит только изображений с цифрами, знаки просто игнорируются и соответственно не распознаются?
И еще моментик, я же могу сопоставлять так сказать любую картинку но присвоить ей любой символ, верно?

local accuracy = 100
local deltaSpace = 3
local toNumber = 0
local durationMax = 1
local symbols = {
["a"] = { "a" },
["b"] = { "b" },
["0"] = { "0" },
["1"] = { "1" },
["2"] = { "2" },
["3"] = { "3" },
["4"] = { "4" },
["5"] = { "5" },
["6"] = { "6" },
["7"] = { "7" },
["8"] = { "8" },
["9"] = { "9" }
}
for symbolKey, symbolVariants in pairs(symbols) do
local variantsStr = table.concat(symbolVariants, ", ")
log(string.format("Для символа '%s' загружены варианты: %s", symbolKey, variantsStr))
end
local recognizedText = imageToString.get { { crds = { scanX, scanY, scanX + 537, scanY + 324, abs = 0 }, durationMax = durationMax, toNumber = toNumber, symbols = symbols, accuracy = accuracy, deltaSpace = deltaSpace } }
if recognizedText then
for i, line in ipairs(recognizedText) do
for j, word in ipairs(line) do
log(string.format("recognizedText[%d][%d]: %s", i, j, word))
end
end

Автор: Edik2323 28.2.2024, 14:33

Цитата(Edik2323 @ 28.2.2024, 10:40) *

Добрый день!
Прошу помощи, почему вот на такой код, загрузка происходит только изображений с цифрами, знаки просто игнорируются и соответственно не распознаются?
И еще моментик, я же могу сопоставлять так сказать любую картинку но присвоить ей любой символ, верно?

local accuracy = 100
local deltaSpace = 3
local toNumber = 0
local durationMax = 1
local symbols = {
["a"] = { "a" },
["b"] = { "b" },
["0"] = { "0" },
["1"] = { "1" },
["2"] = { "2" },
["3"] = { "3" },
["4"] = { "4" },
["5"] = { "5" },
["6"] = { "6" },
["7"] = { "7" },
["8"] = { "8" },
["9"] = { "9" }
}
for symbolKey, symbolVariants in pairs(symbols) do
local variantsStr = table.concat(symbolVariants, ", ")
log(string.format("Для символа '%s' загружены варианты: %s", symbolKey, variantsStr))
end
local recognizedText = imageToString.get { { crds = { scanX, scanY, scanX + 537, scanY + 324, abs = 0 }, durationMax = durationMax, toNumber = toNumber, symbols = symbols, accuracy = accuracy, deltaSpace = deltaSpace } }
if recognizedText then
for i, line in ipairs(recognizedText) do
for j, word in ipairs(line) do
log(string.format("recognizedText[%d][%d]: %s", i, j, word))
end
end

На самом деле может я мудрю и кто то просто подскажет как распознать все что есть в этой рамке, включая минусы и слеш, символы - и / можно заменить любыми буквами, я сконвертирую. Все статично, не переливается, не меняется, как фон так и сами цифры


Прикрепленные изображения
Прикрепленное изображение

Автор: DarkMaster 28.2.2024, 17:29

Вообще этим методом загрузки практически не пользовался. Попробуйте загружать папкой. Там есть второй вариант синтаксиса. Естественно спецсимволы в пути не все пройдут, т.е. придется конвертить. Но не уверен, что поднимать полный синтаксис будет проще.

Русская версия Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)