Skip to content

Task02 Дмитрий Оводок#157

Closed
dmitrio95 wants to merge 2 commits into
PhotogrammetryCourse:task02from
dmitrio95:task02
Closed

Task02 Дмитрий Оводок#157
dmitrio95 wants to merge 2 commits into
PhotogrammetryCourse:task02from
dmitrio95:task02

Conversation

@dmitrio95

@dmitrio95 dmitrio95 commented Jun 12, 2026

Copy link
Copy Markdown

Добрый день! Выкладываю решение второй задачи (пулл-реквест с первой задачей сделаю чуть позже).

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

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

Во-первых, тест Scale50 упорно не хотел проходить, потому что кластерный фильтр, по мнению теста, давал слишком малую долю хороших точек. Этот эффект проявлялся и с моей реализацией SIFT, и с реализацией из OpenCV. Единственный способ, каким мне удалось удовлетворить этот тест — понизить порог отношения расстояний с рекомендованного в лекциях значения 0.8 до 0.75. При этом на вход фильтру подаются именно расстояния, а не их квадраты — до того, как я учёл в решении тот факт, что knnSearch даёт именно квадраты расстояний, на этапе ratio test падали вообще почти все тесты.

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

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

В финальном решении я оставил 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

Run ./build/test_matching
Running main() from /home/runner/work/PhotogrammetryTasks2026/PhotogrammetryTasks2026/libs/3rdparty/libgtest/googletest/src/gtest_main.cc
[==========] Running 20 tests from 2 test suites.
[----------] Global test environment set-up.
[----------] 18 tests from MATCHING
[ RUN      ] MATCHING.SimpleStitching
testing sift detector/descriptor...
estimateHomographyRANSAC : support: 1002/1002
estimateHomographyRANSAC : best support: 1002/1002
keypoints RMSE: 0.171099, color RMSE: 6.86194
testing my detector/descriptor...
estimateHomographyRANSAC : support: 838/838
estimateHomographyRANSAC : best support: 838/838
keypoints RMSE: 0.133872, color RMSE: 5.69711
[       OK ] MATCHING.SimpleStitching (1439 ms)
[ RUN      ] MATCHING.SimpleMatching
testing sift detector/descriptor...
flann matching...
cv flann matching...
brute force matching
BruteforceMatcher::knnMatch : n query desc : 3919, n train desc : 3522
filtering matches by ratio test...
filtering matches by clusters...
filtering matches by ratio & clusters
estimating homography...
estimateHomographyRANSAC : support: 38/1002
estimateHomographyRANSAC : support: 1002/1002
estimateHomographyRANSAC : best support: 1002/1002
evaluating homography...
nn_score: 0.613167, nn2_score: 0.269712, nn_score_cv: 0.61138, nn2_score_cv: 0.270987, time_my: 0.078259, time_cv: 0.077717, time_bruteforce: 4.64499, good_nn: 0.260015, good_ratio: 0.977799, good_clusters: 0.994975, good_ratio_and_clusters: 0.998004
testing my detector/descriptor...
flann matching...
cv flann matching...
brute force matching
BruteforceMatcher::knnMatch : n query desc : 3481, n train desc : 3119
filtering matches by ratio test...
filtering matches by clusters...
filtering matches by ratio & clusters
estimating homography...
estimateHomographyRANSAC : support: 803/840
estimateHomographyRANSAC : support: 840/840
estimateHomographyRANSAC : best support: 840/840
evaluating homography...
nn_score: 0.600402, nn2_score: 0.262281, nn_score_cv: 0.609308, nn2_score_cv: 0.276932, time_my: 0.068898, time_cv: 0.069293, time_bruteforce: 3.73347, good_nn: 0.246194, good_ratio: 0.969248, good_clusters: 0.991701, good_ratio_and_clusters: 1
[       OK ] MATCHING.SimpleMatching (10239 ms)
[ RUN      ] MATCHING.Rotate10
testing sift detector/descriptor...
flann matching...
cv flann matching...
filtering matches by ratio test...
filtering matches by clusters...
filtering matches by ratio & clusters
estimating homography...
estimateHomographyRANSAC : support: 634/754
estimateHomographyRANSAC : support: 754/754
estimateHomographyRANSAC : best support: 754/754
evaluating homography...
nn_score: 0, nn2_score: 0, nn_score_cv: 0, nn2_score_cv: 0, time_my: 0.102121, time_cv: 0.102289, time_bruteforce: 0, good_nn: 0.174024, good_ratio: 0.850955, good_clusters: 0.865079, good_ratio_and_clusters: 0.880637
testing my detector/descriptor...
flann matching...
cv flann matching...
filtering matches by ratio test...
filtering matches by clusters...
filtering matches by ratio & clusters
estimating homography...
estimateHomographyRANSAC : support: 451/681
estimateHomographyRANSAC : support: 679/681
estimateHomographyRANSAC : support: 680/681
gauss: infinitely many solutions found
gauss: xs0: 660.984, 735.297, 562.182, 562.182, 
gauss: ys0: 569.475, 583.604, 576.766, 576.766, 
estimateHomographyRANSAC : support: 681/681
estimateHomographyRANSAC : best support: 681/681
evaluating homography...
nn_score: 0, nn2_score: 0, nn_score_cv: 0, nn2_score_cv: 0, time_my: 0.094968, time_cv: 0.094462, time_bruteforce: 0, good_nn: 0.189601, good_ratio: 0.899859, good_clusters: 0.953488, good_ratio_and_clusters: 0.926579
[       OK ] MATCHING.Rotate10 (2420 ms)
[ RUN      ] MATCHING.Rotate20
testing sift detector/descriptor...
flann matching...
cv flann matching...
filtering matches by ratio test...
filtering matches by clusters...
filtering matches by ratio & clusters
estimating homography...
estimateHomographyRANSAC : support: 709/765
estimateHomographyRANSAC : support: 765/765
estimateHomographyRANSAC : best support: 765/765
evaluating homography...
nn_score: 0, nn2_score: 0, nn_score_cv: 0, nn2_score_cv: 0, time_my: 0.101254, time_cv: 0.099765, time_bruteforce: 0, good_nn: 0.202348, good_ratio: 0.963975, good_clusters: 0.992593, good_ratio_and_clusters: 0.997386
testing my detector/descriptor...
flann matching...
cv flann matching...
filtering matches by ratio test...
filtering matches by clusters...
filtering matches by ratio & clusters
estimating homography...
estimateHomographyRANSAC : support: 647/691
estimateHomographyRANSAC : support: 691/691
estimateHomographyRANSAC : best support: 691/691
evaluating homography...
nn_score: 0, nn2_score: 0, nn_score_cv: 0, nn2_score_cv: 0, time_my: 0.094627, time_cv: 0.094579, time_bruteforce: 0, good_nn: 0.203677, good_ratio: 0.9369, good_clusters: 0.964557, good_ratio_and_clusters: 0.975398
[       OK ] MATCHING.Rotate20 (2415 ms)
[ RUN      ] MATCHING.Rotate30
testing sift detector/descriptor...
flann matching...
cv flann matching...
filtering matches by ratio test...
filtering matches by clusters...
filtering matches by ratio & clusters
estimating homography...
estimateHomographyRANSAC : support: 696/741
estimateHomographyRANSAC : support: 740/741
gauss: infinitely many solutions found
gauss: xs0: 603.999, 737.154, 737.154, 807.569, 
gauss: ys0: 583.68, 551.574, 551.574, 552.209, 
estimateHomographyRANSAC : support: 741/741
estimateHomographyRANSAC : best support: 741/741
evaluating homography...
nn_score: 0, nn2_score: 0, nn_score_cv: 0, nn2_score_cv: 0, time_my: 0.100486, time_cv: 0.100673, time_bruteforce: 0, good_nn: 0.140342, good_ratio: 0.693798, good_clusters: 0.713896, good_ratio_and_clusters: 0.717949
testing my detector/descriptor...
flann matching...
cv flann matching...
filtering matches by ratio test...
filtering matches by clusters...
filtering matches by ratio & clusters
estimating homography...
gauss: infinitely many solutions found
gauss: xs0: 705.649, 590.38, 590.38, 713.539, 
gauss: ys0: 423.375, 553.942, 553.942, 462.478, 
estimateHomographyRANSAC : support: 647/680
estimateHomographyRANSAC : support: 679/680
estimateHomographyRANSAC : best support: 679/680
evaluating homography...
nn_score: 0, nn2_score: 0, nn_score_cv: 0, nn2_score_cv: 0, time_my: 0.09521, time_cv: 0.094097, time_bruteforce: 0, good_nn: 0.183281, good_ratio: 0.875354, good_clusters: 0.899183, good_ratio_and_clusters: 0.902941
[       OK ] MATCHING.Rotate30 (2413 ms)
[ RUN      ] MATCHING.Rotate40
testing sift detector/descriptor...
flann matching...
cv flann matching...
filtering matches by ratio test...
filtering matches by clusters...
filtering matches by ratio & clusters
estimating homography...
estimateHomographyRANSAC : support: 750/750
estimateHomographyRANSAC : best support: 750/750
evaluating homography...
nn_score: 0, nn2_score: 0, nn_score_cv: 0, nn2_score_cv: 0, time_my: 0.101602, time_cv: 0.101226, time_bruteforce: 0, good_nn: 0.198265, good_ratio: 0.976774, good_clusters: 0.987437, good_ratio_and_clusters: 0.994667
testing my detector/descriptor...
flann matching...
cv flann matching...
filtering matches by ratio test...
filtering matches by clusters...
filtering matches by ratio & clusters
estimating homography...
estimateHomographyRANSAC : support: 216/673
estimateHomographyRANSAC : support: 625/673
estimateHomographyRANSAC : support: 658/673
estimateHomographyRANSAC : support: 666/673
estimateHomographyRANSAC : support: 672/673
estimateHomographyRANSAC : support: 673/673
estimateHomographyRANSAC : best support: 673/673
evaluating homography...
nn_score: 0, nn2_score: 0, nn_score_cv: 0, nn2_score_cv: 0, time_my: 0.09529, time_cv: 0.094357, time_bruteforce: 0, good_nn: 0.205113, good_ratio: 0.975714, good_clusters: 0.994521, good_ratio_and_clusters: 0.998514
[       OK ] MATCHING.Rotate40 (2400 ms)
[ RUN      ] MATCHING.Rotate45
testing sift detector/descriptor...
flann matching...
cv flann matching...
filtering matches by ratio test...
filtering matches by clusters...
filtering matches by ratio & clusters
estimating homography...
estimateHomographyRANSAC : support: 562/754
estimateHomographyRANSAC : support: 701/754
estimateHomographyRANSAC : support: 725/754
estimateHomographyRANSAC : support: 753/754
estimateHomographyRANSAC : support: 754/754
estimateHomographyRANSAC : best support: 754/754
evaluating homography...
nn_score: 0, nn2_score: 0, nn_score_cv: 0, nn2_score_cv: 0, time_my: 0.101339, time_cv: 0.100963, time_bruteforce: 0, good_nn: 0.188058, good_ratio: 0.929847, good_clusters: 0.949296, good_ratio_and_clusters: 0.958886
testing my detector/descriptor...
flann matching...
cv flann matching...
filtering matches by ratio test...
filtering matches by clusters...
filtering matches by ratio & clusters
estimating homography...
estimateHomographyRANSAC : support: 152/684
estimateHomographyRANSAC : support: 354/684
estimateHomographyRANSAC : support: 684/684
estimateHomographyRANSAC : best support: 684/684
evaluating homography...
nn_score: 0, nn2_score: 0, nn_score_cv: 0, nn2_score_cv: 0, time_my: 0.095554, time_cv: 0.095238, time_bruteforce: 0, good_nn: 0.202815, good_ratio: 0.966245, good_clusters: 0.989101, good_ratio_and_clusters: 0.989766
[       OK ] MATCHING.Rotate45 (2401 ms)
[ RUN      ] MATCHING.Rotate90
testing sift detector/descriptor...
flann matching...
cv flann matching...
filtering matches by ratio test...
filtering matches by clusters...
filtering matches by ratio & clusters
estimating homography...
estimateHomographyRANSAC : support: 631/831
estimateHomographyRANSAC : support: 759/831
estimateHomographyRANSAC : support: 830/831
gauss: infinitely many solutions found
gauss: xs0: 639.033, 573.879, 770.51, 639.033, 
gauss: ys0: 543.991, 402.412, 506.596, 543.991, 
gauss: infinitely many solutions found
gauss: xs0: 796.975, 636.036, 796.975, 736.905, 
gauss: ys0: 376.487, 622.896, 376.487, 378.528, 
estimateHomographyRANSAC : best support: 830/831
evaluating homography...
nn_score: 0, nn2_score: 0, nn_score_cv: 0, nn2_score_cv: 0, time_my: 0.091555, time_cv: 0.089323, time_bruteforce: 0, good_nn: 0.217147, good_ratio: 0.977855, good_clusters: 0.990888, good_ratio_and_clusters: 0.99639
testing my detector/descriptor...
flann matching...
cv flann matching...
filtering matches by ratio test...
filtering matches by clusters...
filtering matches by ratio & clusters
estimating homography...
estimateHomographyRANSAC : support: 752/752
estimateHomographyRANSAC : best support: 752/752
evaluating homography...
nn_score: 0, nn2_score: 0, nn_score_cv: 0, nn2_score_cv: 0, time_my: 0.083106, time_cv: 0.083613, time_bruteforce: 0, good_nn: 0.217754, good_ratio: 0.946292, good_clusters: 0.95672, good_ratio_and_clusters: 0.969415
[       OK ] MATCHING.Rotate90 (2241 ms)
[ RUN      ] MATCHING.Scale50
testing sift detector/descriptor...
flann matching...
cv flann matching...
filtering matches by ratio test...
filtering matches by clusters...
filtering matches by ratio & clusters
estimating homography...
estimateHomographyRANSAC : support: 150/165
estimateHomographyRANSAC : support: 161/165
estimateHomographyRANSAC : support: 162/165
estimateHomographyRANSAC : support: 165/165
estimateHomographyRANSAC : best support: 165/165
evaluating homography...
nn_score: 0, nn2_score: 0, nn_score_cv: 0, nn2_score_cv: 0, time_my: 0.049191, time_cv: 0.048425, time_bruteforce: 0, good_nn: 0.0441439, good_ratio: 0.833333, good_clusters: 0, good_ratio_and_clusters: 0.987879
too few matches: 0
testing my detector/descriptor...
flann matching...
cv flann matching...
filtering matches by ratio test...
filtering matches by clusters...
filtering matches by ratio & clusters
estimating homography...
estimateHomographyRANSAC : support: 136/137
gauss: infinitely many solutions found
gauss: xs0: 705.649, 630.44, 610.399, 630.44, 
gauss: ys0: 423.375, 416.798, 487.751, 416.798, 
estimateHomographyRANSAC : support: 137/137
estimateHomographyRANSAC : best support: 137/137
evaluating homography...
too few matches: 0
nn_score: 0, nn2_score: 0, nn_score_cv: 0, nn2_score_cv: 0, time_my: 0.043794, time_cv: 0.043936, time_bruteforce: 0, good_nn: 0.0353347, good_ratio: 0.732919, good_clusters: 0, good_ratio_and_clusters: 0.854015
[       OK ] MATCHING.Scale50 (1247 ms)
[ RUN      ] MATCHING.Scale70
testing sift detector/descriptor...
flann matching...
cv flann matching...
filtering matches by ratio test...
filtering matches by clusters...
filtering matches by ratio & clusters
estimating homography...
too few matches: 34
estimateHomographyRANSAC : support: 167/373
estimateHomographyRANSAC : support: 373/373
estimateHomographyRANSAC : best support: 373/373
evaluating homography...
nn_score: 0, nn2_score: 0, nn_score_cv: 0, nn2_score_cv: 0, time_my: 0.06248, time_cv: 0.062068, time_bruteforce: 0, good_nn: 0.09926, good_ratio: 0.930348, good_clusters: 0, good_ratio_and_clusters: 0.989276
testing my detector/descriptor...
flann matching...
cv flann matching...
filtering matches by ratio test...
filtering matches by clusters...
filtering matches by ratio & clusters
estimating homography...
estimateHomographyRANSAC : support: 14/337
estimateHomographyRANSAC : support: 193/337
estimateHomographyRANSAC : support: 336/337
gauss: infinitely many solutions found
gauss: xs0: 555.457, 724.221, 637.701, 555.457, 
gauss: ys0: 421.601, 382.468, 561.076, 421.601, 
gauss: infinitely many solutions found
gauss: xs0: 576.578, 575.815, 575.815, 603.999, 
gauss: ys0: 507.459, 561.294, 561.294, 583.68, 
gauss: infinitely many solutions found
gauss: xs0: 603.999, 603.999, 653.688, 730.595, 
gauss: ys0: 583.68, 583.68, 545.762, 492.599, 
gauss: infinitely many solutions found
gauss: xs0: 622.456, 684.407, 684.407, 770.686, 
gauss: ys0: 202.353, 488.997, 488.997, 223.038, 
estimateHomographyRANSAC : best support: 336/337
too few matches: 49
evaluating homography...
nn_score: 0, nn2_score: 0, nn_score_cv: 0, nn2_score_cv: 0, time_my: 0.056866, time_cv: 0.057404, time_bruteforce: 0, good_nn: 0.093364, good_ratio: 0.84153, good_clusters: 0, good_ratio_and_clusters: 0.902077
[       OK ] MATCHING.Scale70 (1549 ms)
[ RUN      ] MATCHING.Scale90
testing sift detector/descriptor...
flann matching...
cv flann matching...
filtering matches by ratio test...
filtering matches by clusters...
filtering matches by ratio & clusters
estimating homography...
estimateHomographyRANSAC : support: 26/650
estimateHomographyRANSAC : support: 232/650
estimateHomographyRANSAC : support: 537/650
estimateHomographyRANSAC : support: 593/650
estimateHomographyRANSAC : support: 647/650
estimateHomographyRANSAC : support: 649/650
estimateHomographyRANSAC : support: 650/650
estimateHomographyRANSAC : best support: 650/650
evaluating homography...
nn_score: 0, nn2_score: 0, nn_score_cv: 0, nn2_score_cv: 0, time_my: 0.080588, time_cv: 0.081178, time_bruteforce: 0, good_nn: 0.172238, good_ratio: 0.976119, good_clusters: 0.988281, good_ratio_and_clusters: 0.992308
testing my detector/descriptor...
flann matching...
cv flann matching...
filtering matches by ratio test...
filtering matches by clusters...
filtering matches by ratio & clusters
estimating homography...
estimateHomographyRANSAC : support: 604/605
gauss: infinitely many solutions found
gauss: xs0: 582.193, 555.59, 582.193, 719.967, 
gauss: ys0: 619.854, 535.099, 619.854, 555.557, 
estimateHomographyRANSAC : best support: 604/605
evaluating homography...
nn_score: 0, nn2_score: 0, nn_score_cv: 0, nn2_score_cv: 0, time_my: 0.074983, time_cv: 0.074491, time_bruteforce: 0, good_nn: 0.177822, good_ratio: 0.961965, good_clusters: 0.995745, good_ratio_and_clusters: 0.990083
[       OK ] MATCHING.Scale90 (2075 ms)
[ RUN      ] MATCHING.Scale110
testing sift detector/descriptor...
flann matching...
cv flann matching...
filtering matches by ratio test...
filtering matches by clusters...
filtering matches by ratio & clusters
estimating homography...
estimateHomographyRANSAC : support: 348/785
estimateHomographyRANSAC : support: 391/785
estimateHomographyRANSAC : support: 785/785
estimateHomographyRANSAC : best support: 785/785
evaluating homography...
nn_score: 0, nn2_score: 0, nn_score_cv: 0, nn2_score_cv: 0, time_my: 0.11128, time_cv: 0.111607, time_bruteforce: 0, good_nn: 0.207961, good_ratio: 0.974106, good_clusters: 0.984199, good_ratio_and_clusters: 0.993631
testing my detector/descriptor...
flann matching...
cv flann matching...
filtering matches by ratio test...
filtering matches by clusters...
filtering matches by ratio & clusters
estimating homography...
estimateHomographyRANSAC : support: 526/704
estimateHomographyRANSAC : support: 655/704
estimateHomographyRANSAC : support: 703/704
gauss: infinitely many solutions found
gauss: xs0: 735.604, 645.219, 534.945, 534.945, 
gauss: ys0: 463.88, 612.507, 369.818, 369.818, 
gauss: infinitely many solutions found
gauss: xs0: 624.951, 624.951, 690.97, 734.873, 
gauss: ys0: 524.385, 524.385, 571.809, 467.044, 
estimateHomographyRANSAC : best support: 703/704
evaluating homography...
nn_score: 0, nn2_score: 0, nn_score_cv: 0, nn2_score_cv: 0, time_my: 0.104474, time_cv: 0.104085, time_bruteforce: 0, good_nn: 0.207699, good_ratio: 0.967436, good_clusters: 0.979328, good_ratio_and_clusters: 0.995739
[       OK ] MATCHING.Scale110 (2631 ms)
[ RUN      ] MATCHING.Scale130
testing sift detector/descriptor...
flann matching...
cv flann matching...
filtering matches by ratio test...
filtering matches by clusters...
filtering matches by ratio & clusters
estimating homography...
estimateHomographyRANSAC : support: 271/834
estimateHomographyRANSAC : support: 833/834
gauss: infinitely many solutions found
gauss: xs0: 667.328, 557.585, 539.406, 539.406, 
gauss: ys0: 455.62, 610.723, 516.317, 516.317, 
estimateHomographyRANSAC : best support: 833/834
evaluating homography...
nn_score: 0, nn2_score: 0, nn_score_cv: 0, nn2_score_cv: 0, time_my: 0.155676, time_cv: 0.155084, time_bruteforce: 0, good_nn: 0.192396, good_ratio: 0.850917, good_clusters: 0.890438, good_ratio_and_clusters: 0.881295
testing my detector/descriptor...
flann matching...
cv flann matching...
filtering matches by ratio test...
filtering matches by clusters...
filtering matches by ratio & clusters
estimating homography...
estimateHomographyRANSAC : support: 754/755
estimateHomographyRANSAC : support: 755/755
estimateHomographyRANSAC : best support: 755/755
evaluating homography...
nn_score: 0, nn2_score: 0, nn_score_cv: 0, nn2_score_cv: 0, time_my: 0.149123, time_cv: 0.148794, time_bruteforce: 0, good_nn: 0.216892, good_ratio: 0.940127, good_clusters: 0.966102, good_ratio_and_clusters: 0.966887
[       OK ] MATCHING.Scale130 (3479 ms)
[ RUN      ] MATCHING.Scale150
testing sift detector/descriptor...
flann matching...
cv flann matching...
filtering matches by ratio test...
filtering matches by clusters...
filtering matches by ratio & clusters
estimating homography...
estimateHomographyRANSAC : support: 782/785
estimateHomographyRANSAC : support: 783/785
gauss: infinitely many solutions found
gauss: xs0: 584.592, 661.6, 661.6, 576.876, 
gauss: ys0: 545.5, 586.39, 586.39, 467.845, 
estimateHomographyRANSAC : support: 784/785
gauss: infinitely many solutions found
gauss: xs0: 558.46, 558.46, 656.671, 621.637, 
gauss: ys0: 570.713, 570.713, 593.502, 460.091, 
gauss: infinitely many solutions found
gauss: xs0: 610.814, 779.454, 539.499, 539.499, 
gauss: ys0: 367.149, 525.7, 445.948, 445.948, 
gauss: infinitely many solutions found
gauss: xs0: 576.309, 576.309, 797.753, 676.992, 
gauss: ys0: 607.281, 607.281, 327.982, 546.811, 
estimateHomographyRANSAC : best support: 784/785
evaluating homography...
nn_score: 0, nn2_score: 0, nn_score_cv: 0, nn2_score_cv: 0, time_my: 0.219594, time_cv: 0.215747, time_bruteforce: 0, good_nn: 0.204899, good_ratio: 0.958486, good_clusters: 0.989316, good_ratio_and_clusters: 0.982166
testing my detector/descriptor...
flann matching...
cv flann matching...
filtering matches by ratio test...
filtering matches by clusters...
filtering matches by ratio & clusters
estimating homography...
estimateHomographyRANSAC : support: 437/708
estimateHomographyRANSAC : support: 688/708
estimateHomographyRANSAC : support: 707/708
gauss: infinitely many solutions found
gauss: xs0: 670.71, 547.779, 789.087, 547.779, 
gauss: ys0: 218.019, 448.532, 406.466, 448.532, 
gauss: infinitely many solutions found
gauss: xs0: 637.559, 648.905, 793.048, 637.559, 
gauss: ys0: 607.216, 531.614, 453.38, 607.216, 
gauss: infinitely many solutions found
gauss: xs0: 671.039, 640.568, 562.163, 640.568, 
gauss: ys0: 622.54, 575.939, 374.909, 575.939, 
estimateHomographyRANSAC : best support: 707/708
evaluating homography...
nn_score: 0, nn2_score: 0, nn_score_cv: 0, nn2_score_cv: 0, time_my: 0.214999, time_cv: 0.212872, time_bruteforce: 0, good_nn: 0.205113, good_ratio: 0.960383, good_clusters: 0.985714, good_ratio_and_clusters: 0.987288
[       OK ] MATCHING.Scale150 (4641 ms)
[ RUN      ] MATCHING.Scale175
testing sift detector/descriptor...
flann matching...
cv flann matching...
filtering matches by ratio test...
filtering matches by clusters...
filtering matches by ratio & clusters
estimating homography...
estimateHomographyRANSAC : support: 414/769
estimateHomographyRANSAC : support: 762/769
estimateHomographyRANSAC : support: 766/769
estimateHomographyRANSAC : support: 767/769
estimateHomographyRANSAC : support: 768/769
estimateHomographyRANSAC : best support: 768/769
evaluating homography...
nn_score: 0, nn2_score: 0, nn_score_cv: 0, nn2_score_cv: 0, time_my: 0.293974, time_cv: 0.288716, time_bruteforce: 0, good_nn: 0.19903, good_ratio: 0.951189, good_clusters: 0.97807, good_ratio_and_clusters: 0.973992
testing my detector/descriptor...
flann matching...
cv flann matching...
filtering matches by ratio test...
filtering matches by clusters...
filtering matches by ratio & clusters
estimating homography...
estimateHomographyRANSAC : support: 665/666
estimateHomographyRANSAC : support: 666/666
estimateHomographyRANSAC : best support: 666/666
evaluating homography...
nn_score: 0, nn2_score: 0, nn_score_cv: 0, nn2_score_cv: 0, time_my: 0.280195, time_cv: 0.289578, time_bruteforce: 0, good_nn: 0.194484, good_ratio: 0.953824, good_clusters: 0.969466, good_ratio_and_clusters: 0.972973
[       OK ] MATCHING.Scale175 (6116 ms)
[ RUN      ] MATCHING.Scale200
testing sift detector/descriptor...
flann matching...
cv flann matching...
filtering matches by ratio test...
filtering matches by clusters...
filtering matches by ratio & clusters
estimating homography...
estimateHomographyRANSAC : support: 848/852
estimateHomographyRANSAC : support: 850/852
estimateHomographyRANSAC : support: 851/852
gauss: infinitely many solutions found
gauss: xs0: 735.604, 623.24, 562.105, 562.105, 
gauss: ys0: 463.88, 494.132, 552.712, 552.712, 
gauss: infinitely many solutions found
gauss: xs0: 578.574, 586.909, 586.909, 566.074, 
gauss: ys0: 471.335, 516.331, 516.331, 525.051, 
estimateHomographyRANSAC : best support: 851/852
evaluating homography...
nn_score: 0, nn2_score: 0, nn_score_cv: 0, nn2_score_cv: 0, time_my: 0.316323, time_cv: 0.320701, time_bruteforce: 0, good_nn: 0.207196, good_ratio: 0.909091, good_clusters: 0.926335, good_ratio_and_clusters: 0.929577
testing my detector/descriptor...
flann matching...
cv flann matching...
filtering matches by ratio test...
filtering matches by clusters...
filtering matches by ratio & clusters
estimating homography...
estimateHomographyRANSAC : support: 271/775
estimateHomographyRANSAC : support: 617/775
estimateHomographyRANSAC : support: 758/775
estimateHomographyRANSAC : support: 774/775
estimateHomographyRANSAC : support: 775/775
estimateHomographyRANSAC : best support: 775/775
evaluating homography...
nn_score: 0, nn2_score: 0, nn_score_cv: 0, nn2_score_cv: 0, time_my: 0.314908, time_cv: 0.313419, time_bruteforce: 0, good_nn: 0.231255, good_ratio: 0.980075, good_clusters: 0.996055, good_ratio_and_clusters: 0.996129
[       OK ] MATCHING.Scale200 (7072 ms)
[ RUN      ] MATCHING.Rotate10Scale90
testing sift detector/descriptor...
flann matching...
cv flann matching...
filtering matches by ratio test...
filtering matches by clusters...
filtering matches by ratio & clusters
estimating homography...
estimateHomographyRANSAC : support: 5/643
estimateHomographyRANSAC : support: 27/643
estimateHomographyRANSAC : support: 377/643
estimateHomographyRANSAC : support: 643/643
estimateHomographyRANSAC : best support: 643/643
evaluating homography...
nn_score: 0, nn2_score: 0, nn_score_cv: 0, nn2_score_cv: 0, time_my: 0.089859, time_cv: 0.090097, time_bruteforce: 0, good_nn: 0.172493, good_ratio: 0.965569, good_clusters: 0.964143, good_ratio_and_clusters: 0.987558
testing my detector/descriptor...
flann matching...
cv flann matching...
filtering matches by ratio test...
filtering matches by clusters...
filtering matches by ratio & clusters
estimating homography...
estimateHomographyRANSAC : support: 56/582
estimateHomographyRANSAC : support: 505/582
estimateHomographyRANSAC : support: 582/582
estimateHomographyRANSAC : best support: 582/582
evaluating homography...
nn_score: 0, nn2_score: 0, nn_score_cv: 0, nn2_score_cv: 0, time_my: 0.083427, time_cv: 0.083845, time_bruteforce: 0, good_nn: 0.166044, good_ratio: 0.925743, good_clusters: 0.945312, good_ratio_and_clusters: 0.946735
[       OK ] MATCHING.Rotate10Scale90 (2189 ms)
[ RUN      ] MATCHING.Rotate30Scale75
testing sift detector/descriptor...
flann matching...
cv flann matching...
filtering matches by ratio test...
filtering matches by clusters...
filtering matches by ratio & clusters
estimating homography...
estimateHomographyRANSAC : support: 273/437
estimateHomographyRANSAC : support: 435/437
gauss: infinitely many solutions found
gauss: xs0: 665.185, 604.092, 665.185, 769.215, 
gauss: ys0: 377.14, 505.279, 377.14, 453.762, 
estimateHomographyRANSAC : best support: 435/437
evaluating homography...
nn_score: 0, nn2_score: 0, nn_score_cv: 0, nn2_score_cv: 0, time_my: 0.073471, time_cv: 0.07326, time_bruteforce: 0, good_nn: 0.117122, good_ratio: 0.960265, good_clusters: 0.966292, good_ratio_and_clusters: 0.990847
testing my detector/descriptor...
flann matching...
cv flann matching...
filtering matches by ratio test...
filtering matches by clusters...
filtering matches by ratio & clusters
estimating homography...
estimateHomographyRANSAC : support: 124/392
estimateHomographyRANSAC : support: 269/392
estimateHomographyRANSAC : support: 390/392
gauss: infinitely many solutions found
gauss: xs0: 558.583, 578.575, 558.583, 643.974, 
gauss: ys0: 565.697, 471.335, 565.697, 230.608, 
gauss: infinitely many solutions found
gauss: xs0: 642.049, 623.306, 623.306, 630.44, 
gauss: ys0: 538.547, 562.213, 562.213, 416.798, 
estimateHomographyRANSAC : best support: 390/392
evaluating homography...
nn_score: 0, nn2_score: 0, nn_score_cv: 0, nn2_score_cv: 0, time_my: 0.067299, time_cv: 0.067238, time_bruteforce: 0, good_nn: 0.112899, good_ratio: 0.884892, good_clusters: 0.898734, good_ratio_and_clusters: 0.938776
[       OK ] MATCHING.Rotate30Scale75 (1742 ms)
[----------] 18 tests from MATCHING (58710 ms total)

