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

|
Цитата Таким образом мы не модифицируем саму функцию, просто при необходимости мы ее вызываем несколько раз. Я вот что ещё хотел спросить, чтобы не убивать свой Пилот в очередной раз, экспериментами методом тыка. А вызвать из функции её же саму мы можем? Ну типа должна получиться рекурсия. То есть вызывать функцию саму из себя до тех пор, пока будет не таблица, а число?? И ещё есть вопрос, возможно ответа и не будет. А как Кнайт определяет формат искомой картинки (ширину, высоту), если в качестве поиска даём только адрес в памяти. Как он понимает сколько строк и сколько столбцов пикселей в картинке. Пробовал анализировать память вокруг и около ссылки на адрес, результат для меня нуль.
|
|
|
|
DarkMaster |
24.1.2019, 16:26
|
          
Модератор UOPilot
Сообщений: 9.764
Регистрация: 2.12.2008 Группа: Супермодераторы Наличность: 29942
Пользователь №: 11.279

|
Цитата Адрес картинки == уникальный номерок картинки со всей информацией внутри пилота адрес указатель на адрес памяти. Бмп в памяти выглядит примерно так: заголовок заголовок ширина высота смещение на битовую маску заголовок заголовок битовая маска учитывая, что формат бмп нам заранее известен и смещение идет на фиксированое количество байт, то зная адрес битовой маски мы легко можем сместиться обратно к заголовку.
--------------------
Скрипты UOPilot под заказ. Консультации по UOpilot 15$/час. Услуги Lua разработчика (не пилот, проекты, постоянка) Disсоrd: Kov____
|
|
|
|
DarkMaster |
25.1.2019, 3:02
|
          
Модератор UOPilot
Сообщений: 9.764
Регистрация: 2.12.2008 Группа: Супермодераторы Наличность: 29942
Пользователь №: 11.279

|
Цитата Если мне не изменяет память, то в 24бит бмп поле offBits(адрес карты, что нам возвращается), которая может лежать в любом месте Немного не так. Бмп несколько стандартов заголовков имеет и опциональных полей, поэтому offbits бывает разный (ну и существует поэтому). Из-за чего пути обратно может и не быть, т.к. мы не можем однозначно сказать какой тип заголовков и количества полей используется. Тем не менее поскольку мы сами загружаем изображение, я допускаю, что происходит некоторая стандартизация и мы можем прочитать адрес назад.
--------------------
Скрипты UOPilot под заказ. Консультации по UOpilot 15$/час. Услуги Lua разработчика (не пилот, проекты, постоянка) Disсоrd: Kov____
|
|
|
|
sutra |
25.1.2019, 8:56
|
      
Adept
Сообщений: 923
Регистрация: 10.8.2018 Группа: Пользователи Наличность: 0
Пользователь №: 19.007

|
В общем я понял, что проще застрелиться, чем найти параметры, придётся тащить в функции кучу переменных. Под свои нужды мне обычно это не надо, я точно знаю все параметры и кроме адреса мне больше ничего не требуется. Короче, Дарк, концепция универсального финдимиджа у меня вроде в голове уже лежит, только лень не позволяет доделать. Просто я как обычно затупил, сработал стандартный Паскалевский подход к решению задач. Я не сразу въехал как задавать уйму параметров на все случаи жизни. Но в lua то как раз всё намного гибче. Не нужен параметр, просто его пропускаем. Задали одиночный параметр - один алгоритм, задали таблицей - другой. На самом низком уровне будет 3 варианта подфункций. Если ещё и параметр аккуратности тащить, то больше. Хотя так пока толком и не понял какой положительный эффект он даст. В упрощённом варианте должен повышать точность поиска. Но упрощённый на то и упрощённый, чтобы работал быстро, а эта аккуратность даст лишний тормоз. А при формировании массива пикселей для поиска, параметр аккуратности в принципе не приемлем, а с точки зрения скорости - этот метод вне конкуренции. Грубо говоря, искать прицел по-другому несопоставимо медленнее. Ладно, допинаю - выложу. Не допинаю - скажу как допинывать. Хотя чего там говорить, кто в теме, тот давно всё понял лучше меня.
|
|
|
|
sutra |
25.1.2019, 11:54
|
      
