Skip to content

Commit

Permalink
Merge branch 'task01' into task02
Browse files Browse the repository at this point in the history
  • Loading branch information
metametamoon committed Feb 28, 2024
2 parents 8295def + b49f3db commit 325df3a
Show file tree
Hide file tree
Showing 13 changed files with 2,605 additions and 150 deletions.
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
cmake_minimum_required(VERSION 3.1)
cmake_minimum_required(VERSION 3.6)

add_subdirectory(libs)

project(Photogrammetry)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD 20)

# OpenMP позволит распараллеливать циклы на все ядра процессора простыми директивами
find_package(OpenMP)
Expand Down
78 changes: 78 additions & 0 deletions answers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// Убедитесь что название PR соответствует шаблону:
// Task01 <Имя> <Фамилия> <ВУЗ>

// Проверьте что обе ветки PR - task01 (отправляемая из вашего форкнутого репозитория и та в которую вы отправляете PR)

# Перечислите идеи и коротко обозначьте мысли которые у вас возникали по мере выполнения задания, в частности попробуйте ответить на вопросы:

0) Никакой фиттинг параболой (ни по углам, ни по координатам экстремума) не дал значимых улучшений -- где-то получалось лучше, где-то хуже.

1) Почему SIFT менее точно угадывает средний угол отклонения? изменяется ли ситуация если выкрутить параметр ORIENTATION_VOTES_PEAK_RATIO=0.999? почему?
> Это связано с тем, что угол определяется по направлению оценненных градиентов на решетке. При повороте эта решетка переходит не в точности в нужные точки, а в точки, округленные до границ пикселей, в которых в свою очередь градиент считается иначе (так как оценка градиента по конечным разностям не робастна -- на самом деле растояние в один пиксель совсем не маленькое).
> Было бы здравой идеей считать градиент не как градиент пикселя, в который мы попали, а в как результаты билинейной интерполяции по оценка градиентов в пикселях (мы делаем естественное 😁 предположение, что градиент картинки дифференцируем) - так можно было бы в некоторой степени нивелировать то, что повернутая решетка, по которой мы берем градиенты, почти никогда не попадает ровно в центр пикселей.
> Результаты теста некорректны -- при наличии нескольких часто встречающихся направлений мы создадим несколько ключевых точек с разными углами, а в тестах точки матчатся по местоположению. В худшем случае мы будем матчить не точки в одних местах, но с разными углами - они будут портить и разность углов, и расстояние дескрипторов. Эта проблема убирается при выкручивании `ORIENTATION_VOTES_PEAK_RATIO` в почти 1, поэтому результаты ощутимо лучше (см. `log-votes-peak-99pc.txt`). Но хороших выводов из теста самого сделать нельзя, потому что он плохо считает точность для метода с выбором нескольких самых частых направлений.
2) Как надежно замерить во сколько раз распараллеливание через OpenMP ускоряет ваш вариант SIFT? Попробуйте сделать это на вашем компьютере, какое ускорение относительно однопоточной версии оказалось? Сколько у вашего процессора ядер и сколько потоков?
> У моего процессора 6 ядер и 12 логических ядер. Чтобы сделать оценку, я запустил все тесты с включенным и выключенным omp соответственно, оба лога сохранил в реп (`log-with-omp.txt`, `log-no-omp.txt`). При сравнении файлов видно, что наличие распоточивание сокращает время работы примерно в полтора раза в среднем. В идеале надо бы составить табличку и в ней вычислить все времена работы, но очень сложно. Ускорение получается очень маленьким, потому что сам алгоритм очень быстрый - вычисление пирамид занимает в среднем 2 миллисекунды, синхронизация занимает относительно много времени по сравнению с основной работой алгоритма. Видны также выбросы, где omp очень долго работает -- вероятно, это точки спауна потоков.

3) Правда ли можно строить каждый слой в Gaussian пирамиде из самого первого слоя этой октавы? Или нужно обязательно делать так как предложено в статье - дополняя размытие предыдущего слоя этой октавы? Совпадают ли пирамиды визуально?
> Оба подхода приводят к одинаковому размытию, ибо пользуются одним и тем же свойством сверток с ядром гаусса. Визуально они выглядят одинаково (за выбор способа отвечает макрос `SEQUENTIAL` в коде)
4) Какие ожидания от картинок в Gaussian пирамиде можно придумать? Как проверить что работает корректно? С какой другой картинкой предыдущей октавы должна визуально совпадать конкретная картинка конкретной октавы? Как их визуально сравнить, ведь они разного размера?