[----------] 2 tests from STITCHING
[ RUN      ] STITCHING.SimplePanorama
estimateHomographyRANSAC : support: 1002/1005
estimateHomographyRANSAC : support: 1003/1005
gauss: infinitely many solutions found
gauss: xs0: 100.569, 218.72, 218.72, 98.0472, 
gauss: ys0: 468.024, 478.491, 478.491, 384.304, 
estimateHomographyRANSAC : best support: 1003/1005
bbox: [1285.57, 642.106], [0, -2.74005]
[       OK ] STITCHING.SimplePanorama (328 ms)
[ RUN      ] STITCHING.Orthophoto
estimateHomographyRANSAC : support: 100/1044
estimateHomographyRANSAC : support: 381/1044
estimateHomographyRANSAC : support: 391/1044
estimateHomographyRANSAC : support: 407/1044
estimateHomographyRANSAC : support: 450/1044
estimateHomographyRANSAC : support: 466/1044
estimateHomographyRANSAC : support: 543/1044
estimateHomographyRANSAC : best support: 543/1044
estimateHomographyRANSAC : support: 122/1366
estimateHomographyRANSAC : support: 506/1366
estimateHomographyRANSAC : support: 537/1366
estimateHomographyRANSAC : support: 602/1366
estimateHomographyRANSAC : support: 625/1366
gauss: infinitely many solutions found
gauss: xs0: 426.013, 426.013, 226.755, 749.133, 
gauss: ys0: 137.841, 137.841, 414.685, 98.8764, 
estimateHomographyRANSAC : best support: 625/1366
estimateHomographyRANSAC : support: 180/2081
estimateHomographyRANSAC : support: 194/2081
estimateHomographyRANSAC : support: 309/2081
estimateHomographyRANSAC : support: 455/2081
estimateHomographyRANSAC : support: 468/2081
estimateHomographyRANSAC : support: 541/2081
estimateHomographyRANSAC : support: 688/2081
estimateHomographyRANSAC : support: 697/2081
estimateHomographyRANSAC : support: 720/2081
estimateHomographyRANSAC : best support: 720/2081
gauss: infinitely many solutions found
estimateHomographyRANSAC : support: 16/1233
estimateHomographyRANSAC : support: 38/1233
estimateHomographyRANSAC : support: 368/1233
estimateHomographyRANSAC : support: 421/1233
estimateHomographyRANSAC : support: 451/1233
gauss: xs0: 777.313, 921.064, 921.064, 867.533, 
gauss: ys0: 779.655, 440.993, 440.993, 716.449, 
estimateHomographyRANSAC : support: 469/1233
estimateHomographyRANSAC : support: 502/1233
estimateHomographyRANSAC : support: 598/1233
gauss: infinitely many solutions found
gauss: xs0: 751.151, 592.381, 592.381, 796.048, 
gauss: ys0: 430.568, 833.511, 833.511, 432.47, 
estimateHomographyRANSAC : best support: 598/1233
bbox: [1294.39, 1687.39], [-188.666, -349.189]
estimateHomographyRANSAC : support: 107/1051
estimateHomographyRANSAC : support: 181/1051
estimateHomographyRANSAC : support: 184/1051
estimateHomographyRANSAC : support: 215/1051
estimateHomographyRANSAC : support: 375/1051
estimateHomographyRANSAC : support: 446/1051
estimateHomographyRANSAC : support: 457/1051
estimateHomographyRANSAC : support: 573/1051
estimateHomographyRANSAC : best support: 573/1051
estimateHomographyRANSAC : support: 32/1372
estimateHomographyRANSAC : support: 557/1372
estimateHomographyRANSAC : support: 607/1372
gauss: infinitely many solutions found
gauss: xs0: 244.254, 314.101, 314.101, 931.88, 
gauss: ys0: 398.247, 794.539, 794.539, 330.934, 
estimateHomographyRANSAC : support: 656/1372
estimateHomographyRANSAC : best support: 656/1372
estimateHomographyRANSAC : support: 282/2086
estimateHomographyRANSAC : support: 301/2086
estimateHomographyRANSAC : support: 415/2086
estimateHomographyRANSAC : support: 431/2086
estimateHomographyRANSAC : support: 442/2086
estimateHomographyRANSAC : support: 530/2086
estimateHomographyRANSAC : support: 603/2086
estimateHomographyRANSAC : support: 605/2086
estimateHomographyRANSAC : support: 751/2086
gauss: infinitely many solutions found
gauss: xs0: 911.075, 1046.35, 911.075, 311.738, 
gauss: ys0: 425.606, 819.181, 425.606, 673.84, 
estimateHomographyRANSAC : best support: 751/2086
estimateHomographyRANSAC : support: 418/1252
estimateHomographyRANSAC : support: 512/1252
estimateHomographyRANSAC : support: 595/1252
estimateHomographyRANSAC : support: 631/1252
estimateHomographyRANSAC : best support: 631/1252
bbox: [1227.45, 864], [-233.712, -969.221]
n stable ortho kpts: : 21497
[       OK ] STITCHING.Orthophoto (12981 ms)
[----------] 2 tests from STITCHING (13309 ms total)