Adept
Сообщений: 923
Регистрация: 10.8.2018 Группа: Пользователи Наличность: 0
Пользователь №: 19.007

|
Код --lua local ffi=require "ffi" local rmem=ffi.cast local function ImageCompareS2(addrGet,lenGet,arrpix,fx1,fy1) -- addrGet,lenGet : начальный адрес в памяти и длина строки образа -- fx1,fy1 : начальные координаты поиска картинки в образе -- arrpix : массив искомых пикселей (ЛЮБАЯ!! последовательность) -- структура массива искомых пикселей arrpix {x,y,r1,r2,g1,g2,b1,b2} -- x,y координаты значимых (искомых) пикселей в картинке (0..) -- r1,r2 граничные значения поиска канала RED для пикселя (создаются учитывая deviation) -- ... for i=1,#arrpix do -- цикл просмотра значимых пикселей local ind=addrGet + (fy1 + arrpix[i].y) * lenGet + (fx1 + arrpix[i].x) * 3 -- вычисление индекса в памяти if rmem("unsigned char*",ind)[0]<arrpix[i].b1 or rmem("unsigned char*",ind)[0]>arrpix[i].b2 then return false else if rmem("unsigned char*",ind)[1]<arrpix[i].g1 or rmem("unsigned char*",ind)[1]>arrpix[i].g2 then return false else if rmem("unsigned char*",ind)[2]<arrpix[i].r1 or rmem("unsigned char*",ind)[2]>arrpix[i].r2 then return false end end end end return true end -------------------------------------------------------------------------------- local function ImageCompareS(addrGet,lenGet,arrpix,fx1,fy1, r1,r2,r3) -- r1,r2,r3 добавлены параметра порядка просмотра каналов, могут принимать значения 0,1 или 2 -- 2,0,1 сначала RED, потом BLUE, потом GREEN for i=1,#arrpix do -- цикл просмотра значимых пикселей local ind=addrGet + (fy1 + arrpix[i].y) * lenGet + (fx1 + arrpix[i].x) * 3 -- вычисление индекса в памяти if rmem("unsigned char*",ind)[r1]<arrpix[i][r1].s or rmem("unsigned char*",ind)[r1]>arrpix[i][r1].e then return false else if rmem("unsigned char*",ind)[r2]<arrpix[i][r2].s or rmem("unsigned char*",ind)[r2]>arrpix[i][r2].e then return false else if rmem("unsigned char*",ind)[r3]<arrpix[i][r3].s or rmem("unsigned char*",ind)[r3]>arrpix[i][r3].e then return false end end end end return true end -------------------------------------------------------------------------------- log "clear" log "mode compact" -- ДАЛЕЕ ЗНАКИ !!!!! - это МОЙ КОД. Не надо запускать скрипт, пока не переделаете под СВОЙ local i=570 local ad1=loadimage([[СКРИНЫ\\ВИД\Vid-]]..string.format("%04d",i)..[[.bmp]]) -- !!!!! гружу картинку 500x20 local i=571 local ad2=loadimage([[СКРИНЫ\\ВИД\Vid-]]..string.format("%04d",i)..[[.bmp]]) -- !!!!! гружу картинку 500x20 -- ad1 - картинка которая будет найдена ad2 - картинка которая НЕ будет найдена
--\/ формирую СВОЙ!! массив искомых пикселей ВАРИАНТ №1 (15 пикселей) local q={} local j=1 for i=83,97 do q[j]={} q[j].x=i q[j].y=0 q[j].r1=49 q[j].r2=51 q[j].g1=69 q[j].g2=71 q[j].b1=81 q[j].b2=83 j=j+1 end
--\/ формирую СВОЙ!! массив искомых пикселей ВАРИАНТ №1 local w={} local j=1 for i=83,97 do w[j]={} w[j].x=i w[j].y=0 w[j][0]={} w[j][1]={} w[j][2]={} w[j][0].s=81 w[j][0].e=83 w[j][1].s=69 w[j][1].e=71 w[j][2].s=49 w[j][2].e=51 -- s - это START (начало диапазона); e - это END j=j+1 end
-- Далее 2 теста 1 миллион итераций, картинка будет найдена, т.е. внутри функций 15 итераций tmc=os.clock() for i=1,1000000 do ImageCompareS2(ad1,1500,q,0,0) end tmc=os.clock()-tmc log("Время : ",tmc) -- 0,250 сек tmc=os.clock() for i=1,1000000 do ImageCompareS(ad1,1500,w,0,0, 2,1,0) end tmc=os.clock()-tmc log("Время : ",tmc) -- 0,314 сек
-- Далее 2 теста 10 миллионов итераций, картинка НЕ будет найдена, внутри функций отваливается на 1-ой итерации tmc=os.clock() for i=1,10000000 do ImageCompareS2(ad2,1500,q,0,0) end tmc=os.clock()-tmc log("Время : ",tmc) -- 0,278 сек tmc=os.clock() for i=1,10000000 do ImageCompareS(ad2,1500,w,0,0, 2,1,0) end -- порядок просмотра каналов в данном случае роли не играет tmc=os.clock()-tmc log("Время : ",tmc) -- 0,340 сек
deleteimage(ad1) deleteimage(ad2) Дарк, очень нужны советы. Дал 2 варианта функций с нестандартным поиском. Советы в плане варианта, где я попытался сделать порядок сравнения каналов. Это может быть важно, например искать прицел лучше начиная с красного канала, сразу будут отсеиваться большинство сравнений.
|
|
|
|
DarkMaster |
25.1.2019, 11:55
|
          