> При построении пирамиды мы создаем октавы с нахлестом на следующую октаву (по модулю изменения картинки в два раза). Тогда можно сравнивать соответствующие (т.е. с равным радиусом размытия) крайние пирамиды с границ октав.
> Есть соблазн сделать такое, но он не соответствует теоретической основе статьи [lowe 4] -- в отличие от того алгоритма, мы инициализируем новую октаву усреднением блоков 2x2 на картинке, а не прорежением второй с конца матрицы предыдущей октавы (соответствующей размытию радиусом 2 sigma, где sigma -- размытие начала октавы), поэтому соответствующие уровни детализации являются несовместимы и на самом деле не соответствуют одному и тому же уровню размытия.


5) Почему в октаве Gaussian пирамиды s+3 картинки, а не s+2 например?

> Покажем, что s+3 слоя хватит в упор.
Рассмотрим n-ую октаву. После построения s+3 слоев, мы получим свертки с разностями гауссинов:
> - n 1/s - n 0/s
> - n 2/s - n 1/s !!
> - ...
> - n s/s - n (s-1)/s !!
> - n (s+1)/s - n s/s !!
> - n (s+2)/s - n (s+1)/s
>
> Причем мы экстремумы можем искать только не на граничных слоях (отмечены !!). Итого мы такой октавой покрываем экстремумы от [n 2/s - n 1/s] до [n+1 2/s - n+1 1/s] не включительно. То есть такими полуинтервалами мы покроем все промежуточные слои пирамиды разниц. Тогда s+2 слоев не хватило бы.
6) Какие ожидания от картинок в DoG пирамиде можно придумать?
> Они должны быть черненькие :) Потому что коэффициенты в разности соседних ядер гауссианов маленькие, и свертка с разностью будет преимущественно маленькой.
7) Почему порог контрастности должен уменьшаться при увеличении числа слоев в октаве?
> Потому что мы берем разницу более близких гауссианов.
8) Какая строка ответственна за определение сигмы (или что почти то же самое - радиуса), которая задает окрестность, по которой определяется ориентация ключевой точки?

> За это отвечает правая часть инициализации `sigmaCur`, вычисляющая радиус размытия по номеру слоя и октаве. При маштабировании изменится только уровень, на котором мы обнаружим ту же самую ключевую точку --- он изменится так, что отношение радиусов размытия уровней, на которых эта же ключевая точка распознана на разных картинках, равна отношению их масштабов. (иными словами, при масштабировании картинки разность гауссианов соответствующих масштабов будет иметь экстремум, соответствующий экстремуму свертки меньшей разницы гауссианов и меньшей картинки, в частности, той же самой точки картинки).



9) За какой строки вашего кода дескриптор инвариантен к повороту картинки?
> Из-за поворота решетки, по которой мы рассматриваем градиенты картинки, на угол точки внутри функции `buildDescriptor`.
// Создайте PR.
// Дождитесь отработки Github Actions CI, после чего нажмите на зеленую галочку -> Details -> test_sift -> скопируйте весь лог тестирования.
// Откройте PR на редактирование (сверху справа три точки->Edit) и добавьте сюда скопированный лог тестирования внутри тега <pre> для сохранения форматирования и под спойлером для компактности и удобства:

<details><summary>Github Actions CI</summary><p>

<pre>
$ ./build/test_sift
Running main() from /home/runner/work/PhotogrammetryTasks2023/PhotogrammetryTasks2023/libs/3rdparty/libgtest/googletest/src/gtest_main.cc
[==========] Running 22 tests from 1 test suite.
[----------] Global test environment set-up.
[----------] 22 tests from SIFT
[ RUN ] SIFT.MovedTheSameImage
[ORB_OCV] Points detected: 500 -> 500 (in 0.021269 sec)
...
[ OK ] SIFT.HerzJesu19RotateM40 (7730 ms)
[----------] 22 tests from SIFT (12918 ms total)
[----------] Global test environment tear-down
[==========] 22 tests from 1 test suite ran. (12918 ms total)
[ PASSED ] 22 tests.
</pre>

</p></details>
4 changes: 0 additions & 4 deletions data/debug/test_sift/debug/pyramid/.gitignore

This file was deleted.

4 changes: 0 additions & 4 deletions data/debug/test_sift/debug/pyramidDoG/.gitignore

This file was deleted.

Loading

0 comments on commit 325df3a

Please sign in to comment.