|
|
  |
Новая Версия Uopilot v.2.40 (05.11.2017), Официальный сайт. Скачать. Последняя версия. |
|
|
WKnight |
1.11.2018, 16:38
|
       
Разработчик UO Pilot'а
Сообщений: 1.639
Регистрация: 9.1.2006 Группа: Пользователи Наличность: 0
Пользователь №: 4.688

|
Цитата Возможно это: и Цитата Я же не для себя Исправил в 'findimage' поиск запомненной картинки в загруженной области. Требовало размер области больше положенного. Переделал в Lua функции 'findimage' и 'findcolor' на новый синтаксис, все параметры передаются по одному, через запятую. Путь к файлу и набор цветов пока передаются строкой в таблице (в фигурных скобках). Принимающий массив изъят из обращения. По синтаксису Lua в пути необходимо удваивать символ обратный слеш "c:\\", либо указывать путь в двойных квадратных скобках [[c:\]]. Функции возвращают массив (таблицу) найденных элементов и код ошибки. Пример: 'arr, err = findimage(10, 20, 1020, 810, {"C:\\tmp\\image.bmp"}, 2)' 'arr, err = findcolor(10, 20, 1040, 810, {"r(255)"}, 2, -1, "abs")'
|
|
|
|
DarkMaster |
3.11.2018, 16:56
|
          
Модератор UOPilot
Сообщений: 9.740
Регистрация: 2.12.2008 Группа: Супермодераторы Наличность: 29642
Пользователь №: 11.279

|
попробуйте явно указать метод: arr, err = findcolor(0, 0, 100, 100, 1, 1, {"r(0-255)"},2)
--------------------
Скрипты UOPilot под заказ. Консультации по UOpilot 15$/час. Услуги Lua разработчика (не пилот, проекты, постоянка) Disсоrd: Kov____
|
|
|
|
sutra |
3.11.2018, 17:15
|
      
Adept
Сообщений: 923
Регистрация: 10.8.2018 Группа: Пользователи Наличность: 0
Пользователь №: 19.007

|
r(0-255) диапазон так и не понял как искать ни в старом, ни в новом варианте. Цитата попробуйте явно указать метод Всяко пробовал. В новом синтаксисе вообще ничего не ищет. В смысле принимающий массив = nil arr, err = findcolor(0, 0, 199, 0, 1, 1, 0, 2) log(arr,err) -- получаю nil 200 Массива нет, а вместо кода ошибки - количество найденных пикселей. arr, err = findcolor(0, 0, 199, 0, 1, 1, {"r(0)"}, 2) log(arr,err) -- получаю nil 0 Диапазон вообще не ищет.
|
|
|
|
sutra |
6.11.2018, 2:34
|
      
Adept
Сообщений: 923
Регистрация: 10.8.2018 Группа: Пользователи Наличность: 0
Пользователь №: 19.007

|
Ещё давно возник у меня такой вопрос, конечно я обхожу эти "рифы", но решился всё-таки озвучить. Почему, например, такая конструкция у меня выполняется более 4 секунд?
set #tmp findcolor (244 639 825 922 1 1 (R(0-255)) %tmp)
Подозреваю, что что-то не так с массивом. Конечно корифеи скажут, а зачем такое вообще надо. Но мне часто требуется не просто искать конкретный цвет, а именно получить цвета всех пикселей конкретной зоны экрана (зачастую немаленькой, ввиду разброса объектов), желательно минимальным количеством вызова файнда, для детального анализа. Получать из памяти такой массив я пока не пробовал (жду доводки файнда). Но 4 секунды, на мой взгляд, как-то не вяжутся с логикой процесса.
Обработка в lua любого массива данных занимает доли секунды, вопрос как получить эти данные с минимальными затратами времени.
И всё-таки ещё раз "о главном". Конечно запрограммировать можно и "свалку" данных. Но не все будут этим заниматься, а на мой взгляд, нужна реализация поиска findcolor-ом цветовой разницы между RGB каналами. У меня без этого никак невозможно правильно запрограммировать поиск объектов при смене времени суток в игре.
Да и не только при смене времени суток, часто встречаются "переливающиеся" объекты, их тоже можно "вычислить" только анализом RGB.
|
|
|
|
sutra |
6.11.2018, 15:19
|
      