Модератор UOPilot
Сообщений: 9.764
Регистрация: 2.12.2008 Группа: Супермодераторы Наличность: 29942
Пользователь №: 11.279

|
Накидал общую идею нескольких изображений и буферизации, загрузки изображений. Код не запускал. Так сказать идеи в коде, который можно пилить. Код local fi = {}
-- Создаем карман namespace -- для приватных данных, -- которые будут сохранятся между -- вызовами функций. do -- Буфер с загруженными изображениями. fi.buffer = {} -- список функций буфера. local buffer = {} -- непосредственно буфер.
-- Добавляем изображение в буфер -- Возвращает адрес. -- Если указан адрес, то будет -- добавлено в буфер уже загруженное -- изобажение. -- Если указан только путь, то -- изображение будет считано с диска. fi.buffer.add == function(path, address) if address ~= nil then buffer[path] = address else buffer[path] = loadimage(path) end return buffer[path] end -- Получаем адрес изображения из буфера fi.buffer.get == function(path,address) if buffer[path] then return buffer[path] else return fi.buffer.add == function(path, address) end end -- Удаляем элемент из буфера fi.buffer.delete == function(path) buffer[path] = nil end -- Полностью очищаем массив. fi.buffer.flush == function() for k,_ in pairs(buffer) do buffer[v] = nil end end
fi.image = function(x1,y1,x2,y2,path,type,acc,count,dev1,dev2) -- Основная функция поиска -- вынесена для цикличского вызова -- если передано несколько изображений. -- Вместо пути изображения передается -- непосредственно адрес в памяти на -- уже загруженное изображение local function find(x1,y1,x2,y2,image_address,type,acc,count,dev1,dev2, address, width, height, length) -- ТУТ КОД ПОИСКА -- ТУТ КОД ПОИСКА -- ТУТ КОД ПОИСКА end
-- Получаем снимок экрана local address, width, height, length = getimage(x1,y1,x2,y2,type,abs)
-- Если указан массив изображений, то -- последним элмементом указывается -- необходимость искать все изображения (1) -- либо достаточно первого найденного (0) if type(path) == "table" then if path[#path] == 1 then local result = {} for #i = 1, #path - 1 do result[#result+1]=find (x1,y1,x2,y2,fi.buffer.get(path[i]),type,acc,count,dev1,dev2) end elseif path[#path] == 0 local result = {} for #i = 1, #path - 1 do result=find (x1,y1,x2,y2,fi.buffer.get(path[i]),type,acc,count,dev1,dev2) if result then return result end end return nil else log("fi.image error. Wrong image table flag: ".. path[#path] and tostring(path[#path]) or "nil") end else return find(x1,y1,x2,y2,fi.buffer.get(path[i]),type,acc,count,dev1,dev2) end end end
Сообщение отредактировал DarkMaster - 25.1.2019, 12:03
--------------------
Скрипты UOPilot под заказ. Консультации по UOpilot 15$/час. Услуги Lua разработчика (не пилот, проекты, постоянка) Disсоrd: Kov____
|
|
|
|
DarkMaster |
25.1.2019, 12:02
|
          
Модератор UOPilot
Сообщений: 9.764
Регистрация: 2.12.2008 Группа: Супермодераторы Наличность: 29942
Пользователь №: 11.279

|
Цитата Дарк, очень нужны советы. Дал 2 варианта функций с нестандартным поиском. Советы в плане варианта, где я попытался сделать порядок сравнения каналов. Это может быть важно, например искать прицел лучше начиная с красного канала, сразу будут отсеиваться большинство сравнений. Я бы предложил сначала обработать искомое изображение. Т.е. мы делаем 2 изображения с минимальным и максимальным значениями каналов. Если заданы оба типа deviation, то их будет четыре. При формировании этих изображений я бы попробовал найти некторую наиболее контрастную точку и поиск начинать с нее. Указание с какого канала начинать поиск имхо может быть лишним, если оно нужно, то задать в рамках строки deviation. Цитата плане применения (кликнуть где нашло) Мой вариант позволяет использовать достаточно прозрачно данную конструкцию. Там просто введен доп флаг.
--------------------
Скрипты UOPilot под заказ. Консультации по UOpilot 15$/час. Услуги Lua разработчика (не пилот, проекты, постоянка) Disсоrd: Kov____
|
|
|
|
sutra |
26.1.2019, 2:01
|
      
Adept
Сообщений: 923
Регистрация: 10.8.2018 Группа: Пользователи Наличность: 0
Пользователь №: 19.007

|
Цитата При формировании этих изображений я бы попробовал найти некторую наиболее контрастную точку и поиск начинать с нее Ну, для общего случая всё верно. Но в реальном приросте в скорости при применении такого подхода я сильно сомневаюсь. Ну вот давай, раскинем мозгами. Я даже не буду думать о том, с чем я ещё не сталкивался. Скажу про те 3 варианта, с которыми я работал. 1) Это мой случай, когда мне нужно было искать изображение из набора более тысячи картинок. Такой подход НИЧЕГО не даст. У меня основной, глобальный цвет на всех картинках ОДИН. Важно ГДЕ пиксели расположены и тут только отдельным скриптом можно провести анализ. 2) Это твой прицел, там как раз нужна скорость и там тоже не нужно ничего делать, там и так понятен глобальный цвет поиска - КРАСНЫЙ, и опять важно просто уменьшить количество искомых пикселей и начинать искать с КРАСНОГО. 3) Монетки Сайруса, скорость там не критична, но экран поиска - гигантский, да ещё наверняка и с прокруткой по обоим координатам. Но и там всё понятно с искомыми цветами. Резюмируя, для общего случая вообще не вижу смысла заморачиваться над логикой функции, отвечающей за подготовку к поиску. Если кого-то общий случай не устроит (таких вот типа меня), так и пусть напрягает свои мозги. Главное - дать им инструмент. В моей голове например, сидит алгоритм задания параметров, который позволит задавать любые комбинации параметров для подготовки поиска, в том числе и разность между каналами - ЭТО НАИВАЖНЕЙШИЙ параметр, не понимаю, почему его все так упорно игнорируют. Любые цвета и любые фона, которые можно будет задавать и таблицами и просто пропускать любой из них. Общая твоя конструкция, тут я не конкурент, ну конечно же мне учиться и учиться у тебя. Буду учиться! Про разность между каналами... Ну вот твой прицел. Я конечно не знаю. Если изображение статично, то вопрос исчерпан, я его найду и 3-мя пикселями, а вот если ПЛАВАЕТ? Вот там и нужна будет разница между каналами RED-BLUE. Надеюсь понятно изложил свои мысли.
|
|
|
|
sutra |
26.1.2019, 2:14
|
      
