Данный скрипт предназначен для распознавания чисел, текста и различных символов (например, значков серебра, голда).
Есть 2 версии скрипта: одна на языке пилота, вторая на языке lua.
Версия 1 (на языке пилота):
Минимальная версия пилота 2.39. Запускать от администратора.
// Поиск числа с помощью 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] - координаты числа
версию лучше прилепить.
Добавил в первый пост вторую версию скрипта.
Ух ты, а какие примерно картинки должны быть? Что в них нарисовано? Просто цифры на белом фоне?
Спасибо суперский скрипт, работает отлично.
Только как сделать чтобы результат найденный был таким, что если найдена 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
///////// начало скрипта //////////
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
Спасибо всё получилось
А есть ли в пилоте команда- возврат на предыдущий цикл или перепрыгнуть 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
Вопросы, не касающиеся скрипта для поиска числа, задавайте в другой теме, чтобы не засорять эту.
Используйте gosub: http://uopilot.tati.pro/index.php?title=Gosub
Привет, есть такая картинка
как видно золото серебро и медь, цифры разными цветами.
Как реализовать максимально быстрый поиск? Чтобы в итоге пилот выдал число 012665.
Может ли пилот определять цифры, если они разными цветами? или же для каждого цвета придется делать 3 отдельных поочередных поиска?
Еще проблема число бывает таким
т.е. отсутствует число серебра например если оно равно нулю,
тут нужно чтобы пилот выдал результат 020046, вместо отсутствующего цвета числа подставлялось 00.
В итоге нужно делать 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
как правильнее реализовать 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
возник еще 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 число подставлял?
Чуть подробнее объясню
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
Иногда помогает отключить сглаживание шрифтов.
разобрался)
// поиск картинок и их сортировка
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, так же поиск будет дольше
#accuracy -1 #deviation вместо -1, надо 1
не, это не работает, он все равно лопатит всю строку, находит 3 картинки и пишет 3 раза число
// Поиск статичных точек на нескольких картинках
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
set #deviation 3 // указывать ту же (или больше) погрешность что и при сравнении картинок
// Поиск числа с помощью 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
// Поиск числа с помощью 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
// Поиск числа с помощью 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 поиска по 30+ картинок. Только если меньше картинок искать. Попробуйте скриптом, который выше, сделать из нескольких картинок одну.
4 картинки одной цифры сделал. Вообщем она полностью в красный закрашивается при #deviat 10
Архив с картинками прилепил, может что не так делаю.
А может можно искать картинку по вырезанному фону?)))
Прикрепленные файлы
22.rar ( 1,43 килобайт )
Кол-во скачиваний: 1755
Пусть будет больше deviation, тогда меньше закрасит. В любом случае искать 1 картинку быстрее, чем 4.
// Поиск статичных точек на нескольких картинках
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
set #deviation 3 // указывать ту же (или больше) погрешность что и при сравнении картинок
// Закрашивание фона
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
// Закрашивание фона
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
Можете чуть пояснить как 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
Кто-то писал когда-то :
Точность = (количество_совпавших_точек)/(sizeX*sizeY - 1)
Точность = (количество_совпавших_точек)/(sizeX*sizeY - количество_пикселей_фона)
Картинка 5*7, 35 пикселей, 17 закрашиваем, значит 18 остаётся.
По идее так:
18 * 100 / (5 * 7 - 17) - 100%, если нашлось 18 из 18 не закрашенных пикселей.
9 * 100 / (5 * 7 - 17) - 50%, если нашлось 9 из 18 не закрашенных пикселей.
Небольшой пример, есть 2 картинки (8х12)=96px с 50% закрашенным фоном, если присмотреться то верхушки картинок абсолютно схожи и если ставить точность поиска 50%, то в одной картинке поиск находит сразу две.
96 пикселей из них 49 пикселей это фон и другие 47 картинка
Пилот ищет по 47 пикселям
50% от 47 = 23,5
(50 × (1 / 100) × 47 = 23,5)
т.е. найдя 23 пикселя, пилот скажет, что картинка найдена
Прогнал через поиск 100 раз картинку 180х280px с разными параметрами и немного удивился.
Оказывается точность вообще на время поиска не влияет.
а вот #deviation
а где написано было ,что точность влияет на поиск ? Точность вообще ,грубо говоря, производная поиска. И к нему вообще не имеет отношения.
отклонение цвета же имеет прямое отношение к поиску и от него зависит кол-во цветов для сравнения.
Точность = (количество_совпавших_точек*100)/(sizeX*sizeY - количество_пикселей_фона)
Ок. Как тогда объяснить, что при больших значениях deviation, здоровых изображениях с большим фоном и малой точности % совападения зависит от выставленного минимального?
т.е. берем некторое изображение и ищем его 2 50 1 20
результат точности: 54%
увеличиваем минимальную точность 2 75 1 20
результат точности: 76%
увеличиваем еще 2 80 1 20
результат точности: не нашло.
Это ситуация встречалась на практике у меня не 1 и не 2 раза. Проявляется она в тяжелых случаях, как правило при поиске изображений обезображенных переливами jpg.
Можно ли как то прописать поиск не из заданной области экрана, а из картинки
например:
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)
Без сохранения в файл:
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])
Спасябки
Кстати а изменения можно посредством пилота внести в сохраненное изображение?
Сделать например изображение черно белым и уже потом поиск в нем произвести?
И можно ли чтобы картинка сохранялась новая, а не заменялась старая
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:\
Вопросы не касающиеся поиска числа задавайте в другой теме, лучше новой.
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
так это-же для поиска чисел) цветных
я тут подумал, что если картинку с цифрой перед поиском делать черно-белой, то можно будет более быстрее находить)
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
Консольное изменение изображений (консольный фотошоп)
1. Скачиваем программу ImageMagick http://www.imagemagick.org/script/download.php
Крутим страницу в самый низ и скачиваем по последней ссылке ImageMagick-7.0.5-7-portable-Q16-x64.zip (для 64 винды)
это версия в архиве, не требующая установки- другие версии не заработали у меня чет)
2. Для удобства распаковываем в папку C:\Magic
3. Готово
теперь в пилоте вместо обычного поиска картинки:
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
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
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
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 (С:\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
// Поиск числа с помощью 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
Находим строку:
set %get GetImage(#GetStartX #GetStartY #GetEndX #GetEndY) // сохранить часть экрана в память
set %get GetImage(#GetStartX #GetStartY #GetEndX #GetEndY workwindow)
Уважаемый cirus, а как быть если к примеру "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
Спасибо cirus , Вы Молодец!
Уважаемый cirus , Не могли бы Вы мне помочь с кодом, у меня в игре есть 4ре ячейки с мобами, и я хотел последовательно проверять уровень мобов в каждой из ячеек, верхнюю правую нижнюю левую, картинки с цифрами все подготовил, а вот код не могу сформулировать в голове, и самое печально то, что для каждой ячейки с мобами идут свои картинки с цифрами, т.е у меня сейчас 4ре папки с картинками, собственно сам вопрос заключается в том, как мне прописать допустим в общем скрипте проверку всех четырёх ячеек с мобами и если к примеру моб достиг 25 лвла кликнуть по нему, ну с кликами я сам разберусь, самое главное проверку сделать, прилагаю скриншот для наглядности, спасибо за ранее если сможете мне помочь.
Извиняюсь если не по теме написал.
Эскизы прикрепленных изображений
Теоретически можно искать все числа сразу, но надо тестить. Скиньте мне все картинки с цифрами и несколько картинок в 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
// Поиск числа с помощью 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
вот файлики, Спасибо не земное!!! )
Прикрепленные файлы
mob_lvls.7z ( 4,18 килобайт )
Кол-во скачиваний: 360
mobs_images.7z ( 156,94 килобайт )
Кол-во скачиваний: 357
Можете ещё попробовать искать сразу все картинки. Код добавил в пост выше.
Искать сразу все очень долго, картинок очень много просто около 50ти.,
да и действия требуются для каждого моба отдельно, к примеру не достиг максимального уровня, пропускаем его, если прокачался максимально, ткнуть на моба, он автоматически убирается, и на его нужно будет впихнуть другого моба, ну это уже будет другая подпрограмма )
Спасибо огромное cirus, сейчас буду тестировать!
if %result [2 2] = 25
left Кординаты правого моба
end_if
Числа расположены по строкам и столбцам.
[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
%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
// Или циклом проверять все элементы массива.
Все работает, как часы, у меня еще один вопрос, а можно к примеру искать на мобе сразу два числа, к примеру моб 6-ти звездный и 25 лвл, как это это можно идентифицировать? Есть ли возможность одним вашим скриптом обойтись?
Проще сделать отдельную подпрограмму для поиска звёзд. Координаты числа известны, т. е. можно вычислить область поиска звёзд для конкретного моба.
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
Если бы всегда было 4 моба, то и проблем не было. А так не удобно соотносить какое число к какому мобу относится.
Что то не пойму как сравнить звезды с уровнем (
Подскажите нубу...
Мне картинки звезд делать уже каждую по отдельности или целиком ***** всю группу, что то запутался
Смотря что требуется. Если нужно знать точное количество звёзд, то делать картинку 1 звезды. Если интересует только когда 6 звёзд, то можно и целиком искать. Кстати, звёзды тоже отличаются, так что либо точность снижать и добавлять погрешность в цвете, либо сделать несколько картинок и сравнить скриптом.
Нужно искать группу звезд:
** - звезды (максимальный лвл с этими звездами ) - 20
*** - звезды (максимальный лвл с этими звездами ) - 25
**** - звезды (максимальный лвл с этими звездами ) - 30
***** - звезды (максимальный лвл с этими звездами ) - 35
****** - звезды (максимальный лвл с этими звездами ) - 40
Суть моей задумки, проверять моб достиг максимального уровня или нет, просто у мобов разный максимальный уровень в зависимости от количества звезд.
Уважаемый cirus, Вы мне и так сильно помогли, я очень благодарен Вам.
Если есть возможность подсказать кодом, буду Вам очень благодарен!
cirus, в код скрипта какие-то изменения будешь вносить в ближайшее время? Если собираешься, просьба это сделать.
Правка мелкая пару строчек, по сути не повлияет на работу. Но, проще самому скрипт написать, чем чей-то переписывать. Если надо могу написать принцип работы, но это ночью. Ушёл на работу.
Смысл писать то, что уже написано и потом баги ловить? Принцип я понимаю. Более того могу сам пару таких принципов написать) Тут вопрос отладки и ошибок по невнимательности.
еще бы кто-то с goto не позорился)))
// Поиск числа с помощью 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
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
cirus Огромное Вам спасибо, благодаря Вам, понимаю что сделать можно все, вы вдохновляете нубов как я на изучение программирования в целом! )))
кхе... думал часа за 2 перепишу) вобщем формат хранения данных в пилотовском синтаксисе и lua сильно различаются и прозрачно делать не везде получается, а где-то очень кощунственно выглядит и приходится подправлять. Делаю под красивые луашные вызовы. Это я все к чему, если собирался переписывать - погоди чуток, чтобы вместе одно и то же не делали.
В ближайшее время не соберусь. Вдохновение ещё не пришло.
Бетка распознавания текста. Буду благодарен за тесты и багрепорты, т.к. времени катастрофически не хватает.
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
-- Вместо этого:
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
Исправь:
DeleteImage(buffer[filePath])
deleteimage(buffer[filePath])
for i=1, 10000, 1 do
v = getimage(0, 0, 1920, 1080, workwindow)
deleteimage(v)
end
Передавая в 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
А по адресу можно определить высоту/ширину изображения? Чтобы не передавать кучу параметров вместо одного, если в функцию передается источник изображения? Всмысле по-человечески. Понятно, что можно взять readmem и понеслался...
symbols = {
"0" = {"zero1", "zero2"},
"1" = {"1a", "1b"},
"2" = {"two", "second"}
}
symbols = {
["0"] = {"zero1", "zero2"},
["1"] = {"1a", "1b"},
["2"] = {"two", "second"}
}
Первый пост почистил.
default.loadPath = nil -- Путь по которому будут загружены все изображения с указанными расширением. Имя файла будет соответсвовать имени символа.
fileList = dir(options.path, options.ext)
fileList = dir(options.path, "*" .. options.ext .. "*")
Кое-что пофиксил, добавил, переработал. В целом можно назвать релиз кандидатом. По функционалу есть вопрос: нужна ли возможность одновременно указать несколько источников изображений? Умолчательные, перечисленные, папку? Несколько папок (подпапки можно уже сейчас)?
-- Баг: из-за особенностей костыля финдимиджа создается НЕ локальня переменная 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
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
Если замечаний нет, то можно в первый пост, да начну документацию писать.
// Автор скрипта 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
result = imageToString{crds={33, 189 ,292, 255}}
result = imageToString{crds={33, 189 ,292, 255}}
Фишки луа, которые не учел. Тут же arr={} не таблица, а только ссылка на таблицу и копирование arr2=arr1 не проходит - данные не копируются.
--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
-- Автор скрипта 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
Если так понятнее:
result = imageToString{crds={33, 189, 292, 255},
loadFolder = {path="C:\\l2number3", mask="*bmp", sub=1}}
Эмм? И как это может привести к перезаписи значений по умолчанию? Более того у меня два подобных вызова подряд стоят еще с прошлого теста (т.е. всего 4: два на символы, два на папки).
Вообще проблема была вызвана обработкой при которой синтаксис приводился к единообразию и это единообразие запихивалось в умлочание. С остальными таблицами этого даже представить не могу, т.к. их значения нигде не изменяются и ссылки там на самом деле достаточно. Даже если в умлочаниях вместо nil'ов что-то задать, то это не приведет как каким-то последствиям. Там весь скрипт общается с переданными параметрами только в режиме read-only. Исключение было в символах и это даже где-то ошибка проектирования ибо входящие параметры в моем понимании скорее не стоит изменять и проще завести новый массив под это дело, но проблему бы это не решило, т.к. все равно пришлось бы копирование прикручивать.
result = imageToString{crds={33, 189, 292, 255},
loadFolder = {path="C:\\l2number3", mask="*bmp", sub=1}}
default.loadFolder = {path="C:\\l2number3", mask="*bmp", sub=1}
проблемы какие-то остались? копирование остальных массивов чем-то обусловлено кроме подозрений?
Данный скрипт предназначен для распознавания чисел, текста и различных символов (например, значков серебра, голда). Скрипт учитывает возможные пробелы и переносы строк. Параметры в квадратных [] скобках являются не обязательными, параметры в угловых скобках <> указываются всегда. Квадратные и фигурные скобки при вызове функций не пишутся, они лишь указывают возможность не задавать параметр. Фигурные {} и круглые () скобки пишутся, там где указаны. Символ '|' означает исключающее или, например, 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],...}
Съешь еще
этих
мягких французских булок.
t[1][1] -- Съешь
t[1][2] -- еще
t[2][1] -- этих
t[3][1] -- мягких
t[3][2] -- французских
t[3][3] -- булок
--lua
table = {}
table.insert (table, 10) -- получим ошибку
Что-то накалялкал. И даже почти все тодо сделал.
Осталось понять, что за бред с вызовами a ={params}. Возможно придется скобки лепить...
Скачать скрипт:
FindString.lua_1.0.zip ( 9,55 килобайт )
Кол-во скачиваний: 232
--Получение текста из изображения:
t = imageToString.get{[parms],[parms],[parms],...}
--Управление буфером:
--Добавление изображения в буфер (вернет адрес):
imageToString.buffer.add(<путь>, [адрес])
--Получение адреса в памяти загруженного в буфер изображения:
imageToString.buffer.get(<путь>)
--Удаление изображения из буфера:
imageToString.buffer.delete(<путь>)
--Полная очистка буфера:
imageToString.buffer.flush()
t = imageToString.get{[parms],[parms],[parms],...}
Съешь еще
этих
мягких французских булок.
t[1][1] -- Съешь
t[1][2] -- еще
t[2][1] -- этих
t[3][1] -- мягких
t[3][2] -- французских
t[3][3] -- булок
Потестил этот баг.
1. Ищет не от левого верхнего угла, а от левого нижнего.
2. endX = endX - startX
Ну переворачивать весь массив в обратную сторону смысла слава богу нет - сам перевернется при сортировке.
Координату костыль прилепил. В описании сделал пометку.
Прикрепленные файлы
FindString.lua_1.0.1.zip ( 9,69 килобайт )
Кол-во скачиваний: 152
Начальную координату X нужно прибавлять к конечной, т. к. findimage её отнимет. С координатой X решилось, а вот с Y всё не так просто. Там такой же косяк с вычитанием начальной координаты, но даже не это главное. Ищет снизу, т. е получается вот такая фигня:
В общем что-то там напутано с Y, я так и не понял до конца как оно ищет.
Исправил:
startX, startY, endX, endY = options.crds[1], 0, options.crds[3] + options.crds[1], height
-- Удаление лишнего по 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
imageToString["buffer"]["get"]("C:\\l2number\\1.bmp")
Правок больше не будет? X, Y все поправлено? Переименовываю функции и все?
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
------------
Ну что... Опять что попало...
Кароче говоря он не хочет нормально вложенные функции воспринимать нормальным синтаксисом. Только через доп скобки квадратные/круглые.
Проблема в том, что как только ты подключаешь это дело через require, то уровень вложенности сразу на единичку повышается. Суть проблемы:
imageToString.get - без require работает
imageToString["get"] - с require только так
С буфером подавно проблемы, т.к. там вложенность еще больше. И че делать будем?
У меня так работает без проблем.
--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)
Мде... У меня подобные финты не проходят. Ничего не понимаю...
Кстати мы два балбеса) Тесты вдоль и поперек. Вот только числа стрингом возвращает)) Ща серьезный тест дал в реальных условиях и никак понять не мог почему сравнение чисел идет ошибочное. Причем собака на 164 предмете сбилось)) Надо прикрутить конвертацию опциональную.
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"} -- какие выводить массивы
}
Можно и 2. У меня все равно будет workwindow) Но для остальных это может быть действительно правильным.
Обновил мануал, там же новая версия с преобразованием и новыми костылями.
подчистил вывод в лог.
buffer.add возвращает адрес.
Я так и не понял как теперь imageToString.get вызывается.
через фигурные скобки.
--lua
require ("FindString")
t = imageToString.get{path="C:\l2number"}
там реквайр теперь другой. теперь только чистая функция. Поддерживать два синтсаксиса, каждый из которых с багами нереально. Возможно будет замена crystal lua на luajit, но там писанины много относительно кристал. Проблемы с прослойкой между пилотом и либой.
Мануал вроде прилизывал под все вызовы, чтобы как раз проблем не было.
Исправь default.window на 2.
if options.toNumber == 1 then
-- Полностью очищаем массив.
function imageToString.buffer.flush()
for k,_ in pairs(buffer) do buffer[v] = nil end
end
либо
_, v
v = nil
это шустрее должно быть кстати.
Пасиб, починил.
доброго времени, попробовал как работает на этом примере, но что то не оч получилось не находит искомое, или я чтот не так делаю, в этом месте (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
Давайте не будем засорять тему вопросами, которые не имеют отношения к данному скрипту.
Лучше создать отдельную тему.
Собственно совсем забылось. Прикрепи в первый пост, тему помню ты хотел почистить, если есть желание.
Прикрепленные файлы
FindString.lua ( 40,39 килобайт )
Кол-во скачиваний: 302
Как с помощью данного скрипта вывести значения картнок в таблицу из массива?
Есть стандартное поле с условно-рандомно генерируемых цифр разделенных сеткой
нужно записать значение по боксам
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столбца
Нужно ли прописывать для каждой ячейки область поиска или можно сделать лишь задав одну, а найденные изображения(цифры) можно будет записать с лево на право и с верху вниз???
Можно обойтись одной областью, но скрипт нужно обновить. У меня походу монитор накрылся... Не могу сделать это прямо сейчас...
Скрипт из нестабильной версии. Вроде был рабочий =)
Прикрепленные файлы
FindStringDev.lua ( 40,94 килобайт )
Кол-во скачиваний: 224
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) -- Координаты поиска.
В общем понял, что ничего не понял...язык пилота мне понятнее.
Cirus что может быть запускаю скрипт на языке пилота доходит до строчки:
call test %picture %symbol %GetImage %path #deltaY #deltaspace #accuracy #deviation #wait #timeproc #repeatimage // процедура поиска
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
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
Можно ли возвращать результат работы скрипта(числа) через вызов процедуры? Отправить скрипту координаты, он находит числа и возвращает строку
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
Не совсем понял почему в скрипте на пилоте так много букв!?
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 )
Встроил в скрипт часть кода для проверки баланса на персах, но есть ошибки в его работе... Когда этот код работает сам по себе то нормально распознает значения. Но если его встроить то сперва работает нормально, но спустя некоторое время дает неверные значение. Если число баланса состоит равно или больше из трех цифр то все четко, но если число менее 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
Перед этой строкой:
set size(%field) // удалить массив
Cirus, настроил в вашем варианте очень маленький диапазон поиска цифр: init_arr %GetImage (1) 949 269 1004 289 а выдал он цифр во всплывающем окошке, гораздо больше чем там в действительности:
Добрый день. А можно попросить боевой рабочий пример использования этого скрипта в варианте lua?
А то что-то с циферками из блокнота не выходит - плюется в меня рантайм-еррором .
На всякий случай цепляю тестовый шот из блокнота и вырезанные оттуда циферки.
test.zip ( 43,35 килобайт )
Кол-во скачиваний: 422
Можно ваш вызов увидеть?
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])
Добрый день. Не могу разобраться с пробелами- в result111.txt и в лог записывает слово и цифру слитно. Как разбить, помогите, пожалуйста!
Разобрался, ссори
Lua версия скрипта обновлена до версии 1.0.8
Я обновлял версию для луа. У вас вопрос версии для старого синтаксиса судя по скриншоту. Это два разных скрипта Вас какой именно интересует?
Lua версия обновлена.
1.0.9
Добавлено: установление приоритетов символов при удалении дублей. 4 и 1 - будет удалено 1, O и Q удалено O и т.д.
Добавлено: пример вызова, пример для сбора табличных данных.
Фикс: исправлены проблемы findimage пилота при поиске в уже загруженном изображении (getimage/loadimage)
в другом решении видел фичу обучения распознавания. У нас не планируется подобное ? С дублями может помочь ну и при большом наборе обучающей выборки (а ее можно делать автоматически) точность хорошая будет.
Я про оба варианта. OCR имхо не имеет существенного смысла ввиду нестабильности. Мой вариант поэтом жив и боюсь будет жить еще очень долго. Вопрос во времени для развития.
Пробую скрипт на языке пилота
Не могу понять как указать регион поиска чисел.
Почему- то всегда ищет по всему окну неважно какой регион поиска укажу.
У меня список из 14 чисел, и всегда выдает все 14.
init_arr %GetImage (1) 33, 218 133, 271
Поиграв немного с цифрами, в итоге нашел нужные мне координаты для одной строки. Координаты по X правильно работают, а вот по Y вообще минусовой пришлось указать (и то только стартовый указал, а второй оставил 0). Не совсем понятно почему так
init_arr %GetImage (1) 40, -1100 115, 0
минусовые бывают при нескольких мониторах.
А версия пилота последняя? А то там баг был в пилоте с координатами, ранние версии текущего скрипта их компенсировали, потом эта компенсация была убрана при фиксе пилота. Возможно просто несоответсвие версий. Скачайте последние, если у вас не таковвые.
а версия скрипта последняя? надо понять где расхождение пошло и фикс выложить(
Добрый день!
Прошу помощи, почему вот на такой код, загрузка происходит только изображений с цифрами, знаки просто игнорируются и соответственно не распознаются?
И еще моментик, я же могу сопоставлять так сказать любую картинку но присвоить ей любой символ, верно?
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
Вообще этим методом загрузки практически не пользовался. Попробуйте загружать папкой. Там есть второй вариант синтаксиса. Естественно спецсимволы в пути не все пройдут, т.е. придется конвертить. Но не уверен, что поднимать полный синтаксис будет проще.
Русская версия Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)