Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в эту темуОткрыть новую тему
> Ускорение работы color, color требует отдельный кадр, можно ли ускорить?
KudesniK
сообщение 10.7.2018, 9:09
Сообщение #1


*

Registred
Сообщений: 6
Регистрация: 10.7.2018
Группа: Пользователи
Наличность: 0
Пользователь №: 18.992



Было замечено, что каждый вызов функции color требует отдельный кадр, рассмотрим пример (отключено слежение, задержка 0ms):
Код
set #counter 0
set timer
while 1
    if timer > 1000
        hint #counter
        set timer
        set #counter 0
    end_if

    set #counter #counter + 1
    set #color color (53, 144)
end_while
end_script
в окнах, где используется vsync количество вызовов color будет ограничено частотой экрана, в моем случае 60, в остальных окнах количество вызовов color может доходить до нескольких тысяч.

Таким образом при необходимости анализа шести разных пикселей на цвет, мы получаем падение производительности скрипта до десяти проверок в секунду, при необходимости контролировать десять пикселей, уже шесть операций в секунду.

Например, заменив одну операцию color на (как пример):
Код
if 255, 380 16777215 and 200, 300 15588051 and 12, 27 5621216 and 33, 33 13743257
    send {f1}
end_if
мы получаем падение производительности в четыре раза (четыре вызова color), т.е. до 15 проверок в секунду, пример выше использован для демонстрации. Соответственно при пяти таких блоках производительность уже будет около трех проверок в секунду.

Альтернативный вариант сделать один снимок экрана и в нем искать нужные цвета в нужных пикселях, но я не нашел как взять цвет пикселя в результате работы GetImage.

Может кто сталкивался, подскажите как решали, или как взять цвет пикселя после фотографии экрана.
Пользователь в офлайнеDelete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
Cockney
сообщение 10.7.2018, 11:09
Сообщение #2


********

Master
Сообщений: 1.395
Регистрация: 22.6.2013
Группа: Пользователи
Наличность: 21043
Пользователь №: 16.156



Если картинка меняется, а захватывать нужно всю область, то это едва ли будет быстрей 4х color.



Использовать findcolor.
Пользователь в офлайнеDelete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
KudesniK
сообщение 10.7.2018, 12:05
Сообщение #3


*

Registred
Сообщений: 6
Регистрация: 10.7.2018
Группа: Пользователи
Наличность: 0
Пользователь №: 18.992



Скрипт так же успевает сделать 60 фотографий всего окна.

Идея была в том, что часть проверок на цвет сосредоточены в достаточно небольшой области: примерно 200 на 100 пикселей, если сделать скриншот этой области и изучить цвета уже в ней, это в теории могло быть быстрее чем 1/60 секунды на пиксель (ведь будет обращение к двухмерному массиву, что является крайне быстрой операцией), но как оказалось получить цвет пикселя после GetImage крайне сложно: readmem очень медленная операция, а так же часто приводит к "Client sooner dead, than alive".
Пользователь в офлайнеDelete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
Cockney
сообщение 10.7.2018, 12:36
Сообщение #4


********

Master
Сообщений: 1.395
Регистрация: 22.6.2013
Группа: Пользователи
Наличность: 21043
Пользователь №: 16.156



Само снятие(без проверки цвета) области 200х100 будет медленней 4х вызовов color(и снятие и проверка).
Пользователь в офлайнеDelete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
cirus
сообщение 10.7.2018, 12:44
Сообщение #5


**********

Elder
Сообщений: 3.480
Регистрация: 18.8.2014
Группа: Пользователи
Наличность: 26689
Пользователь №: 16.971
Возраст: 29



Цитата
Само снятие(без проверки цвета) области 200х100 будет медленней 4х вызовов color(и снятие и проверка).

Нет. Если область небольшая, то быстрее.
Цитата
readmem очень медленная операция

Быстрее, чем получение цвета.
Код
set linedelay 0
log clear
log mode compact
set %arr GetImage (0 0 1920 1080)  // получаем скрин

set #handle workwindow     // запоминаем текущее рабочее окно
set workwindow windowhandle  // рабочее окно пилот
call getcolor %arr 867, 362      // передаём массив и координаты X и Y
log $getcolor   // цвет

call getcolor %arr 863, 371      // передаём массив и координаты X и Y
log $getcolor   // цвет

set workwindow #handle   // возвращаем рабочее окно
end_script

proc getcolor %a #x #y
    set #z1 %a [1 1] + %a [1 4] * #y + #x * 3
    set #z2 %a [1 1] + %a [1 4] * #y + #x * 3 + 1
    set #z3 %a [1 1] + %a [1 4] * #y + #x * 3 + 2
    readmem #b #z1 b
    readmem #g #z2 b
    readmem #r #z3 b
    set #color #r + #g * 256 + #b * 65536
    set $result #color
end_proc

Если скрин делать не от координат 0 0, то от передаваемых координат надо отнимать начальные x y.
Пользователь в офлайнеDelete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
KudesniK
сообщение 10.7.2018, 13:50
Сообщение #6


*

Registred
Сообщений: 6
Регистрация: 10.7.2018
Группа: Пользователи
Наличность: 0
Пользователь №: 18.992



Замеры производительности:
17ms (1/60s) на вызов
Код
get color #color 100 100


1-2ms на вызов
Код
set %arr GetImage (0 0 200 200)

9-17ms на вызов
Код
call getcolor %arr 100, 100


Код
for #i 1 25
    set #t timer
    set %arr GetImage (0 0 300 300)
    set #t timer - #t
    log get-image tooks #t ms, timer
end_for


Код
for #i 1 25
    set #t timer
    call getcolor %arr 100, 100
    set #t timer - #t

    log get-color tooks #t ms, timer
end_for