Adept
Сообщений: 923
Регистрация: 10.8.2018 Группа: Пользователи Наличность: 0
Пользователь №: 19.007

|
При подготовке поиска, на мой взгляд , нужно искать не максимальные и минимальные значения каналов, а УНИКАЛЬНЫЕ цвета и запросто они будут далеки от максимальных и минимальных значений. Анализом только картинок ничего толком не добиться, в таком случае мы должны анализировать перед поиском и область снимка, тогда неизбежно получаются глупые тормоза. Короче, в общем случае и так ищет быстро, ну во всяком случае на порядки быстрее ныне действующего алгоритма, так и то никто особо не жужжит. Просто дать юзерам инструмент для полёта фантазии, вот и всё.
А вот если ты, Дарк, прикрутишь потоки ... вот это реальный прирост. Просто бить снимок экрана на количество кусков равных ядрам камня. Для большинства - это будет почти в 4 раза быстрее.
|
|
|
|
sutra |
26.1.2019, 2:34
|
      
Adept
Сообщений: 923
Регистрация: 10.8.2018 Группа: Пользователи Наличность: 0
Пользователь №: 19.007

|
Хотя кто знает, может я и не прав и ты сделаешь супер вещь. Но предупреждаю (IMG: style_emoticons/default/biggrin.gif) я обязательно сделаю всё криво и не как у людей, но искать будет не медленнее чем у тебя! Я к чему клоню ... Предподготовка к поиску, запросто может убить конечный результат. Если зона поиска огромна, то скорее всего предподготовка даст прирост, а если искать в узкой зоне снимка экрана? Хотел сказать большой вопрос, но поправлюсь, без вопросов, обычный поиск будет выполнен однозначно быстрее. И главная фишка. Если алгоритм игры отлажен, тогда и картинки будут не нужны. Если подготовлены массивы поиска пикселей их можно грузить при старте скрипта вместо картинок, всё будет намного быстрее. Все уникальные случаи поиска - пусть ищутся стандартно.
|
|
|
|
sutra |
26.1.2019, 3:00
|
      
