Task02 Дмитрий Оводок#157
Conversation
А какая ситуация в случае если есть повторяющиеся текстуры? (Одинаковые кирпичи или если развесить на стене ксерокопии одной и той же картинки)
Здесь не совсем удачная формулировка задания, подразумевалось именно деление матрицы на Н33 при составлении системы. В каком случае это проблема, чему соответствует этот случай, и как решить систему уравнений в этом случае?
Цепочка изображений, связанная сопоставлениями, образует граф. Как выбрать вершину? |
При повторяющихся текстурах, кажется, будет особенно полезно сначала применить ratio test. В этом случае будет много ключевых точек с примерно одинаковыми дескрипторами, которые не очень понятно, как друг с другом соотносить. Ratio test такие точки уберёт, и сопоставление будет дальше работать по каким-то более уникальным и выделяющимся на общем фоне точкам. А вот если эти все точки передать в кластерный фильтр без предварительной фильтрации, то ситуация, скорее всего, будет примерно аналогичной случаю с большим количеством ошибочных точек: в окрестности каждой хорошей точки будет много точек, которые будут сопоставлены случайным частям повторяющейся текстуры, и кластерный фильтр не сможет надёжно их отобрать.
Видимо, тогда я не совсем правильно сначала понял вопрос — эта ситуация в задании не рассматривалась. Если я правильно понимаю, то проблема тут может возникнуть только если H33 равен нулю (или как-то особенно близок к нему). А возникнуть такая ситуация, похоже, может только когда в задаче возникает уже третье измерение — либо фотографии сделаны из почти перпендикулярных ракурсов или под каким-то заметным углом друг к другу, либо, как в примере с рельсами из лекции, когда мы такой перпендикулярный ракурс хотим построить, а на исходной фотографии есть очень удалённые объекты. В лекции упоминается, что решить такую систему можно с помощью SVD, через разложение искомой матрицы в произведение двух ортогональных и диагональной.
В целом, при любом выборе корневой картинки должен получиться какой-то разумный результат. Но для наилучшего результата, думаю, лучше выбрать корень где-то посередине нужной нам панорамы, чтобы избежать упомянутой в другом моём ответе проблемы с потенциально накапливающейся погрешностью координат на дальних фотографиях. В качестве критерия "срединности" можно использовать либо глубину получившегося графа, либо расстояние до самой удалённой точки панорамы (его, правда, будет посчитать чуть сложнее). Возможно, могут быть нюансы, если некоторые фотографии сделаны в разных масштабах или под другими углами (и с другим перспективным искажением), но, кажется, это всё будет лучше исправлять корректировкой итоговых матриц гомографии, а не выбором корневой картинки. |
| // но при более низком количестве попыток был зафиксирован и результат, | ||
| // лишь немного превышающий 0.3 (638/2070). Поэтому с запасом можно | ||
| // оставить 800 попыток, если это не будет вредить производительности | ||
| // (а на тестах проблем с этим пока не заметно). |
хорошее наблюдение) |
Ну в общем-то гомография становится гомографией только когда она описывает 3Д геометрию, иначе это просто афинная матрица) |
Добрый день! Выкладываю решение второй задачи (пулл-реквест с первой задачей сделаю чуть позже).
Перечислите идеи и коротко обозначьте мысли которые у вас возникали по мере выполнения задания, в частности попробуйте ответить на вопросы:
В первую очередь, хотелось бы отметить две части моего решения, которые, вероятно, отличаются от предлагаемого в лекциях.
Во-первых, тест Scale50 упорно не хотел проходить, потому что кластерный фильтр, по мнению теста, давал слишком малую долю хороших точек. Этот эффект проявлялся и с моей реализацией SIFT, и с реализацией из OpenCV. Единственный способ, каким мне удалось удовлетворить этот тест — понизить порог отношения расстояний с рекомендованного в лекциях значения 0.8 до 0.75. При этом на вход фильтру подаются именно расстояния, а не их квадраты — до того, как я учёл в решении тот факт, что
knnSearchдаёт именно квадраты расстояний, на этапе ratio test падали вообще почти все тесты.Во-вторых, после включения моей реализации SIFT перестал проходить тест