Adept
Сообщений: 923
Регистрация: 10.8.2018 Группа: Пользователи Наличность: 0
Пользователь №: 19.007

|
Я тестировал все функции связанные с обработкой изображений, от printscreen до getimage. И все они выполняются примерно 3 сотых секунды, хоть в Пилоте, хоть в lua. Собственно поэтому я и пытаюсь вызывать эти функции ОДИН раз, потому что весь остальной скрипт на lua (далеко не маленький) выполняется 13-18 ТЫСЯЧНЫХ секунды.
С загрузкой из файла массива, потом сохранением в файл (правда всё на RAM) и всего 18 тысячных.
readmem не совсем понимаю как пристроить под это дело. В lua я мало что знаю, раньше я просто использовал move в указатель, выделив соответствующую память.
Нужно Кнайту просто сделать этот самый move.
Насколько я понял getimage возвращает параметр длины 3 байта * кол-во пикселей + 2 байта.
Хотя наверное move не прокатит. 3 байта - это формат файла, их не пристроишь никак под переменные.
Проще наверное посмотреть, почему файнд так начинает тормозить.
|
|
|
|
DarkMaster |
6.11.2018, 18:28
|
          
Модератор UOPilot
Сообщений: 9.740
Регистрация: 2.12.2008 Группа: Супермодераторы Наличность: 29642
Пользователь №: 11.279