Adept
Сообщений: 923
Регистрация: 10.8.2018 Группа: Пользователи Наличность: 0
Пользователь №: 19.007

|
Теперь про deviation. Да не нужно тащить 2 параметра. Объясню утрированно, при предподготовке поиска прицела, задаём искомые пиксели, скажем разницу между каналами RED-BLUE R-B[100] и все пиксели картинки, которые попали в этот интервал, будут обработаны с ОДНИМ параметром deviation. Просто к каждому найденному пикселю в картинке, соответствующему разности каналов, мы добавим deviation (если на снимке экрана прицел плавает).
Хотел извиниться, это я в своё время, когда сам плохо понимал, что делаю, дал мысль про 2 параметра deviation. Но реально это не нужно. Погрешность должна распространяться на пиксели снимка экрана, а не на пиксели картинок.
|
|
|
|
DarkMaster |
26.1.2019, 5:06
|
          
Модератор UOPilot
Сообщений: 9.764
Регистрация: 2.12.2008 Группа: Супермодераторы Наличность: 29942
Пользователь №: 11.279

|
Цитата Хотел извиниться, это я в своё время, когда сам плохо понимал, что делаю, дал мысль про 2 параметра deviation. Но реально это не нужно.
Нужно. Они отвечают за абсолютно разные вещи: 1) За гамму. Т.е. изображение может становится светлее/темнее сохраняя общий цвет. 2) Возможно отклонение цвета. В чистом виде разве что в шрифтах использовать смысл есть. Deviation для меня в первую очередь инструмент для анализа полупрозрачных изображений. Из моего опыта проблемы с отклонением цвета возникают всего в двух случаях: 1) Полупрозрачные окна. 2) Шрифты. На все остальное можно просто не обращать внимание - это казуистика, которая решается в рамках тех же опереторов. Если шрифты тема хоть и сложная в плане прогнозируемости, но суть обработки ясна и просто, то вот с полупрозрачными окнами все на самом деле существенно сложнее. Полупрозрачность дает нам некторое ограничение по %диапазона, который может участвовать в сравнении. Тем не менее там явным образом могут происходить отклонения по цветам в абсолютном значении. Оставляя только один из параметров мы в итоге приходим к вариантам, когда вместо указания 1 и 1 в погрешности нам приходится необосновано задирать одно значение, скажем до 10 вместо 1 и 1. Это неправильно. Микроскоп и гвозди. Цитата Погрешность должна распространяться на пиксели снимка экрана, а не на пиксели картинок. Я кстати не думал об этом и считал, что по умолчанию погрешность должна считаться для экрана. Пока ты не написал об этом. Ирония в том, что теперь я абсолютно не согласен с этим. У нас есть два пикселя с цветами: 1) экран 200 2) искомый 208 Нам нужно понять укладывается ли изображение в отклонение 10. От экарана: 200-10=190 200+10=210 190<208<210 От искомого: 208-10=198 208+10=218 198<200<218 Т.е. разницы нет вообще никакой. Но изображение экрана значительно больше и обрабатывать его придется дольше, мы получим больше математике. А зачем оно нужно? Поэтому обрабатывать однозначно искомое. Если разбирать deviation в %, то тут тем более нужно от искомого, т.к. в противном случае у нас будет постоянно гуляющая погрешность помимо размера.
--------------------
Скрипты UOPilot под заказ. Консультации по UOpilot 15$/час. Услуги Lua разработчика (не пилот, проекты, постоянка) Disсоrd: Kov____
|
|
|
|
sutra |
26.1.2019, 13:43
|
      