SimpleStitching, и решил я эту проблему, видимо, тоже не совсем как полагалось. Если взглянуть на результат применения кластерного фильтра в этом случае, видно, что, помимо явно корректных больших кластеров сопоставлений, есть один явно некорректный кластер из трёх сопоставлений (третье на картинке плохо прорисовано, но оно есть):Судя по всему, эти три точки прошли фильтрацию из-за того, что в их окрестности были другие точки, некоторые из которых имели попадающую в окрестность пару на второй картинке, но сами кластерный тест не прошли. Очевидный способ решить эту проблему — запустить несколько итераций кластерного фильтра. Точки из хороших кластеров от этого никак не пострадают, а такие ложные кластеры начнут от повторных итераций рассыпаться. В данном случае трёх итераций вполне достаточно для устранения плохого кластера:

В финальном решении я оставил 3 итерации кластерного фильтра (хотя число итераций вполне можно и вычислять автоматически, прекращая фильтрацию, когда число сопоставлений перестаёт уменьшаться от применения фильтра). Возможно, в каких-то других случаях такое решение сильно уменьшит число сопоставлений, но на случаях из теста такой вариант, кажется, работает неплохо.
1) Зачем фильтровать матчи, если потом мы запускаем устойчивый к выбросам RANSAC и отфильтровываем шумные сопоставления?
Слишком большая доля ошибочных сопоставлений приведёт к тому, что для корректного результата потребуется запускать слишком много итераций RANSAC. Поэтому имеет смысл уменьшить долю ошибок до каких-то разумных значений.
2) Cluster filtering довольно хорошо работает и без Ratio test. Однако, если оставить только Cluster filtering, некоторые тесты начнут падать. Почему так происходит? В каких случаях наоборот, не хватает Ratio test и необходима дополнительная фильтрация?
Судя по всему, кластерный фильтр может плохо работать при слишком большом количестве ошибочных сопоставлений. Тогда в окрестности каждой корректно сопоставленной точки будет находиться большое количество ошибочных точек, и доля других корректных точек будет низкой. Это увеличивает вероятность того, что данная корректная точка кластерный тест не пройдёт.
3) С какой проблемой можно столкнуться при приравнивании единице элемента H33 матрицы гомографии? Как ее решить?
Если имеется в виду приравнивание H33 единице в произвольной матрице гомографии, не обязательно полученной реализованным в задании методом, то для корректности матрицы действительно лучше действовать не так, а поделить все остальные элементы матрицы на значение H33. В противном случае результат действия матрицы изменится. По крайней мере, именно такой эффект я наблюдал при отладке склеивания панорамы (в конечном итоге, правда, проблема была в отсутствии копирования матрицы перед её модификацией, и H33 оказалось возможным просто оставить как есть).
4) Какой подвох таится в попытке склеивать большие панорамы и ортофото методом, реализованным в данной домашке? (Для интуиции можно посмотреть на результат склейки, когда за корень взята какая-нибудь другая картинка)
Реализованный здесь метод подразумевает построение матрицы гомографии, переводящей координаты любой, даже очень удалённой от корня, фотографии в координаты корневой фотографии. Поскольку матрица строится через цепочку фотографий, даже малые ошибки в оценке матрицы гомографии между кадрами этой цепочки могут приводить к большой погрешности матрицы гомографии для дальних фотографий. В результате дальние фотографии могут оказаться, например, сильно смещены, даже если конкретно для этой фотографии матрицы гомографий с её соседями оценены довольно точно.
5) Как можно автоматически построить граф для построения панорамы, чтобы на вход метод принимал только список картинок?
По-видимому, нужно попытаться оценить количество (и качество) совпадений между всеми парами фотографий. Цепочку фотографий затем можно построить по наиболее совпадающим парам фотографий. Можно, вероятно, оптимизировать этот метод и оценивать совпадения не между всеми парами (например, принимать пару в цепочку сразу по достижении какого-то порога количества сопоставлений), но идея примерно такая.
6) Если с вашей реализацией SIFT пройти тесты не получилось, напишите (если пробовали дебажить), где, как вам кажется, проблема и как вы пробовали ее решать.
Получилось, но путём применения кластерного фильтра в несколько итераций — более подробно описал это выше.
7) Если есть, фидбек по заданию: какая часть больше всего понравилась, где-то слишком сложно/просто (что именно), где-то слишком мало ссылок и тд.
Вряд ли я вхожу в целевую аудиторию курса :)
Github Actions CI