|
|
  |
Разработка findcolor, findimage, Pure lua |
|
|
Cockney |
7.6.2022, 10:34
|
       
Master
Сообщений: 1.403
Регистрация: 22.6.2013 Группа: Пользователи Наличность: 22550
Пользователь №: 16.156

|
Возможно он всегда проверяет ограниченный набор пикселей, скажем примерно 30 из всего изображения (этим я объясняю константность времени поиска), может опирается на саму структуру изображения, находит редкие пиксели, например, или ищет пятна одного цвета. Вроде это уже обсуждалось с sutra как-то. Ну и различные ухищрения для ухода от лишних проверок, например хранить в матрице бинарной результаты сравнения пикселей, а потом ее просто посчитать и сравнить 1 раз в конце поиска. Цитата(Cockney @ 7.6.2022, 10:33)  Возможно он всегда проверяет ограниченный набор пикселей, скажем примерно 30 из всего изображения (этим я объясняю константность времени поиска), может опирается на саму структуру изображения, находит редкие пиксели, например, или ищет пятна одного цвета. Вроде это уже обсуждалось с sutra как-то. Ну и различные ухищрения для ухода от лишних проверок, например хранить в матрице бинарной результаты сравнения пикселей, а потом ее просто посчитать и сравнить 1 раз в конце поиска.
П.с. а вообще мог бы спросить напрямую у него на условиях не разглашения
|
|
|
|
DarkMaster |
16.6.2022, 13:08
|
          
Модератор UOPilot
Сообщений: 9.735
Регистрация: 2.12.2008 Группа: Супермодераторы Наличность: 29624
Пользователь №: 11.279

|
Ты знаешь за прошедшие пару дней я получил столько удовольствия от оптимизации, что для меня ffi в луа c jit'ом впридачу кажутся более предсказуемыми. Ну, например, есть цикл: Код for (char *restrict area_y = area + area_offset_y1*area_lenght; area_y < area + (area_offset_y2-pattern_height)*area_lenght; area_y = area_y + area_lenght){ // Перебор пикселей в линии скрина for (char *restrict area_x = area_y+area_offset_x1*3; area_x < area_y+(area_offset_x2-pattern_width)*3; area_x = area_x + 3){
Вот только незадача - нужно компенсировать "убегающую" единичку и строгое сравнение. area_y < area + (area_offset_y2-pattern_height)*area_lenght area_y < area + (area_offset_y2-pattern_height+2)*area_lenght area_x < area_y+(area_offset_x2-pattern_width)*3 area_x < area_y+(area_offset_x2-pattern_width+2)*3 Ну какие могут быть от этого проблемы? А проблемы +26% времени поиска. Почему? Как? Площадь увеличилась на 4%, а время на 26%. Причем если не делать эти +2, а просто при вызове передать заведомо увеличенные на 2 pattern_height и pattern_width, то время выполнения не то, что не увеличится на 26%, а и вовсе где-то в погрешностях затеряется. Причем это вершина айсберга. Там столько подобного бреда уже словил, что дальше некуда. Добавляем лишний счетчик - скорость увеличивается (просто счетчик который пишет в память выделенную вне длл). Удаляем паразитное условие, которое было просто для отладки - скорость падает. С такими приколами уже не знаешь, чего ожидать. Сообщение отредактировал DarkMaster - 27.6.2022, 17:03
--------------------
Скрипты UOPilot под заказ. Консультации по UOpilot 15$/час. Услуги Lua разработчика (не пилот, проекты, постоянка) Disсоrd: Kov____
|
|
|
|
Cockney |
16.6.2022, 22:26
|
       
Master
Сообщений: 1.403
Регистрация: 22.6.2013 Группа: Пользователи Наличность: 22550
Пользователь №: 16.156

|
Цитата(DarkMaster @ 16.6.2022, 13:08)  Ты знаешь за прошедшие пару дней я получил столько удовольствия от оптимизации, что для меня ffi в луа c jit'ом впридачу кажутся более предсказуемыми. Ну, например, есть цикл: Код for (char *restrict area_y = area + area_offset_y1*area_lenght; area_y < area + (area_offset_y2-pattern_height)*area_lenght; area_y = area_y + area_lenght){ // Перебор пикселей в линии скрина for (char *restrict area_x = area_y+area_offset_x1*3; area_x < area_y+(area_offset_x2-pattern_width)*3; area_x = area_x + 3){
Вот только незадача - нужно компенсировать "убегающую" единичку и строгое сравнение. area_y < area + (area_offset_y2-pattern_height)*area_lenght area_y < area + (area_offset_y2-pattern_height+2)*area_lenght area_x < area_y+(area_offset_x2-pattern_width)*3 area_x < area_y+(area_offset_x2-pattern_width+2)*3 Ну какие могут быть от этого проблемы? А проблемы +26% времени поиска. Почему? Как? Площадь увеличилась на 4%, а время на 26%. Причем если не делать эти +2, а просто при вызове передать заведомо увеличенные на 2 pattern_height и pattern_width, то время выполнения не то, что не увеличится на 26%, а и вовсе где-то в погрешностях затеряется. Причем это вершина айсберга. Там столько подобного бреда уже словил, что дальше некуда. Добавляем лишний счетчик - скорость увеличивается (просто счетчик который пишет в память выделенную вне длл). Удаляем паразитное условие, которое было просто для отладки - скорость падает. С такими приколами уже не знаешь, чего ожидать. Я уже вроде писал, что особо ты ничего выкрутасами этими не добьешься. Мое мнение - нужно снижать алгоритмическую сложность. Условно, в стандартном варианте это O(n^4), т.к. 4 цикла вложенных. Сделая O(n^3) или еще лучше - O(n^2). Далее думай уже над мелочами типа скорость обработки инта. А касательно магии, так это нормально. Тут нет логики. Нужно постоянно смотреть выхлоп компилятора, например, в rust, бывают такие вещи: Код int f1(int a, int b) { for (int i = 0; i < b; ++i) { a += i; if (a - 1 > b - 3) return a; } }
Выполняется условные 10мс А вот в таком варианте: Код int f1(int a, int b) { for (int i = 0; i < b; ++i) { a += i; if (a - 1 > b - 3) return a; } unreacheable!(); //подсказка компилятору }
Выполняется менее 1мс. Естественно такое поймать глазами почти невозможно. А компиляторы пока слабы в таких анализах вроде как. Сообщение отредактировал DarkMaster - 27.6.2022, 17:03
|
|
|
|
DarkMaster |
17.6.2022, 1:53
|
          
Модератор UOPilot
Сообщений: 9.735
Регистрация: 2.12.2008 Группа: Супермодераторы Наличность: 29624
Пользователь №: 11.279

|
Цитата Условно, в стандартном варианте это O(n^4), т.к. 4 цикла вложенных. Сделая O(n^3) или еще лучше - O(n^2). разворачивание вложенных циклов привело лишь к увеличению времени работы. Делал разные варианты (сейчас есть 8 штук и еще один на луа) вплоть до двух goto без форов и прозрачного вычисления следющего указателя. Смысла в этом не оказалось. Вцелом скорость сносная - 28мс на грубый перебор паттерна 10*10 в скрине 1920*1080 с дико древнем камнем q9600. Да, хотелось бы нолик убрать, а в идеале получить ~2мс на 15*15, но думаю, что это не очень реально - просто тактов даже при идеальном коде не хватит. У меня есть ряд идей по ускорению поиска, которые могут привести к скорости значительно выше, но при этом не будет соблюдаться правило строго порядка слева->направо, сверху->вниз, могут быть пропуски. Т.е. это шустрый вариант когда нужно выдернуть любое подходящее изображение в некоторой области (по факту не менее 90% поиска именно такие). Ну и многопоточку никто не отменял. Но все попорядку - нужно базу иметь адекватную. А в базе дикий вынос мозга ибо война с компилятором (IMG: style_emoticons/default/smile.gif)
--------------------
Скрипты UOPilot под заказ. Консультации по UOpilot 15$/час. Услуги Lua разработчика (не пилот, проекты, постоянка) Disсоrd: Kov____
|
|
|
|
Cockney |
17.6.2022, 10:12
|
       
Master
Сообщений: 1.403
Регистрация: 22.6.2013 Группа: Пользователи Наличность: 22550
Пользователь №: 16.156

|
Цитата(DarkMaster @ 17.6.2022, 1:53)  разворачивание вложенных циклов привело лишь к увеличению времени работы. Делал разные варианты (сейчас есть 8 штук и еще один на луа) вплоть до двух goto без форов и прозрачного вычисления следющего указателя. Смысла в этом не оказалось. Вцелом скорость сносная - 28мс на грубый перебор паттерна 10*10 в скрине 1920*1080 с дико древнем камнем q9600. Да, хотелось бы нолик убрать, а в идеале получить ~2мс на 15*15, но думаю, что это не очень реально - просто тактов даже при идеальном коде не хватит. У меня есть ряд идей по ускорению поиска, которые могут привести к скорости значительно выше, но при этом не будет соблюдаться правило строго порядка слева->направо, сверху->вниз, могут быть пропуски. Т.е. это шустрый вариант когда нужно выдернуть любое подходящее изображение в некоторой области (по факту не менее 90% поиска именно такие). Ну и многопоточку никто не отменял. Но все попорядку - нужно базу иметь адекватную. А в базе дикий вынос мозга ибо война с компилятором (IMG: style_emoticons/default/smile.gif) Разворачивание циклов это не снижение сложности. Снижение сложности это когда вместо целого изображения обрабатываешь только половину, например
|
|
|
|
DarkMaster |
17.6.2022, 12:43
|
          
Модератор UOPilot
Сообщений: 9.735
Регистрация: 2.12.2008 Группа: Супермодераторы Наличность: 29624
Пользователь №: 11.279

|
Но это снижение вложенности. Прогнозирование ветвлений и все такое. Ну и компилятор черт пойми что соберет и в какую сторону его переклинит.
А искать куски имхо очень спорная идея. Ну возможно в каких-то случаях шаг сетки может помочь, идея спорная. С тем же успехом можно просто изображение сделать меньше. Я представляю себе развлечение с попытками найти кривые пиксели и перекрасить их в фон, когда там ищет сеткой. Лично мое мнение текущая скорость выполнения даже в 1 поток допустимая. Кстати сложность тут не O^4, а O1^2*O2^2, что сильно меняет дело, учитывая, что O1 и O2 у нас очень существенно отличаются. Да и ^2 тоже очень условно ибо далеко не всегда это квадратики, но тут уже можно в какой-то степени пренебречь.
--------------------
Скрипты UOPilot под заказ. Консультации по UOpilot 15$/час. Услуги Lua разработчика (не пилот, проекты, постоянка) Disсоrd: Kov____
|
|
|
|
Cockney |
17.6.2022, 14:07
|
       
Master
Сообщений: 1.403
Регистрация: 22.6.2013 Группа: Пользователи Наличность: 22550
Пользователь №: 16.156

|
Цитата(DarkMaster @ 17.6.2022, 12:43)  Но это снижение вложенности. Прогнозирование ветвлений и все такое. Ну и компилятор черт пойми что соберет и в какую сторону его переклинит.
А искать куски имхо очень спорная идея. Ну возможно в каких-то случаях шаг сетки может помочь, идея спорная. С тем же успехом можно просто изображение сделать меньше. Я представляю себе развлечение с попытками найти кривые пиксели и перекрасить их в фон, когда там ищет сеткой. Лично мое мнение текущая скорость выполнения даже в 1 поток допустимая. Кстати сложность тут не O^4, а O1^2*O2^2, что сильно меняет дело, учитывая, что O1 и O2 у нас очень существенно отличаются. Да и ^2 тоже очень условно ибо далеко не всегда это квадратики, но тут уже можно в какой-то степени пренебречь.
Ну скажем, худшая точно о(н^4), ибо можно искать 10х10 на скрине 10х10, частные случаи да, чуть меньше, но асимптотика такая же. Почему спорная искать куски ? Если целиком искать то в игнор попадает 1 только цвет, при этом куча мусорных пикселей остается и съедает ресурсы. Ну, имхо, при поиске реального объекта типа монетки или галочки это выход, а вот просто мешанина уникальных пикселей - да, не очень.
|
|
|
|
DarkMaster |
18.6.2022, 10:10
|
          
Модератор UOPilot
Сообщений: 9.735
Регистрация: 2.12.2008 Группа: Супермодераторы Наличность: 29624
Пользователь №: 11.279

|
Цитата У тебя есть средний цвет, средняя яркость, яркость каждого пиксела, средняя яркость в рамках условного участка 3х3. Никто же не запрещает эксперементы. посмотри из чего состоит изображение с разных сторон. В августе прошлого года очень активно этим занимался. Фактически только месяц сидел за анализом одного объекта, который имел вращение, размытые границы и наклон по одной из осей. Необходимо было четко понимать, как расположен этот объект, но из-за почти полной симетрии и отсутсвия четких границ и крайне малых размеров задача оказалось очень сложной. Огромный прорыв в ее решении дал именно анализ яркостей отдельных каналов, усредненных значений и соотношения каналов. Это одна из причин почему мне хочется иметь собственный финд - подобный анализ имеет крайне высокую продуктивность. Для текстов же перевод картинки в чб по определенной границе дает фантастические результаты. Сообщение отредактировал DarkMaster - 18.6.2022, 10:12
--------------------
Скрипты UOPilot под заказ. Консультации по UOpilot 15$/час. Услуги Lua разработчика (не пилот, проекты, постоянка) Disсоrd: Kov____
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|