[----------] Global test environment tear-down
[==========] 20 tests from 2 test suites ran. (72019 ms total)
[  PASSED  ] 20 tests.

@simiyutin

Copy link
Copy Markdown
Contributor

Это увеличивает вероятность того, что данная корректная точка кластерный тест не пройдёт.

А какая ситуация в случае если есть повторяющиеся текстуры? (Одинаковые кирпичи или если развесить на стене ксерокопии одной и той же картинки)

то для корректности матрицы действительно лучше действовать не так, а поделить все остальные элементы матрицы на значение H33

Здесь не совсем удачная формулировка задания, подразумевалось именно деление матрицы на Н33 при составлении системы. В каком случае это проблема, чему соответствует этот случай, и как решить систему уравнений в этом случае?

Можно, вероятно, оптимизировать этот метод и оценивать совпадения не между всеми парами (например, принимать пару в цепочку сразу по достижении какого-то порога количества сопоставлений), но идея примерно такая.

Цепочка изображений, связанная сопоставлениями, образует граф. Как выбрать вершину?

@dmitrio95

Copy link
Copy Markdown
Author

А какая ситуация в случае если есть повторяющиеся текстуры? (Одинаковые кирпичи или если развесить на стене ксерокопии одной и той же картинки)

При повторяющихся текстурах, кажется, будет особенно полезно сначала применить ratio test. В этом случае будет много ключевых точек с примерно одинаковыми дескрипторами, которые не очень понятно, как друг с другом соотносить. Ratio test такие точки уберёт, и сопоставление будет дальше работать по каким-то более уникальным и выделяющимся на общем фоне точкам. А вот если эти все точки передать в кластерный фильтр без предварительной фильтрации, то ситуация, скорее всего, будет примерно аналогичной случаю с большим количеством ошибочных точек: в окрестности каждой хорошей точки будет много точек, которые будут сопоставлены случайным частям повторяющейся текстуры, и кластерный фильтр не сможет надёжно их отобрать.

Здесь не совсем удачная формулировка задания, подразумевалось именно деление матрицы на Н33 при составлении системы. В каком случае это проблема, чему соответствует этот случай, и как решить систему уравнений в этом случае?

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

Цепочка изображений, связанная сопоставлениями, образует граф. Как выбрать вершину?

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

// но при более низком количестве попыток был зафиксирован и результат,
// лишь немного превышающий 0.3 (638/2070). Поэтому с запасом можно
// оставить 800 попыток, если это не будет вредить производительности
// (а на тестах проблем с этим пока не заметно).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔥

@simiyutin

Copy link
Copy Markdown
Contributor

запустить несколько итераций кластерного фильтра

хорошее наблюдение)

@simiyutin

Copy link
Copy Markdown
Contributor

А возникнуть такая ситуация, похоже, может только когда в задаче возникает уже третье измерение

Ну в общем-то гомография становится гомографией только когда она описывает 3Д геометрию, иначе это просто афинная матрица)

@simiyutin simiyutin closed this Jun 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants