Быстрый Гауссов блюр (separable filter)

Вопрос Какая асимптотика у размытия картинки через свертку с ядром Гаусса размера KxK?

А что если обратить внимание что Гауссово ядро является separable ядром?

Separable filter

Вопрос Какая будет асимптотика если мы сначала выполним горизонтальные свертки размера K, и затем - вертикальные свертки размера K?

Вопрос Можно ли еще быстрее? Можно ли ускорить свертку с горизонтальным ядром размера K?

Анализ распределения: медиана и перцентиль

На этой картинке можно хорошо видеть что среднее значение (“среднее по больнице”) мало чего говорит о данных, т.к. сильно зависит от больших значений (которых может быть мало, но они в абсолюлтных значениях очень большие и поэтому перетягивают на себя одеяло).

Медиана же разбивает множество на две половины - одна половина значений меньше медианы, другая - больше.

90% перцентайль разбивает множество на две части - 90% меньших, 10% больших.

Distribution and average, median and 90th percentile visualization

Вопрос Изменится ли среднее значение если наибольшее число распределения увеличить в 239 квадрильонов раз? То есть если мы добавили очевидный выброс. А медиана? А перцентайль?

Как найти цвет фона?

Вопрос Как найти по какому значению яркости в нашей картинке с паззлом на черном фоне можно различить пиксели на пиксели фона и пиксели объекта? Можно ли взять просто максимум яркости на границе изображения? А просто 90% перцентайль?

Downscaled photo of puzzle example

Как зная цвет фона построить маску?

Как из такой маски сделать красоту?

Noisy foreground mask

Морфология: эрозия, диляция

Morphology dilation

Morphology dilation

Вопрос А как вот такого добиться? Даст ли это dilation/erosion?

Morphology dilation

Вопрос А как вот такого добиться? Даст ли это dilation/erosion?

Morphology dilation

Выводы

  • Не запускал - не работает - если код не запускали, то он скорее-всего работает неверно, а может быть даже не компилируется
  • Не смотрел результат - не работает - если вы не проанализировали результат, а желательно - каждый микрошаг алгоритма - то результат скорее-всего не верен (или, что тоже самое, субоптимален, и можно ЛУЧШЕ, если посмотрев - оптимизировать параметры или убрать баги)
  • Втыкать инварианты - если есть идеи “во, тут верно такое-то правило-инвариант” - фиксируйте его явной проверкой, особенно если на это предположение полагается дальше код. Делите на число? Проверьте перед этим что оно не ноль. Берете первый элемент вектора? Проверьте что он не пустой
  • Быстрота эксперимента - если легко и быстро все работает - больше всякого попробуете (т.к. больше экспериментов успеете), меньше тратите времени на ожидание
  • Визуализации и логи - как способ держать руку на пульсе, увидеть и глубоко прочувствовать что происходит на каждом этапе
  • Поиск рисков и контр-примеров - чтобы получить надежный алгоритм нужно в каждом алгоритме-кирпичике думать “А КАК ЭТО МОЖЕТ НЕ СРАБОТАТЬ? КАК Я МОГУ ЭТО СЛОМАТЬ?” + поиск контр-примеров, в т.ч. синтетических
  • C++ и OpenMP - имба - многопоточность бесплатно всем и пусть никто не уйдет обиженным!

Практика

Задание 1 Обновите свой fork репозиторий, убедитесь что у вас все компилируется, все юнит тесты проходят - запустите All CTest:

Run All CTest

Задание 2 Откройте main.cpp и выполните там все TODO. После выполнения каждого - запускайте программу и проверяйте что очередной этап выдал ожидаемые хорошие результаты (сверяясь с отладочной визуализацией в папке debug/). Вверху main.cpp есть #include попрыгайте по ним через Ctrl+Левый клик мышки, там есть вспомогательные функции.

Доп. Задание 3 Возьмите любой алгоритм и ускорьте его с помощью многопоточности и OpenMP! Какой алгоритм лучше всегоу ускорить? Самый медленный, предположу что это морфология! Прежде чем ускорять - убедитесь что она занимает значимое время (можете искусственно замедлить через больший аргумент strength). Пример промпта:

Дорогой ChatGPT, не передать словами как я рад снова с тобой беседовать
Не мог бы ты мне помочь, дорогой друг?
У меня есть libs/images/CMakeLists.txt + цикл который я хочу ускорить (прилагаю ниже)
Обрати внимание что у меня есть цикл преобразующий картинку
1) добавь замер времени сколько занимает этот цикл
2) сделай переменную bool with_openmp = true;
3) если она выставлена в true - цикл обработки картинки должен выполняться многопоточно с помощью OpenMP
4) и кроме кода я бы хотел узнать что делает каждая строка, и что вообще часто пригождается из OpenMP?
5) и любопытно, а как вычислительные задачки распределяются по ядрам процессора? например какие задачи возьмет на себя первое ядро?
CMakeLitst.txt + код цикла который ниже:
...

Мем

Prompt Engineer VS Sloperator meme

К следующему занятию

Задание 4 Подумайте, может у вас появятся вопросы к коду, что-то стало непонятно, или есть идеи вида: “а почему мы вместо алгоритма А не сделали алгоритм Б? ведь было бы проще/лучше?”

Задание 5 Подумайте, имея идеальную маску делящую пиксели на фон и объект - как нам вычленить каждый из кусочков пазла в отдельную картинку? Например - как банально понять сколько у нас кусочков оказалось?

Задание 6 Подумайте, если бы у вас на картинке был ровно один кусочек пазла, но часть фотографии занимал фон (его маска уже известна) - то как нам получить геометрию контура куска пазла? Как получить четырехугольник? Как найти координаты четырех углов?