|
Цитата Вот если бы readmem мог считывать в побайтовый массив, типа как в строку, только без ограничения по длине. Тогда можно было бы сделать быстрый обработчик. Дык он и делает. Там в параметрах задается тип значения которое нужно считать. Байт - b. Для понимания, что именно вы читаете рекомендую сначала использовать writemem и редактировать область памяти с битовой маской. set %a GetImage (100 100 1000 1000) log %a [1 1] - адрес в памяти log %a [1 2] - ширина изображения log %a [1 3] - высота изображения log %a [1 4] - длина строки в байтах End_script Там есть тонкость - размер таблицы выравнивается по количеству байт кратному 4, если мне память не изменяет. Т.е. длина строки в любом случае будет кратная 4. Поэтому настоятельно рекомендую сначала разобраться c writemem, чтобы не путаться в чтении каналов. Это кстати косяк, т.к. выравнивание служит для увеличения скорости обработки процессором, но современные камни почему-то под кратность 10 точатся(для меня великая загадка почему 10 ибо это корявый размер во всех смыслах). Пытаюсь найти скрипт в котором все это делал - пока безрезультатно. Обработка изображения
Код --lua fileBinary = require"luaPlugins\\FileBinary"
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
log("clear")
-- Получаем изображение в массив. function imageToArray (startX, startY, endX, endY, appWindow) local bitmap = {} local address, w, h, l = getimage(startX, startY, endX, endY, appWindow) log (address, w, h, l, "n56") local pos = 1 for i=address, address + h*(l) - 1, l do for j=i, i+w*3 - 1 do bitmap[pos] = readmem(j .. " b") pos = pos + 1 end end saveimage(address, "d:\\!lua\\!test.bmp") deleteimage(address) return bitmap end
function binary(file, pos, val, i, j) file:seek("set", pos) if i == nil then i = 1 end if j == nil then j = #val - 1 else j = i + j - 1 end -- log(i, j) for i=i, j do file:write(string.char(val[i])) end end
-- file - хендл или имя файла -- w - ширина изображения -- h - высота изображения function writeBmp (file, bitmap, w, h) if type(file) == "string" then file = io.open(file, "w+b") end file:seek("set", 0)
local l = math.ceil (w*3/4) * 4 -- Длина строки с выравниванием. local alignment = l - w*3 local fileSize = l * h + 0x36 log(fileSize)
-- Заголовок file:write(string.char(0x42)) file:write(string.char(0x4D)) file:write(string.char( -- Размер файла. fileSize%256, floor(fileSize/256), floor(fileSize/65536), floor(fileSize/16777216))) file:write(string.char(0)) file:write(string.char(0)) file:write(string.char(0)) file:write(string.char(0)) file:write(string.char(0x36)) -- Оффсет на битовую маску. file:write(string.char(0)) file:write(string.char(0)) file:write(string.char(0)) file:write(string.char(0x28)) file:write(string.char(0)) file:write(string.char(0)) file:write(string.char(0)) file:write(string.char(floor(w%256))) -- Ширина file:write(string.char(floor(w/256))) file:write(string.char(0)) file:write(string.char(0)) file:write(string.char(floor(h%256))) -- Высота file:write(string.char(floor(h/256))) file:write(string.char(0)) file:write(string.char(0)) file:write(string.char(0x01)) file:write(string.char(0)) file:write(string.char(0x18)) file:write(string.char(0)) file:write(string.char(0)) file:write(string.char(0)) file:write(string.char(0)) file:write(string.char(0)) file:write(string.char(0)) file:write(string.char(0)) file:write(string.char(0)) file:write(string.char(0)) file:write(string.char(0x74)) file:write(string.char(0x12)) file:write(string.char(0)) file:write(string.char(0)) file:write(string.char(0x74)) file:write(string.char(0x12)) file:write(string.char(0)) file:write(string.char(0)) file:write(string.char(0)) file:write(string.char(0)) file:write(string.char(0)) file:write(string.char(0)) file:write(string.char(0)) file:write(string.char(0)) file:write(string.char(0)) file:write(string.char(0))
local i = #bitmap - w*3 + 1 for i = w*3*(h-1)+1, 1, -w*3 do -- log("!!!", #bitmap, file:seek() ,i, h, w, w*3, l) binary(file, file:seek(), bitmap, i, w*3) for j = 1, alignment do file:write(string.char(0)) end end
-- for pos=0x36, 0x36 + #bitmap - 1, l do -- log("!!!", #bitmap, pos ,i, h, w, w*3, l) -- binary(file, pos, bitmap, i, w*3) -- i = i - w*3 -- end end
function getAvg(path, appWindow, timeout, startX, startY, endX, endY) local countImages = 0 local w = endX - startX + 1 local h = endY - startY + 1 local s = w * h * 3 -- количество полезных пикселей (без выравнивания) local sum = {} -- сумма значений каждого канала всех изображений. for i = 1, s do sum[i] = 0 end -- Собираем изображения в течении заданного времени. local myTimer = os.clock() + timeout while myTimer > os.clock() do -- Массив со значениями каналов. local bitmap = imageToArray (startX, startY, endX, endY, appWindow) --table.show(bitmap) -- Суммируем изображения for i = 1, s do sum[i] = sum[i] + bitmap[i] end countImages = countImages + 1 end
-- Находим среднее значение local avg = {} for i = 1, s do avg[i] = sum[i] / countImages end --table.show(avg, "avg") writeBmp (path, avg, w, h) end
function getStatic (path, appWindow, timeout, startX, startY, endX, endY) local bitmap = imageToArray (startX, startY, endX, endY, appWindow) local w = endX - startX + 1 local h = endY - startY + 1 local countImages = 0 -- Собираем изображения в течении заданного времени. local myTimer = os.clock() + timeout local bench = os.clock() while myTimer > os.clock() do -- Массив со значениями каналов. local scr = imageToArray (startX, startY, endX, endY, appWindow) log("Битмап в массив за:" .. os.clock() - bench .. " сек.") bench = os.clock() -- Закрашиваем нестатичные пиксели. for i = 1, #bitmap, 3 do if bitmap[i ] ~= scr[i ] or bitmap[i+1] ~= scr[i+1] or bitmap[i+2] ~= scr[i+2] then
bitmap[i ] = 0 bitmap[i+1] = 255 bitmap[i+2] = 0 end end log("Поиск статики за:" .. os.clock() - bench .. " сек.") countImages = countImages + 1 end writeBmp(path, bitmap, w, h) end
if workwindow ~= tonumber(windowhandle()) then log("Привязка должна быть к пилоту.") workwindow = tonumber(windowhandle()) alarm("online") return end
startX, startY, endX, endY = 194, 286, 277, 434 appWindow = findwindow("Crossout 0.")[1][1] log(appWindow) --if 1 then return end
local cpuTime = os.clock() -- getAvg("d:\\!lua\\test" .. os.time().. ".bmp", appWindow, 5, startX, startY, endX, endY) getStatic("d:\\!lua\\test" .. os.time() ..".bmp", appWindow, 60, 193, 286 , 208, 432 ) getStatic("d:\\!lua\\test" .. os.time() ..".bmp", appWindow, 60, 193, 615 , 210, 762 )
log(os.clock() - cpuTime) alarm("online")
FileBinary
Код --lua
local binary = {}
function binary.getBitmapOffset(file) return binary.readInt(file, 0x0A) end
function binary.readInt(file, pos) file:seek("set", pos) local a = string.byte(file:read(1)) file:seek("set", pos + 1) local b = string.byte(file:read(1)) file:seek("set", pos + 2) local c = string.byte(file:read(1)) file:seek("set", pos + 3) local d = string.byte(file:read(1)) file:seek("set", pos + 4) return a + b * 256 + c * 65536 + d * 16777216 end
function binary.writeInt(file, pos, val) file:seek("set", pos) return file:write( string.char(math.fmod(val, 256), math.fmod(val, 65536)/256, math.fmod(val, 16777216)/65536, val/16777216) ) end
function binary.readByte(file, pos) file:seek("set", pos) return string.byte(file:read(1)) end
function binary.writeByte(file, pos, val) file:seek("set", pos) return file:write(string.char(val)) end
function binary.readArray(file, pos, sz) local result = {} file:seek("set", pos) local s = file:read(sz) for i=1, #s do table.insert(result,string.byte(string.sub(s, i, i))) end return result end
-- Пишет в бинарном виде данные в файл file -- начиная с позиции pos -- из таблицы или строки val -- начиная с позиции i внутри val -- размером j внутри val -- Запись полный тормоз. -- Массив 2.296 Мб/сек.
function binary.writeArray(file, pos, val, i, j) file:seek("set", pos) if i == nil then i = 1 end if j == nil then j = #val - 1 else j = i + j - 1 end log(i, j) for i=i, j do file:write(string.char(val[i])) end end
return binary
--f = io.open("d:\\test.bmp", "r+b") --log(f) --log(binary.readInt(f, 0)) --log(binary.writeInt(f, 0, 0x123456ab)) --log(dec2hex(v)) --v="1234567890" --log(string.byte(v, 1, 10)) --t = binary.readArray(f, 0, 4096)
--local j = 0 --local t = {} --for i = 1, 40100 do -- if j < 255 then -- j = j + 1 -- else -- j = 1 -- end -- t[i] = j --end --binary.writeArray(f, 0x36, t, 1, 40100)
--local j = 0 --local t="" --for i = 1, 40100 do -- if j < 255 then -- j = j + 1 -- else -- j = 1 -- end -- t = t .. string.char(j) --end -- --f:seek("set", 0x36) --myTimer = os.clock() --for i=1, 1000 do -- f:write(t) --end --log(os.clock() - myTimer)
Выложил ровно в том виде, в котором оно осталось. Это фактически были тесты производительности и возможностей. Т.е. там свинарник =) . FileBinary мог редактироваться отдельно и возможно не имеет обратной совместимости либо имеет баги. Сообщение отредактировал DarkMaster - 6.11.2018, 18:29
--------------------
Скрипты UOPilot под заказ. Консультации по UOpilot 15$/час. Услуги Lua разработчика (не пилот, проекты, постоянка) Disсоrd: Kov____
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|