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

|
Код for j=1,1000000000 do if j>0 then a=rmem("unsigned char*",pg)[0] end end Вот ни чего не понимаю, есть if , есть вызов функции, есть присваивание ... целый миллиард раз, отрабатывает за 0,6 сек. В рабочей функции итераций (в целом на всех циклах) в 1000 раз меньше, ну есть небольшая математика, а результат по времени даже хуже. В 1000 раз медленнее. Не в 10 и даже не во 100, а в 1000. Не могу понять где тормоза. По логике - тормозит математика. В данный пример запихнул математику ТРИ действия, стало в ДВА раза медленнее, так ведь в 2, а не в 1000. Что-то видимо я недопонимаю или криво делаю.
|
|
|
|
sutra |
16.2.2019, 1:28
|
      
Adept
Сообщений: 923
Регистрация: 10.8.2018 Группа: Пользователи Наличность: 0
Пользователь №: 19.007

|
В общем, ничего у меня не получилось, ничего я не понимаю, ничего не знаю. То ищет за 0,03 сотых, то за 0,8 сек. Всё сломал, что нормально работало, копий не один десяток, только я и сам теперь не понимаю, что, где и как работает. Кину вам код, всё переделано на вайлы, хотя форы обычно работают быстрее. Наверняка уйма ошибок, потому что всё эксперименты ставлю, толком на всех режимах не тестировал, но в принципе вроде работает. Описание работы функции буду давать порциями, кто в теме, тот и так поймёт. Может кто чего скажет что не так, может просто дадите советы как не надо делать ... Код функции
Код --lua local ffi=require "ffi" local rmem=ffi.cast local function CreateFindArray(co) local k,q,b,g,r,p,d,ad,w,h,l=0,1,ffi.new("uint8_t"),ffi.new("uint8_t"),ffi.new("uint8_t"),ffi.new("uint8_t[6]"),ffi.new("int16_t[6]"),co[1][1],co[1][2],co[1][3],co[1][4] local ar,f,x,y,i,R,G,B,P,D,RG,RB,GB,ba,ga,ra=ffi.new("uint16_t[?][8]",w*h),ffi.new("uint16_t["..h.."]["..w.."]") while q<#co do & nbsp;q,R,G,B,P,D,RG,RB,GB,y,x,i=q+1,true,true,true,true,true,true,true,true,0,0, ad if co[q].R then P,R,p[0],p[1]=false,false,co[q].R,co[q].R2 or co[q].R end if co[q].G then P,G,p[2],p[3]=false,false,co[q].G,co[q].G2 or co[q].G end if co[q].B then P,B,p[4],p[5]=false,false,co[q].B,co[q].B2 or co[q].B end if co[q].RG then D,RG,d[0],d[1]=false,false,co[q].RG,co[q].RG2 or 255 end if co[q].RB then D,RB,d[2],d[3]=false,false,co[q].RB,co[q].RB2 or 255 end if co[q].GB then D,GB,d[4],d[5]=false,false,co[q].GB,co[q].GB2 or 255 end if co[q].acc then acc=(100-co[q].acc)/100 else acc=0 end if co[q].dev then v=co[q].dev else v=0 end if co[q].fgr then while y<h do while x<w do if f[y][x]==0 then b,g,r=rmem("unsigned char*",i)[0],rmem("unsigned char*",i)[1],rmem("unsigned char*",i)[2] if(D or((RG or r-g>=d[0]and r-g<=d[1])and(RB or r-b>=d[2]and r-b<=d[3])and(GB or g-b>=d[4]and g-b<=d[5])))and(P or((R or r>=p[0]and r<=p[1])and(G or g>=p[2]and g<=p[3])and(B or b>=p[4]and b<=p[5])))then k,ba,ga,ra,f[y][x]=k+1,b*acc,g*acc,r*acc,1 ar[k]={math.max(0,math.floor(b-ba-v)),math.max(0,math.floor(g-ga-v)),math.max(0,math.floor(r-ra-v)),math.min(255,math.ceil(b+ba+v)),math.min(255,math.ceil(g+ga+v)),math.min(255,math.ceil(r+ra+v)),x,y} end end i,x=i+3,x+1 end y=y+1 i,x=ad+y*l,0 end else while y<h do while x<w do if f[y][x]==0 then b,g,r=rmem("unsigned char*",i)[0],rmem("unsigned char*",i)[1],rmem("unsigned char*",i)[2] if not(D or((RG or r-g>=d[0]and r-g<=d[1])and(RB or r-b>=d[2]and r-b<=d[3])and(GB or g-b>=d[4]and g-b<=d[5])))and(P or((R or r>=p[0]and r<=p[1])and(G or g>=p[2]and g<=p[3])and(B or b>=p[4]and b<=p[5])))then k,ba,ga,ra,f[y][x]=k+1,b*acc,g*acc,r*acc,1 ar[k]={math.max(0,math.floor(b-ba-v)),math.max(0,math.floor(g-ga-v)),math.max(0,math.floor(r-ra-v)),math.min(255,math.ceil(b+ba+v)),math.min(255,math.ceil(g+ga+v)),math.min(255,math.ceil(r+ra+v)),x,y} end end i,x=i+3,x+1 end y=y+1 i,x=ad+y*l,0 end end end deleteimage(ad) ar[0]={k,0,w,h,l} return ar end -------------------------------------------------------------------------------- local function FindImage(aG,lG,x1,y1,x2,y2, pic, numf, sim,v1,v2,v3) local t,af,k,dG,dL, ci=false,{},1,false,false if not(aG)then dG,x1,y1,x2,y2,aG,ci,ci,lG=true,0,0,x2-x1,y2-y1,getimage(x1,y1,x2,y2,lG) end if type(pic)~="cdata" then if type(pic[1][1])=="string" then dL,pic[1][1],pic[1][2],pic[1][3],pic[1][4]=true,loadimage(pic[1][1]) end if #pic>1 then pic,t=CreateFindArray(pic),true end else t=true end local sr,i,j,x,y=true,0,0,x1,y1 if t then sim,v1,v2,v3=pic[0][0]*0.01*(100-sim),v1 or 0,v2 or 1,v3 or 2 local xe,ye,V1,V2,V3,ind=x2+2-pic[0][2],y2+2-pic[0][3],v1+3,v2+3,v3+3 while y<ye do while x<xe do local function Compare() ind=aG+(y+pic[i][7])*lG+(x+pic[i][6])*3 if rmem("unsigned char*",ind)[v1]<pic[i][v1]or rmem("unsigned char*",ind)[v1]>pic[i][V1]then j=j+1 if j>sim then return false end elseif rmem("unsigned char*",ind)[v2]<pic[i][v2]or rmem("unsigned char*",ind)[v2]>pic[i][V2]then j=j+1 if j>sim then return false end elseif rmem("unsigned char*",ind)[v3]<pic[i][v3]or rmem("unsigned char*",ind)[v3]>pic[i][V3]then j=j+1 if j>sim then return false end end return true end ------------------------------------------------------------------------ while sr and i<pic[0][0]do i=i+1 sr=Compare() end if sr then af[k],k={x,y},k+1 if k>numf then if dG then deleteimage(aG) end return af end end x,sr,i,j=x+1,true,0,0 -- j - пропущенные пиксели end x,y=x1,y+1 end else ci,v1,v2,v3=pic[1][2]*3,v1 or 0,v2 or 1,v3 or 0 aG,pic[1][1]=aG+v3,pic[1][1]+v3 local xe,ye,ag,al,raz=x2+2-pic[1][2],y2+2-pic[1][3] while y<ye do while x<xe do ag,al=aG+y*lG+x*3,pic[1][1] while sr and j<pic[1][3]do while sr and i<ci do raz,i=rmem("unsigned char*",ag)[i]-rmem("unsigned char*",al)[i],i+v2 if raz~=0 then if raz>0 then if raz>v1 then sr=false end elseif raz<-v1 then sr=false end end end ag,al,i,j=ag+lG,al+pic[1][4],0,j+1 end if sr then af[k],k={x,y},k+1 if k>numf then if dL then deleteimage(pic[1][1]) end if dG then deleteimage(aG) end return af end end x,sr,i,j=x+1,true,0,0 -- j - текущая ордината картинки end x,y=x1,y+1 end if dL then deleteimage(pic[1][1]) end end if dG then deleteimage(aG) end return af end --------------------------------------------------------------------------------
log "clear" log "mode compact" local aff -- распакуйте картинки в каталог Пилота (всего 2 штуки) local pg,wg,hg,lg=loadimage([[scr.bmp]]) local pl,wl,hl,ll=loadimage([[target_.bmp]]) --local pix=CreateFindArray({{pl,wl,hl,ll},{RG=100,fgr=true,acc=90,dev=5}}) --aff=FindImage(pg,lg,0,0,1919,1079,pix,9,71)
-- далее ищем 9 мишеней, найдутся имеющиеся 6 (координаты покажут каких) tmc=os.clock() aff=FindImage(pg,lg,0,0,1919,1079,{{pl,wl,hl,ll},{RG=100,fgr=true,acc=86,dev=5}},9,70)
-- далее обычный поиск одной картинки --aff=FindImage(pg,lg,0,0,1041,1025,{{pl,wl,hl,ll}},2,100) tmc=os.clock()-tmc log("Время : ",tmc)
log(#aff) for i=1, #aff do log(table.concat(aff[i], " ")) end deleteimage(pg) deleteimage(pl) -- Описание работы функции дам чуть позже. Собственно код.
Прикрепленные файлы
pictures.zip ( 2,23 мегабайт )
Кол-во скачиваний: 51
|
|
|
|
sutra |
16.2.2019, 1:40
|
      
Adept
Сообщений: 923
Регистрация: 10.8.2018 Группа: Пользователи Наличность: 0
Пользователь №: 19.007

|
Код ArrayFindPictures = FindImage(<AddrScr,LengthScr | nil, handle|"abs"> , x1,y1,x2,y2,picture,NumberFind,similarity [,deviation]) ArrayFindPictures - массив найденных картинок, координаты картинок AddrScr - адрес в памяти где будем искать (снимок экрана, загруженная картинка) LengthScr - длина строки в памяти или nil (будет сделан снимок экрана) handle|"abs" - хендл окна или абсолютные координаты ... понятно picture - таблица параметров картинки, NumberFind - количество искомых картинок similarity - схожесть искомых картинок с эталоном, только для продвинутого режима [,deviation] - отклонение, ИСПОЛЬЗОВАТЬ!!! только для стандартного режима поиска остальные переменные (v1,v2,v3) не нужны, просто пропускаем их (оставил пока для тестов)
picture либо готовый СИ-массив искомых пикселей картинки - БУДЕТ использоваться ПРОДВИНУТЫЙ поиск либо ДВУМЕРНАЯ таблица параметров первый элемент - массив параметров картинки {Address,width,height,length} адрес, ширина, высота, длина строки. второй и последующие элементы - таблицы условий создания СИ-массива искомых пикселей картинки - БУДЕТ использоваться ПРОДВИНУТЫЙ поиск ключи таблиц: acc - accuracy - точность; dev - deviation - отклонение; fgr - foreground (задание искомых цветов (каналов RGB)), если этого ключа нет, значит описывается фон R,R2,G,G2,B,B2 - граничные значения поиска каналов RG,RG2,RB,RB2,BG,BG2 - разность между каналами. Коротко пока так.
|
|
|
|
sutra |
16.2.2019, 2:12
|
      
Adept
Сообщений: 923
Регистрация: 10.8.2018 Группа: Пользователи Наличность: 0
Пользователь №: 19.007

|
Скорость работы функции - для меня загадка. Но вроде ищет, надо просто сделать её по уму. Может умные головы додумают. В принципе пользоваться наверное можно. У меня нет таких задач, где бы она была нужна в таком виде, тестировал на том, что дали. В частных случаях работало даже очень быстро, запихнул всё в одну функцию - перестал понимать как всё работает.
Количество описаний фонов и цветов не ограничено, при правильном подходе можно найти практически что угодно. Плюс, это всё можно править руками, я дал пример автоматики, если я приложу мозг, всё будет искаться в разы быстрее. Поиск по разности каналов я пока убрал, работает слишком медленно, а применяемость крайне не востребована, если только не искать объекты с градацией (день - ночь).
Да, вот ещё что важно. Обработку ошибок я не делал, поскольку и сам не всё понимаю как сделать так, чтобы ЛЮБЫЕ ошибки игнорировались в принципе, ну собственно это и не моя задача. Я дал идею как можно искать то, что типа вроде не ищется - ищется!
По использованию функции... Ключи R, R2 ... и т.д. - это диапазон поиска нужных пикселей в шаблоне картинки. К найденным пикселям применяются отклонение и точность (абсолютная и относительная погрешность). При использовании относительной погрешности (acc), задавать абсолютную (dev) в интервале 3-7 единиц, остальное сделает относительная. абсолютная нужна для нивелирования непредсказуемого изменения значений каналов, которые имеют минимальные значения (Нуль на сколько не умножай - останется нулём).
|
|
|
|
sutra |
16.2.2019, 2:48
|
      
Adept
Сообщений: 923
Регистрация: 10.8.2018 Группа: Пользователи Наличность: 0
Пользователь №: 19.007

|
Ждём здесь очень, с нетерпеньем, Ваших мнений, откровений. Замечанья, пожеланья, Всё, что требует вниманья!
Ждём рецензий и упрёков, Если будут ненароком. По пустому иль по делу, Критике здесь нет предела.
Мастера и корифеи, Программистеры - орфеи, Что грызут гранит науки, Даже походя, от скуки, Коль покажут, что не так, Буду только очень рад. Как не надо на фиг делать, Говорите прямо, смело.
А возникнут вдруг вопросы, Где, чего и как искать Или вылезут ошибки, Значит буду отвечать.
|
|
|
|
sutra |
17.2.2019, 13:51
|
      
Adept
Сообщений: 923
Регистрация: 10.8.2018 Группа: Пользователи Наличность: 0
Пользователь №: 19.007

|
Дарк, я всё-таки нашёл источник жутких тормозов. И это то, на что я даже не думал. Нашёл абсолютно случайно - это rmem. Причину пока не понял, но понять нужно обязательно, потому что тормоз - ДВА ПОРЯДКА. Привожу конкретный пример. Код теста
Код --lua local ffi=require "ffi" local rmem=ffi.cast local function CreateFindArray(co,LG) local k,q,b,g,r,p,d,ad,w,h,l=0,1,ffi.new("uint8_t"),ffi.new("uint8_t"),ffi.new("uint8_t"),ffi.new("uint8_t[6]"),ffi.new("int16_t[6]"),co[1][1],co[1][2],co[1][3],co[1][4] local ar,f,x,y,i,R,G,B,P,D,RG,RB,GB,ba,ga,ra=ffi.new("uint32_t[?][9]",w*h),ffi.new("uint16_t["..h.."]["..w.."]") while q<#co do & nbsp;q,R,G,B,P,D,RG,RB,GB,y,x,i=q+1,true,true,true,true,true,true,true,true,0,0, ad if co[q].R then P,R,p[0],p[1]=false,false,co[q].R,co[q].R2 or co[q].R end if co[q].G then P,G,p[2],p[3]=false,false,co[q].G,co[q].G2 or co[q].G end if co[q].B then P,B,p[4],p[5]=false,false,co[q].B,co[q].B2 or co[q].B end if co[q].RG then D,RG,d[0],d[1]=false,false,co[q].RG,co[q].RG2 or 255 end if co[q].RB then D,RB,d[2],d[3]=false,false,co[q].RB,co[q].RB2 or 255 end if co[q].GB then D,GB,d[4],d[5]=false,false,co[q].GB,co[q].GB2 or 255 end if co[q].acc then acc=(100-co[q].acc)/100 else acc=0 end if co[q].dev then v=co[q].dev else v=0 end if co[q].fgr then while y<h do while x<w do if f[y][x]==0 then b,g,r=rmem("unsigned char*",i)[0],rmem("unsigned char*",i)[1],rmem("unsigned char*",i)[2] if(D or((RG or r-g>=d[0]and r-g<=d[1])and(RB or r-b>=d[2]and r-b<=d[3])and(GB or g-b>=d[4]and g-b<=d[5])))and(P or((R or r>=p[0]and r<=p[1])and(G or g>=p[2]and g<=p[3])and(B or b>=p[4]and b<=p[5])))then k,ba,ga,ra,f[y][x]=k+1,b*acc,g*acc,r*acc,1 ar[k]={math.max(0,math.floor(b-ba-v)),math.max(0,math.floor(g-ga-v)),math.max(0,math.floor(r-ra-v)),math.min(255,math.ceil(b+ba+v)),math.min(255,math.ceil(g+ga+v)),math.min(255,math.ceil(r+ra+v)),x*3+y*LG,x,y} end end i,x=i+3,x+1 end y=y+1 i,x=ad+y*l,0 end else while y<h do while x<w do if f[y][x]==0 then b,g,r=rmem("unsigned char*",i)[0],rmem("unsigned char*",i)[1],rmem("unsigned char*",i)[2] if not(D or((RG or r-g>=d[0]and r-g<=d[1])and(RB or r-b>=d[2]and r-b<=d[3])and(GB or g-b>=d[4]and g-b<=d[5])))and(P or((R or r>=p[0]and r<=p[1])and(G or g>=p[2]and g<=p[3])and(B or b>=p[4]and b<=p[5])))then k,ba,ga,ra,f[y][x]=k+1,b*acc,g*acc,r*acc,1 ar[k]={math.max(0,math.floor(b-ba-v)),math.max(0,math.floor(g-ga-v)),math.max(0,math.floor(r-ra-v)),math.min(255,math.ceil(b+ba+v)),math.min(255,math.ceil(g+ga+v)),math.min(255,math.ceil(r+ra+v)),x*3+y*LG,x,y} end end i,x=i+3,x+1 end y=y+1 i,x=ad+y*l,0 end end end deleteimage(ad) ar[0]={k,LG,w,h,l} return ar end -------------------------------------------------------------------------------- local function FindImage(aG,lG,x1,y1,x2,y2, pic, numf, sim,v1,v2,v3) local t,af,k,dG,dL, ci=false,{},1,false,false if not(aG)then dG,x1,y1,x2,y2,aG,ci,ci,lG=true,0,0,x2-x1,y2-y1,getimage(x1,y1,x2,y2,lG) end if type(pic)~="cdata" then if type(pic[1][1])=="string" then dL,pic[1][1],pic[1][2],pic[1][3],pic[1][4]=true,loadimage(pic[1][1]) end if #pic>1 then pic,t=CreateFindArray(pic,lG),true end else t=true -- добавить проверку lG end local sr,i,j,x,y=true,0,0,x1,y1 if t then sim,v1,v2,v3=pic[0][0]*0.01*(100-sim),v1 or 0,v2 or 1,v3 or 2 local AG,shi,xe,ye,V1,V2,V3,ind=aG+3*x+lG*y,lG-(2+x2-x1-pic[0][2])*3,x2+2-pic[0][2],y2+2-pic[0][3],v1+3,v2+3,v3+3 if sim<1 then while y<ye do while x<xe do local function Compare() ind=AG+pic[i][6] if rmem("unsigned char*",ind)[v1]<pic[i][v1]or rmem("unsigned char*",ind)[v1]>pic[i][V1]then return false elseif rmem("unsigned char*",ind)[v2]<pic[i][v2]or rmem("unsigned char*",ind)[v2]>pic[i][V2]then return false elseif rmem("unsigned char*",ind)[v3]<pic[i][v3]or rmem("unsigned char*",ind)[v3]>pic[i][V3]then return false end return true end ------------------------------------------------------------------------ while sr and i<pic[0][0]do i=i+1 sr=Compare() end if sr then af[k],k={x,y},k+1 if k>numf then if dG then deleteimage(aG) end return af end end AG,x,sr,i,j=AG+3,x+1,true,0,0 -- j - пропущенные пиксели end AG,x,y=AG+shi,x1,y+1 end else while y<ye do while x<xe do local function Compare() ind=AG+pic[i][6] if rmem("unsigned char*",ind)[v1]<pic[i][v1]or rmem("unsigned char*",ind)[v1]>pic[i][V1]then j=j+1 if j>sim then return false end elseif rmem("unsigned char*",ind)[v2]<pic[i][v2]or rmem("unsigned char*",ind)[v2]>pic[i][V2]then j=j+1 if j>sim then return false end elseif rmem("unsigned char*",ind)[v3]<pic[i][v3]or rmem("unsigned char*",ind)[v3]>pic[i][V3]then j=j+1 if j>sim then return false end end return true end ------------------------------------------------------------------------ while sr and i<pic[0][0]do i=i+1 sr=Compare() end if sr then af[k],k={x,y},k+1 if k>numf then if dG then deleteimage(aG) end return af end end AG,x,sr,i,j=AG+3,x+1,true,0,0 -- j - пропущенные пиксели end AG,x,y=AG+shi,x1,y+1 end end else ci,v1,v2,v3=pic[1][2]*3,v1 or 0,v2 or 1,v3 or 0 local AG,AL,shi,xe,ye,ag,al,raz=aG+3*x+lG*y,pic[1][1],lG-(2+x2-x1-pic[1][2])*3,x2+2-pic[1][2],y2+2-pic[1][3] while y<ye do while x<xe do while sr and j<pic[1][3]do ag,al=AG,AL while sr and i<ci do raz,i=rmem("unsigned char*",ag)[i+v3]-rmem("unsigned char*",al)[i+v3],i+v2 -- БЫСТРО -- raz,i=rmem("unsigned char*",ag)[i+v3]-rmem("unsigned char*",al+v3)[i],i+v2 -- ТОРМОЗ -- raz,i=rmem("unsigned char*",ag)[i+v3]-rmem("unsigned char*",al)[i+2],i+v2 -- НЕПОНЯТНЫЙ ТОРМОЗ if raz~=0 then if raz>0 then if raz>v1 then sr=false end elseif raz<-v1 then sr=false end end end ag,al,i,j=ag+lG,al+pic[1][4],0,j+1 end if sr then af[k],k={x,y},k+1 if k>numf then if dL then deleteimage(pic[1][1]) end if dG then deleteimage(aG) end return af end end AG,x,sr,i,j=AG+3,x+1,true,0,0 -- j - текущая ордината картинки end AG,x,y=AG+shi,x1,y+1 end if dL then log("udpic") deleteimage(pic[1][1]) end end if dG then log("udget") deleteimage(aG) end return af end -------------------------------------------------------------------------------- log "clear" log "mode compact" -- распакуйте картинки в каталог Пилота (всего 2 штуки) local pg,wg,hg,lg=loadimage([[scr.bmp]]) local pl,wl,hl,ll=loadimage([[target_.bmp]])
tmc=os.clock() local aff=FindImage(pg,lg,0,0,1919,1079,{{pl,wl,hl,ll}},9,71,0,3,2) tmc=os.clock()-tmc log("Время : ",tmc) --13.41 log(#aff) for i=1, #aff do log(table.concat(aff[i], " ")) end deleteimage(pg) deleteimage(pl)
Я заремарил тормозные варианты, глянь для интереса. Сразу скажу, тело функции особо не смотри, ничего там интересного нет. Короче вот из-за этой непонятной на данный момент особенности и возникают НЕПРЕДВИДЕННЫЕ тормоза. Картинки только закинь не забудь. Переменная v3, которой я "играю" равна 2. Для меня загадкой является ещё и то обстоятельство, что если вместо переменной задаю константой (значение 2), то тоже возникает тормоз во 100 раз. Если найдётся причина, то и продвинутый режим поиска будет летать. Прикол ещё в том, что на левую часть выражения все эти манипуляции НИКАК не влияют. Пробовал грузить картинку шириной 28 пикселей, чтобы была кратность 4 - РЕЗУЛЬТАТ ТОТ ЖЕ. Вот такие фокусы творятся.
Прикрепленные файлы
pictures.zip ( 2,23 мегабайт )
Кол-во скачиваний: 45
|
|
|
|
sutra |
18.2.2019, 3:22
|
      
Adept
Сообщений: 923
Регистрация: 10.8.2018 Группа: Пользователи Наличность: 0
Пользователь №: 19.007

|
Спасибо, Дарк, да не бери даже в голову. Я сам ещё поколдую, может ещё чего нарою. Сделаю 2 варианта, одну заготовку под dll, а вторую чисто луашную. Я посмотрел по скорости, 1920х1080 считывает примерно за 1 сотую секунды. Решил попробовать сделать таким образом, сначала всё читаю из памяти, потом обрабатываю. Получится 100% намного быстрее в продвинутом поиске, опять же можно будет и снимок экрана при желании анализировать, в общем подумаю ещё над концепцией, а уж ты потом сам решишь что да как.
А может кто научит как dll-ку подцепить написанную на Делфи, так мне больше ничего и не надо будет. Не научат, тоже не смертельно.
|
|
|
|
sutra |
18.2.2019, 19:08
|
      
Adept
Сообщений: 923
Регистрация: 10.8.2018 Группа: Пользователи Наличность: 0
Пользователь №: 19.007

|
Вот что значит отсутствие понимания принципов работы. Вынес локальную функцию сравнения из цикла, сразу стало быстрее в 2,5 раза, точнее я её уже совсем убрал, больше она там вообще не нужна. Ну и ещё плюс процентов 10 за счёт уменьшения математики. В общем вполне достойная скорость получилась, при разумных параметрах. Всего 0,2 сек. на моей машинке, при поиске всех картинок, на снимке формата HD, с использованием параметра схожести картинок. Облагородить только ещё всё надо. Так что Дарк даже не торопись смотреть мою предыдущую "мазню", хотя конечно факт тормозов в примере, который я дал, плохо поддаётся логическому осмыслению.
|
|
|
|
sutra |
19.2.2019, 18:50
|
      
Adept
Сообщений: 923
Регистрация: 10.8.2018 Группа: Пользователи Наличность: 0
Пользователь №: 19.007

|
Не перестаю удивляться (разочаровываться) lua. У меня возник вопрос. Это "неуважение" к функции чтения памяти или такая хрень может вылезать где угодно и когда угодно? Если первое, то бог с ним, обойдём, а если второе??? На тебе Дарк ещё один пример ТОРМОЗОВ. Просто непостижимая логика работы. Для лучшего восприятия специально даю локализованный кусок кода. Или это только у меня такие тормоза??? Код теста
Код --lua local ffi=require "ffi" local rmem=ffi.cast local function CreateFindArray(co,LG) local k,q,b,g,r,p,d,ad,w,h,l=0,1,ffi.new("uint8_t"),ffi.new("uint8_t"),ffi.new("uint8_t"),ffi.new("uint8_t[6]"),ffi.new("int16_t[6]"),co[1][1],co[1][2],co[1][3],co[1][4] local ar,f,x,y,i,R,G,B,P,D,RG,RB,GB,ba,ga,ra=ffi.new("uint32_t[?][9]",w*h),ffi.new("uint16_t["..h.."]["..w.."]") while q<#co do & nbsp;q,R,G,B,P,D,RG,RB,GB,y,x,i=q+1,true,true,true,true,true,true,true,true,0,0, ad if co[q].R then P,R,p[0],p[1]=false,false,co[q].R,co[q].R2 or co[q].R end if co[q].G then P,G,p[2],p[3]=false,false,co[q].G,co[q].G2 or co[q].G end if co[q].B then P,B,p[4],p[5]=false,false,co[q].B,co[q].B2 or co[q].B end if co[q].RG then D,RG,d[0],d[1]=false,false,co[q].RG,co[q].RG2 or 255 end if co[q].RB then D,RB,d[2],d[3]=false,false,co[q].RB,co[q].RB2 or 255 end if co[q].GB then D,GB,d[4],d[5]=false,false,co[q].GB,co[q].GB2 or 255 end if co[q].acc then acc=(100-co[q].acc)/100 else acc=0 end if co[q].dev then v=co[q].dev else v=0 end if co[q].fgr then while y<h do while x<w do if f[y][x]==0 then b,g,r=rmem("unsigned char*",i)[0],rmem("unsigned char*",i)[1],rmem("unsigned char*",i)[2] if(D or((RG or r-g>=d[0]and r-g<=d[1])and(RB or r-b>=d[2]and r-b<=d[3])and(GB or g-b>=d[4]and g-b<=d[5])))and(P or((R or r>=p[0]and r<=p[1])and(G or g>=p[2]and g<=p[3])and(B or b>=p[4]and b<=p[5])))then k,ba,ga,ra,f[y][x]=k+1,b*acc,g*acc,r*acc,1 ar[k]={math.max(0,math.floor(b-ba-v)),math.max(0,math.floor(g-ga-v)),math.max(0,math.floor(r-ra-v)),math.min(255,math.ceil(b+ba+v)),math.min(255,math.ceil(g+ga+v)),math.min(255,math.ceil(r+ra+v)),x*3+y*LG} end end i,x=i+3,x+1 end y=y+1 i,x=ad+y*l,0 end else while y<h do while x<w do if f[y][x]==0 then b,g,r=rmem("unsigned char*",i)[0],rmem("unsigned char*",i)[1],rmem("unsigned char*",i)[2] if not(D or((RG or r-g>=d[0]and r-g<=d[1])and(RB or r-b>=d[2]and r-b<=d[3])and(GB or g-b>=d[4]and g-b<=d[5])))and(P or((R or r>=p[0]and r<=p[1])and(G or g>=p[2]and g<=p[3])and(B or b>=p[4]and b<=p[5])))then k,ba,ga,ra,f[y][x]=k+1,b*acc,g*acc,r*acc,1 ar[k]={math.max(0,math.floor(b-ba-v)),math.max(0,math.floor(g-ga-v)),math.max(0,math.floor(r-ra-v)),math.min(255,math.ceil(b+ba+v)),math.min(255,math.ceil(g+ga+v)),math.min(255,math.ceil(r+ra+v)),x*3+y*LG} end end i,x=i+3,x+1 end y=y+1 i,x=ad+y*l,0 end end end deleteimage(ad) ar[0]={k,LG,w,h,l} return ar end -------------------------------------------------------------------------------- local function FindImage(aG,lG,x1,y1,x2,y2, pic, numf, sim,v1,v2,v3) local af,k,dG,dL, ci={},1,false,false local sr,i,j,x,y=true,0,0,x1,y1 sim,v1,v2,v3=pic[0][0]*0.01*(100-sim),v1 or 0,v2 or 1,v3 or 2 v1,v2,v3=v1 or 0,v2 or 1,v3 or 2 local AG,shi,xe,ye,V1,V2,V3,ind=aG+3*x+lG*y,lG-(2+x2-x1-pic[0][2])*3,x2+2-pic[0][2],y2+2-pic[0][3],v1+3,v2+3,v3+3 while y<ye do while x<xe do while sr and i<pic[0][0]do i=i+1 ind=AG+pic[i][6] -- if rmem("unsigned char*",ind)[v1]<pic[i][v1]or rmem("unsigned char*",ind)[v1]>pic[i][V1]then j=j+1 if j>sim then sr=false end -- elseif rmem("unsigned char*",ind)[v2]<pic[i][v2]or rmem("unsigned char*",ind)[v2]>pic[i][V2]then j=j+1 if j>sim then sr=false end -- elseif rmem("unsigned char*",ind)[v3]<pic[i][v3]or rmem("unsigned char*",ind)[v3]>pic[i][V3]then j=j+1 if j>sim then sr=false end -- end if rmem("unsigned char*",ind)[v1]<pic[i][v1]or rmem("unsigned char*",ind)[v1]>pic[i][V1]then sr=false elseif rmem("unsigned char*",ind)[v2]<pic[i][v2]or rmem("unsigned char*",ind)[v2]>pic[i][V2]then sr=false elseif rmem("unsigned char*",ind)[v3]<pic[i][v3]or rmem("unsigned char*",ind)[v3]>pic[i][V3]then j=j+1 if j>sim then sr=false end -- sr=false -- если разремарить тормоза вне зависимости от значения sim end end if sr then af[k],k={x,y},k+1 if k>numf then if dG then deleteimage(aG) end return af end end AG,x,sr,i,j=AG+3,x+1,true,0,0 -- j - пропущенные пиксели end AG,x,y=AG+shi,x1,y+1 end return af end -------------------------------------------------------------------------------- log "clear" log "mode compact" local aff -- распакуйте картинки в каталог Пилота (всего 2 штуки) local pg,wg,hg,lg=loadimage([[scr.bmp]]) local pl,wl,hl,ll=loadimage([[target_.bmp]]) local pix=CreateFindArray({{pl,wl,hl,ll},{RG=100,fgr=true,acc=90,dev=5}},lg) tmc=os.clock() -- Разремарить нижестоящий вызов функции и УДИВИТЬСЯ!! -- aff=FindImage(pg,lg,0,0,1919,1079,pix,9,98)--, 2,1,0) aff=FindImage(pg,lg,0,0,1919,1079,pix,9,99)--, 2,1,0) tmc=os.clock()-tmc log("Время : ",tmc) --13.41 log(#aff) for i=1, #aff do log(table.concat(aff[i], " ")) end deleteimage(pg) --deleteimage(pl)
|
|
|
|
sutra |
20.2.2019, 15:57
|
      
Adept
Сообщений: 923
Регистрация: 10.8.2018 Группа: Пользователи Наличность: 0
Пользователь №: 19.007

|
Зря я грешил на rmem. Абсолютно на одном и том же месте спотыкается LUA. Задолбал. Настолько криво работают циклы ... в них то и вся прелесть, держи Дарк ещё пример. Дал опять вырезку. Код теста
Код --lua local ffi=require "ffi" local rmem=ffi.cast local function ImageToArray(addr,len,fx1,fy1,fx2,fy2) -- ЧТЕНИЕ ВСЕХ ПИКСЕЛЕЙ В ОБЛАСТИ ПАМЯТИ local h,w=fy2-fy1+1,fx2-fx1+1 local k=h*w local ind,sh,arr=addr+3*fx1+len*fy1,len-w*3,ffi.new("uint8_t["..k.."][3]") if w==len then for i=0,k-1 do for j=0,2 do arr[i][j]=rmem("unsigned char*",ind)[j] end ind=ind+3 end else local i=0 for y=1,h do for x=0,w-1 do for j=0,2 do arr[i][j]=rmem("unsigned char*",ind)[j] end i,ind=i+1,ind+3 end ind=ind+sh end end return arr end local function CreateFindArray(co,LG) local k,q,b,g,r,p,d,ad,w,h,l=0,1,ffi.new("uint8_t"),ffi.new("uint8_t"),ffi.new("uint8_t"),ffi.new("uint8_t[6]"),ffi.new("int16_t[6]"),co[1][1],co[1][2],co[1][3],co[1][4] local ar,f,x,y,i,R,G,B,P,D,RG,RB,GB,ba,ga,ra=ffi.new("uint32_t[?][9]",w*h),ffi.new("uint16_t["..h.."]["..w.."]") while q<#co do & nbsp;q,R,G,B,P,D,RG,RB,GB,y,x,i=q+1,true,true,true,true,true,true,true,true,0,0, ad if co[q].R then P,R,p[0],p[1]=false,false,co[q].R,co[q].R2 or co[q].R end if co[q].G then P,G,p[2],p[3]=false,false,co[q].G,co[q].G2 or co[q].G end if co[q].B then P,B,p[4],p[5]=false,false,co[q].B,co[q].B2 or co[q].B end if co[q].RG then D,RG,d[0],d[1]=false,false,co[q].RG,co[q].RG2 or 255 end if co[q].RB then D,RB,d[2],d[3]=false,false,co[q].RB,co[q].RB2 or 255 end if co[q].GB then D,GB,d[4],d[5]=false,false,co[q].GB,co[q].GB2 or 255 end if co[q].acc then acc=(100-co[q].acc)/100 else acc=0 end if co[q].dev then v=co[q].dev else v=0 end if co[q].fgr then while y<h do while x<w do if f[y][x]==0 then b,g,r=rmem("unsigned char*",i)[0],rmem("unsigned char*",i)[1],rmem("unsigned char*",i)[2] if(D or((RG or r-g>=d[0]and r-g<=d[1])and(RB or r-b>=d[2]and r-b<=d[3])and(GB or g-b>=d[4]and g-b<=d[5])))and(P or((R or r>=p[0]and r<=p[1])and(G or g>=p[2]and g<=p[3])and(B or b>=p[4]and b<=p[5])))then k,ba,ga,ra,f[y][x]=k+1,b*acc,g*acc,r*acc,1 ar[k]={math.max(0,math.floor(b-ba-v)),math.max(0,math.floor(g-ga-v)),math.max(0,math.floor(r-ra-v)),math.min(255,math.ceil(b+ba+v)),math.min(255,math.ceil(g+ga+v)),math.min(255,math.ceil(r+ra+v)),x+y*LG} end end i,x=i+3,x+1 end y=y+1 i,x=ad+y*l,0 end else while y<h do while x<w do if f[y][x]==0 then b,g,r=rmem("unsigned char*",i)[0],rmem("unsigned char*",i)[1],rmem("unsigned char*",i)[2] if not(D or((RG or r-g>=d[0]and r-g<=d[1])and(RB or r-b>=d[2]and r-b<=d[3])and(GB or g-b>=d[4]and g-b<=d[5])))and(P or((R or r>=p[0]and r<=p[1])and(G or g>=p[2]and g<=p[3])and(B or b>=p[4]and b<=p[5])))then k,ba,ga,ra,f[y][x]=k+1,b*acc,g*acc,r*acc,1 ar[k]={math.max(0,math.floor(b-ba-v)),math.max(0,math.floor(g-ga-v)),math.max(0,math.floor(r-ra-v)),math.min(255,math.ceil(b+ba+v)),math.min(255,math.ceil(g+ga+v)),math.min(255,math.ceil(r+ra+v)),x+y*LG} end end i,x=i+3,x+1 end y=y+1 i,x=ad+y*l,0 end end end deleteimage(ad) ar[0]={k,LG,w,h,l} return ar end -------------------------------------------------------------------------------- local function FindImage(aG,lG,x1,y1,x2,y2, pic, numf, sim,v1,v2,v3) local af,k={},1 sim,v1,v2,v3=pic[0][0]*0.01*(100-sim),v1 or 0,v2 or 1,v3 or 2 local sr,i,j,x,y,wi,ins=true,0,0,0,0,x2-x1+1,0 local xe,ye,V1,V2,V3,n=wi+1-pic[0][2], (y2+2-pic[0][3]-y1)*wi, v1+3,v2+3,v3+3 -- в pic посылать свою ширину поиска local a=ImageToArray(aG,lG,x1,y1,x2,y2) while y<ye do while x<xe do while sr and i<pic[0][0]do i=i+1 n=ins+pic[i][6] if a[n][v1]<pic[i][v1]or a[n][v1]>pic[i][V1]or a[n][v2]<pic[i][v2]or a[n][v2]>pic[i][V2]or a[n][v3]<pic[i][v3]or a[n][v3]>pic[i][V3]then j=j+1 if j>sim then sr=false end end end if sr then af[k],k={x,y/wi},k+1 if k>numf then return af end end x,sr,i,j,ins=x+1,true,0,0,ins+1 -- j - пропущенные пиксели end x,y,ins=0,y+wi,ins+pic[0][2]-1 end return af end -------------------------------------------------------------------------------- log "clear" log "mode compact" local aff -- распакуйте картинки в каталог Пилота (всего 2 штуки) local pg,wg,hg,lg=loadimage([[scr.bmp]]) local pl,wl,hl,ll=loadimage([[target_.bmp]]) local pix=CreateFindArray({{pl,wl,hl,ll},{RG=100,fgr=true,acc=90,dev=5}},1920) -- !!!!!!!!!!!! А вот теперь заремарьте следующие 4 строки !!!!!!!!!!!!!!!!! tmc=os.clock() aff=FindImage(pg,lg,0,0,1919,1079,pix,9,98)--, 2,1,0) tmc=os.clock()-tmc log("Время : ",tmc) --13.41 log(#aff) for i=1, #aff do log(table.concat(aff[i], " ")) end
tmc=os.clock() aff=FindImage(pg,lg,0,0,1919,1079,pix,9,100)--, 2,1,0) tmc=os.clock()-tmc log("Время : ",tmc) --13.41 log(#aff) for i=1, #aff do log(table.concat(aff[i], " ")) end deleteimage(pg) deleteimage(pl)
Чисто проверял, вынес вообще rmem, что поразительно, явно тупит в одном и том же месте. Я даже ошарашен, да у меня уйма всяких циклов. И как там всё это работать будет? Может я чего не так делаю? Короче, я "приплыл". Не знаю как с этим бороться. Извращаться? Методом тыка? Или может сразу жалобу в ООН? (IMG: style_emoticons/default/biggrin.gif) (IMG: style_emoticons/default/biggrin.gif) (IMG: style_emoticons/default/biggrin.gif) Вот лично мне например и не надо искать перекрытые объекты. Мне как раз надо быстро искать с параметром sim 100%. А на 100% - стопроцентные тормоза. Сорри за каламбур.
|
|
|
|
|
  |
8 чел. читают эту тему (гостей: 8, скрытых пользователей: 0)
Пользователей: 0
|
|