Но, уберем затраты на вызов процедур:
Код
set #x 100
set #y 100
for #i 1 25
    set #t timer

    set #z1 %arr [1 1] + %arr [1 4] * #y + #x * 3
    set #z2 %arr [1 1] + %arr [1 4] * #y + #x * 3 + 1
    set #z3 %arr [1 1] + %arr [1 4] * #y + #x * 3 + 2
    readmem #b #z1 b
    readmem #g #z2 b
    readmem #r #z3 b
    set #color #r + #g * 256 + #b * 65536

    set #t timer - #t

    log get-color tooks #t ms, timer
end_for


получаем 1ms на вызов.
Пользователь в офлайнеDelete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
KudesniK
сообщение 10.7.2018, 14:15
Сообщение #7


*

Registred
Сообщений: 6
Регистрация: 10.7.2018
Группа: Пользователи
Наличность: 0
Пользователь №: 18.992



Имеем производительность порядка 1100 пикселей в секунду по сравнению с 60 у get color.
При увеличении области до 800х600 производительность падает до 600 в секунду.
Область 1920х1080 - 400 пикселей в секунду.
"Фотография" экрана происходит для анализа 20 пикселей.

Всем спасибо, с большего меня это решение устраивает, может в будущем что-то переработают, пока живу с вот этим.

Код
set #handle workwindow

set timer

while 1
   if timer > 1000
        hint #counter
        log #counter
        set timer
        set #counter 0
    end_if

    set #counter #counter + 1

    set workwindow #handle
    set %arr GetImage (1 1 200 200)

    set workwindow windowhandle

    for #i 1 20
        set #x random(200)
        set #y random(200)
        // set #x 21
        // set #y 41
        gosub fast_color
        // log #color
    end_for
end_while

:fast_color
    set #z1 %arr [1 1] + %arr [1 4] * (#y - 1) + (#x - 1) * 3
    set #z2 %arr [1 1] + %arr [1 4] * (#y - 1) + (#x - 1) * 3 + 1
    set #z3 %arr [1 1] + %arr [1 4] * (#y - 1) + (#x - 1) * 3 + 2
    readmem #b #z1 b
    readmem #g #z2 b
    readmem #r #z3 b
    set #color #b * 256 * 256 + #g * 256 + #r
return
Пользователь в офлайнеDelete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
cirus
сообщение 10.7.2018, 14:41
Сообщение #8


**********

Elder
Сообщений: 3.480
Регистрация: 18.8.2014
Группа: Пользователи
Наличность: 26689
Пользователь №: 16.971
Возраст: 29



Цитата
set %arr GetImage (1 1 200 200)
set #x 21
set #y 41

В этом случае надо проверять не в 21 41, а 20 40. Или скрин делать 0 0 200 200.
Неплохо бы после получения цветов устанавливать рабочее окно обратно, то, к которому была изначально привязка, иначе к пилоту будет скрипт привязан.
Код
set #handle workwindow  // запомнили рабочее окно
set workwindow windowhandle
for #i 1 20
    set #x random(200)
    set #y random(200)
    // set #x 21
    // set #y 41
    gosub fast_color
    // log #color
end_for

set workwindow #handle  // вернули рабочее окно, иначе привязка будет к пилоту.
Пользователь в офлайнеDelete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
KudesniK
сообщение 10.7.2018, 15:01
Сообщение #9


*

Registred
Сообщений: 6
Регистрация: 10.7.2018
Группа: Пользователи
Наличность: 0
Пользователь №: 18.992



Цитата(cirus @ 10.7.2018, 14:41) *

Неплохо бы после получения цветов устанавливать рабочее окно обратно, то, к которому была изначально привязка, иначе к пилоту будет скрипт привязан.


ВРоде не забыл же, перед тем как взять очередную картинку.
Код
    set workwindow #handle
    set %arr GetImage (1 1 200 200)


Про координаты спасибо, почитаю документацию.
Пользователь в офлайнеDelete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
cirus
сообщение 10.7.2018, 15:20
Сообщение #10


**********

Elder
Сообщений: 3.480
Регистрация: 18.8.2014
Группа: Пользователи
Наличность: 26689
Пользователь №: 16.971
Возраст: 29



Цитата
ВРоде не забыл же, перед тем как взять очередную картинку.

После:
Код
set workwindow windowhandle

Все действия будут относится к пилоту. Т. е. клики, нажатия и прочее.
Лучше так:
Код
set #handle workwindow  // запомнили окно

while 1
    set %arr GetImage (1 1 200 200)
    set workwindow windowhandle
       // получили цвета
    set workwindow #handle // вернули рабочее окно
       // тут нужные действия
end_while
Пользователь в офлайнеDelete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения
DarkMaster
сообщение 11.7.2018, 1:54
Сообщение #11


***********

Модератор UOPilot
Сообщений: 9.462
Регистрация: 2.12.2008
Группа: Супермодераторы
Наличность: 27674
Пользователь №: 11.279



В общем и целом уже достаточно давно использую findcolor вместо color. Ирония в том, что find'ы незаметно для пользователей перешли на новые алогоритмы получения изображений, а вот color, который вроде как и является частным случаем findcolor'a просто забыли перевести на новую схему работы. В общем рекомендую брать луа и использовать обертку под это дело.


--------------------
Скрипты UOPilot под заказ.
Консультации по UOpilot 15$/час.
Услуги Lua разработчика (не пилот, проекты, постоянка)
Disсоrd:
Kov____
Пользователь в офлайнеDelete PostОтправить личное сообщение
Вернуться в начало страницы
+Ответить с цитированием данного сообщения

Ответить в эту темуОткрыть новую тему
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 

- Текстовая версия | Версия для КПК Сейчас: 16.4.2024, 7:40
Designed by Nickostyle