|
|
  |
Помогите освоить LUA |
|
|
sutra |
19.11.2018, 8:57
|
      
Adept
Сообщений: 923
Регистрация: 10.8.2018 Группа: Пользователи Наличность: 0
Пользователь №: 19.007

|
Код --lua local ffi = require "ffi" ffi.cdef[[ typedef struct { uint16_t x; uint16_t y; uint8_t red; uint8_t green; uint8_t blue; } rgba_pixel; ]] function FindRGB(addr,len,scrX1,scrY1,fx1,fy1,fx2,fy2,usl,numf) -- Функция поиска RGB в области памяти -- addr,len : адрес в памяти и длина строки в памяти (те, что даёт getimage) -- scrX1,scrY1 : координаты верхнего левого угла скрина в памяти, аналогичны координатам getimage (конечные X и Y не требуются) -- fx1,fy1,fx2,fy2 : координаты поиска, абсолютные относительно рабочего окна. Обязательно должны быть внутри диапазона скрина. -- usl : условие поиска ОДНО, по принципу ужесточения параметров "R(0-255) G(70-90) B(50) R-G[10 80] R-B[-40 -20] G-B[15]" (G-B[15] идентично G-B[15 255] - разность -- между каналами с возможностью интервала) -- numf : максимальное количество искомых пикселей local rmem = require "ffi".cast local n=(fx2 - fx1+1)*(fy2-fy1+1) -- если будет работать, сделать минимум по параметру numf local arr = ffi.new("rgba_pixel[?]", n ) local _,_,r1,r2=usl:find("R%((%d+)%-*(%d*)") r1,r2=tonumber(r1),tonumber(r2) -- Получение синтаксических значений поиска по каналу RED local _,_,g1,g2=usl:find("G%((%d+)%-*(%d*)") g1,g2=tonumber(g1),tonumber(g2) -- Получение синтаксических значений поиска по каналу GREEN local _,_,b1,b2=usl:find("B%((%d+)%-*(%d*)") b1,b2=tonumber(b1),tonumber(b2) -- Получение синтаксических значений поиска по каналу BLUE local _,_,RG1,RG2=usl:find("R%-G%[(%-*%d+)%s*(%-*%d*)") RG1,RG2=tonumber(RG1),tonumber(RG2) local _,_,RB1,RB2=usl:find("R%-B%[(%-*%d+)%s*(%-*%d*)") RB1,RB2=tonumber(RB1),tonumber(RB2) local _,_,GB1,GB2=usl:find("G%-B%[(%-*%d+)%s*(%-*%d*)") GB1,GB2=tonumber(GB1),tonumber(GB2) if r1==nil then r1,r2=0,255 else if r2==nil then r2=r1 end end if g1==nil then g1,g2=0,255 else if g2==nil then g2=g1 end end if b1==nil then b1,b2=0,255 else if b2==nil then b2=b1 end end if RG1==nil then RG1,RG2=-255,255 else if RG2==nil then RG2=255 end end if RB1==nil then RB1,RB2=-255,255 else if RB2==nil then RB2=255 end end if GB1==nil then GB1,GB2=-255,255 else if GB2==nil then GB2=255 end end local k,indY,ind,r,g,b=0 for i=fy1,fy2 do indY=addr+(i-scrY1)*len for j=fx1,fx2 do ind=indY+(j-scrX1)*3 b=rmem("unsigned char*", ind)[0] g=rmem("unsigned char*", ind+1)[0] r=rmem("unsigned char*", ind+2)[0] if r>=r1 and r<=r2 and g>=g1 and g<=g2 and b>=b1 and b<=b2 and r-g>=RG1 and r-g<=RG2 and r-b>=RB1 and r-b<=RB2 and g-b>=GB1 and g-b<=GB2 then k=k+1 arr[k].x=j arr[k].y=i arr[k].red=r arr[k].green=g arr[k].blue=b if numf==k then return arr end end end end return arr end
log "clear" log "mode compact" local addr, width, height, len = getimage (0, 0, 9, 9) local vi={} tmm = os.clock() for i=1, 300 do vi=FindRGB(addr,len,0,0,0,0,9,9,"R(0-255)",10000000) end log(os.clock()-tmm) deleteimage(addr) log(#vi) -- ошибка, если заремарить - ошибка закрытия lua
С мелочами пока не стал разбираться, пробовал делать однотипными элементы таблицы - результат тот же. Пробовал вообще делать таблицу глобальной - результат тот же. Пробовал запускать пример - всё работает. Причины ошибок мне не понятны. По логике - проблема вроде как в размерности таблицы.
|
|
|
|
DarkMaster |
20.11.2018, 1:03
|
          
Модератор UOPilot
Сообщений: 9.764
Регистрация: 2.12.2008 Группа: Супермодераторы Наличность: 29941
Пользователь №: 11.279

|
Цитата log(#vi) -- ошибка, если заремарить - ошибка закрытия lua Дык конечно ошибка =) Вы пытаетесь получить размер массива си структур оператором который возвращает размер массива луа(он по сути является скрытым полем таблицы). Я более того скажу, даже если вы попытаетесь получить размер массива внутри си, то у вас будут те же самые проблемы. Дело в том, что массив созданный даже в нормальной си-программе в пределах одной функции передается в другую функцию по указателю/ссылке (суть одна и та же - просто адрес в памяти 32/64 бита в зависимости от разрядности). Это приводит к тому, что создав массив в функции А мы не можем получить его размер в функции В, т.к. в функцию В прилетает только адрес этого массив. Размер в таком случае передается дополнительной переменной. На самом деле мой косяк - хотел предупредить и забыл. Сообщение отредактировал DarkMaster - 20.11.2018, 1:05
--------------------
Скрипты UOPilot под заказ. Консультации по UOpilot 15$/час. Услуги Lua разработчика (не пилот, проекты, постоянка) Disсоrd: Kov____
|
|
|
|
sutra |
20.11.2018, 1:12
|
      
Adept
Сообщений: 923
Регистрация: 10.8.2018 Группа: Пользователи Наличность: 0
Пользователь №: 19.007

|
Перевёл ещё один "хитрый" блок на lua, всё чудно работает, теперь не думаю про дополнительные операторы (if и for). Усилил логику за счёт добавления ифов и форов и за счёт расширения диапазона проверок и количества вызова файнда, всё мгновенно и точно на 100%. Как и обещал, да хоть блоху. Улучшился анализ временнЫх параметров, по факту время тратится только на getimage. Но за один такой вызов "высасываю" максимум возможного, да ещё и с предсказанием дальнейших действий. Цитата Вы пытаетесь получить размер массива си структур Если заремарить - ошибка закрытия lua. Цитата Дык конечно ошибка Дарк, у меня нет сомнений, что косячу я, у меня нет сомнений, что можно сделать ВСЁ. Но только как это сделать я пока не знаю.
|
|
|
|
DarkMaster |
20.11.2018, 1:16
|
          
Модератор UOPilot
Сообщений: 9.764
Регистрация: 2.12.2008 Группа: Супермодераторы Наличность: 29941
Пользователь №: 11.279

|
Код print = log print "clear" print "mode compact"
local ffi = require "ffi" local rmem = ffi.cast ffi.cdef[[ typedef struct { uint16_t x; uint16_t y; uint8_t red; uint8_t green; uint8_t blue; } rgba_pixel; ]] function FindRGB(addr,len,scrX1,scrY1,fx1,fy1,fx2,fy2,usl,numf) -- Функция поиска RGB в области памяти -- addr,len : адрес в памяти и длина строки в памяти (те, что даёт getimage) -- scrX1,scrY1 : координаты верхнего левого угла скрина в памяти, аналогичны координатам getimage (конечные X и Y не требуются) -- fx1,fy1,fx2,fy2 : координаты поиска, абсолютные относительно рабочего окна. Обязательно должны быть внутри диапазона скрина. -- usl : условие поиска ОДНО, по принципу ужесточения параметров "R(0-255) G(70-90) B(50) R-G[10 80] R-B[-40 -20] G-B[15]" (G-B[15] идентично G-B[15 255] - разность -- между каналами с возможностью интервала) -- numf : максимальное количество искомых пикселей local n=(fx2 - fx1+1)*(fy2-fy1+1) -- если будет работать, сделать минимум по параметру numf local arr = ffi.new("rgba_pixel[?]", n ) local _,_,r1,r2=usl:find("R%((%d+)%-*(%d*)") r1,r2=tonumber(r1),tonumber(r2) -- Получение синтаксических значений поиска по каналу RED local _,_,g1,g2=usl:find("G%((%d+)%-*(%d*)") g1,g2=tonumber(g1),tonumber(g2) -- Получение синтаксических значений поиска по каналу GREEN local _,_,b1,b2=usl:find("B%((%d+)%-*(%d*)") b1,b2=tonumber(b1),tonumber(b2) -- Получение синтаксических значений поиска по каналу BLUE local _,_,RG1,RG2=usl:find("R%-G%[(%-*%d+)%s*(%-*%d*)") RG1,RG2=tonumber(RG1),tonumber(RG2) local _,_,RB1,RB2=usl:find("R%-B%[(%-*%d+)%s*(%-*%d*)") RB1,RB2=tonumber(RB1),tonumber(RB2) local _,_,GB1,GB2=usl:find("G%-B%[(%-*%d+)%s*(%-*%d*)") GB1,GB2=tonumber(GB1),tonumber(GB2) if r1==nil then r1,r2=0,255 else if r2==nil then r2=r1 end end if g1==nil then g1,g2=0,255 else if g2==nil then g2=g1 end end if b1==nil then b1,b2=0,255 else if b2==nil then b2=b1 end end if RG1==nil then RG1,RG2=-255,255 else if RG2==nil then RG2=255 end end if RB1==nil then RB1,RB2=-255,255 else if RB2==nil then RB2=255 end end if GB1==nil then GB1,GB2=-255,255 else if GB2==nil then GB2=255 end end
local k,indY,ind,r,g,b=-1 for i=fy1,fy2 do indY=addr+(i-scrY1)*len for j=fx1,fx2 do ind=indY+(j-scrX1)*3 b=rmem("unsigned char*", ind)[0] g=rmem("unsigned char*", ind+1)[0] r=rmem("unsigned char*", ind+2)[0] if r>=r1 and r<=r2 and g>=g1 and g<=g2 and b>=b1 and b<=b2 and r-g>=RG1 and r-g<=RG2 and r-b>=RB1 and r-b<=RB2 and g-b>=GB1 and g-b<=GB2 then k=k+1 arr[k].x=j arr[k].y=i arr[k].red=r arr[k].green=g arr[k].blue=b --k=k+1 arr[k].x=j arr[k].y=i arr[k].red=r arr[k].green=g arr[k].blue=b if numf==k then return arr, k end end end end log(k) return arr, k end
log "clear" log "mode compact" local addr, width, height, len = getimage (0, 0, 9, 9) local vi, k={} tmm = os.clock() for i=1, 300 do vi, k=FindRGB(addr,len,0,0,0,0,9,9,"R(0-255)",10000000) end log(os.clock()-tmm) deleteimage(addr) log(type(vi)) -- ошибка, если заремарить - ошибка закрытия lua log(k)
log "done." Исправлена ошибка с выходами за пределы массива. k - ранее объявлялся равным нулю, затем при первой же итерации перед записью данных происходил инкремент: k = k + 1 Что в итоге приводило выходу за пределы массива на 1 элемент в хвосте. Добавлен возврат количества совпадений: if numf==k then return arr, k end return arr, k добавлено получение количества совпадений: vi, k=FindRGB изменено для понимания происходящего: log(type(vi)) -- ошибка, если заремарить - ошибка закрытия lua Обратите внимение на возвращаемый типа - cdata. Не table.
--------------------
Скрипты UOPilot под заказ. Консультации по UOpilot 15$/час. Услуги Lua разработчика (не пилот, проекты, постоянка) Disсоrd: Kov____
|
|
|
|
DarkMaster |
20.11.2018, 1:22
|
          
Модератор UOPilot
Сообщений: 9.764
Регистрация: 2.12.2008 Группа: Супермодераторы Наличность: 29941
Пользователь №: 11.279

|
Еще раз обращаю внимание на то, что это Сишный массив. Т.е. индекс первого элемента равен нулю. Возвращается не "размер"(k), а номер последнего индекса в массиве. Т.е. элементов у нас 100, но k вернет 99, т.к. записаны данные в индексах 0-99. Если есть желание можно сделать +1 в return, но есть ли в этом смысл не понятно, т.к. если будете работать с данным масивом то в первом же переборе нужно будет делать -1. Цитата Я просто многого не знаю, как всё это "фунциклирует", поэтому всё методом тыка. Ну вот чтобы не методом тыка я стараюсь давать ответ чуть шире, чтобы было понимание происходящего. Тут запамятовал написать про размеры.
--------------------
Скрипты UOPilot под заказ. Консультации по UOpilot 15$/час. Услуги Lua разработчика (не пилот, проекты, постоянка) Disсоrd: Kov____
|
|
|
|
sutra |
20.11.2018, 1:30
|
      
Adept
Сообщений: 923
Регистрация: 10.8.2018 Группа: Пользователи Наличность: 0
Пользователь №: 19.007

|
Цитата return arr, k Ну про эту вещь я тоже думал. Только я не совсем понял, получается первый элемент таблицы с индексом НУЛЬ? Спасибо, пока я спрашивал, ответ получен. А всё-таки, хоть я и неуч, но оказался прав, есть всё-таки проблемы с совместимостью. Если честно, то меня эти нули и единицы всегда раздражали, правильнее, если по уму, то наверное единица, поскольку нуль - это собственно говоря НИЧЕГО. Но булева алгебра накладывает отпечаток, так-как и нуль является информацией.
|
|
|
|
sutra |
20.11.2018, 2:39
|
      
Adept
Сообщений: 923
Регистрация: 10.8.2018 Группа: Пользователи Наличность: 0
Пользователь №: 19.007

|
На самом деле тема уже не актуальна. Поскольку ридмем не тормозит, лично у меня уже нет необходимости получать результат поиска файндом в виде массива. Улучшить можно, но только, как я уже говорил, теперь медленный только get, а эти "крохи" выигрыша в виде нескольких микросекунд погоды не делают. Ты помог решить вопрос, СПАСИБО, научил наперёд, СПАСИБО. Пока попробую сам поковыряться. В конце концов, у меня нет цели изучать СИ, я не собираюсь писать свой кликер, меня вполне устраивает Кнайтовский, за что и ему СПАСИБО!
|
|
|
|
DarkMaster |
20.11.2018, 2:43
|
          
Модератор UOPilot
Сообщений: 9.764
Регистрация: 2.12.2008 Группа: Супермодераторы Наличность: 29941
Пользователь №: 11.279

|
Цитата Дарк, извини меня, я тут немножко вспылил и начал права качать, на самом деле, спасибо тебе, что "возишься тут со мной", да ещё и за бесплатно. Я даже корзину форума поднял, благо админка есть. Я хз где вы вспылили) Мной не обнаружено, идем дальше =) Цитата эти "крохи" выигрыша в виде нескольких микросекунд погоды не делают. Не загадывайте. Когда нужно будет делать не один анализ, а десяток, а то и больше подряд на больших площадях, то поймете, что оказывается работает все не так быстро, как хотелось бы. Я тоже считал современный финдимидж в сочетании с гетимиджем невероятно быстрым. Ровно до того момента, как понадобилось искать ~200 изображений. Причем и область то была не большой, но тормоз дикий вышел и плясал я долго потом.
--------------------
Скрипты UOPilot под заказ. Консультации по UOpilot 15$/час. Услуги Lua разработчика (не пилот, проекты, постоянка) Disсоrd: Kov____
|
|
|
|
|
  |
10 чел. читают эту тему (гостей: 10, скрытых пользователей: 0)
Пользователей: 0
|
|