Adept
Сообщений: 923
Регистрация: 10.8.2018 Группа: Пользователи Наличность: 0
Пользователь №: 19.007

|
Цитата Поэтому обрабатывать однозначно искомое. Ну естественно, при самом поиске НИКАКОЙ математики. Мы просто немножко недопоняли друг друга. Ещё раз, что я имел ввиду. Пропускаем момент, как мы формируем искомый массив. Самый последний этап этого действия. Определили пиксель, который попадает в наш искомый массив. И вот к его RGB и применяем deviation получая в результате значения r1,r2 и т.д. И что ещё хотел сказать. Функция поиска должна понимать, когда ей работать с картинкой, а когда напрямую с массивом искомых пикселей. Опять про пресловутый прицел. Его проанализировать надо всего только ОДИН раз, а потом ТЫСЯЧИ раз использовать уже готовый массив пикселей поиска. Функция просто будет смотреть - задали массив - сразу искать, если нет таблицы - значит включать предварительную обработку. Цитата Из моего опыта проблемы с отклонением цвета возникают всего в двух случаях Всё верно, именно так. И даже не нужно никуда ходить, пример Сайруса с монетками - идеальный полигон. Там как раз фон капельки - полупрозрачный. Вот берём оттуда пиксель и прикручиваем к нему ОТНОСИТЕЛЬНЫЙ deviation скажем даже 10% и я уверен, других таких пикселей кроме как в капельках мы не найдём.
|
|
|
|
|
  |
5 чел. читают эту тему (гостей: 5, скрытых пользователей: 0)
Пользователей: 0
|
|