Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
a56074e
opencl matching can be slower on server
simiyutin Mar 10, 2026
9d8dda1
Update README for bonus points criteria
simiyutin Mar 11, 2026
ffe7a47
mvp
VashchilkoAV Feb 27, 2026
02077e3
tmp
VashchilkoAV Mar 21, 2026
917e08b
stitching 1st attempt
VashchilkoAV Mar 22, 2026
e31c21d
accelerated
VashchilkoAV Mar 24, 2026
f20034c
make sense for n_points and n_trials
VashchilkoAV Mar 25, 2026
dee35b4
answers + removed debug prints
VashchilkoAV Mar 25, 2026
b70f822
Merge branch 'task02' into task03
VashchilkoAV Mar 26, 2026
a01f213
task3 mvp
VashchilkoAV Mar 29, 2026
e8b66c1
more trials resection
VashchilkoAV Mar 29, 2026
1c00ce6
fix for depth test
VashchilkoAV Mar 29, 2026
b71fc8f
task3: probabilities in order to get 100000 n_trials + answers
VashchilkoAV Mar 29, 2026
63b9613
task03: changed behavior for ensureSpectralProperty -- now it is maki…
VashchilkoAV Apr 1, 2026
58419fa
task03: fixed fmatrix2ematrix camera order, made epipolarTest more co…
VashchilkoAV Apr 1, 2026
3fb7d63
task03: rms eps removed?
VashchilkoAV Apr 1, 2026
8ce5e85
CI: run patch match depth maps binary on windows
PolarNick239 Apr 6, 2026
e22cf73
Merge remote-tracking branch 'origin/task03' into task04
VashchilkoAV Apr 21, 2026
f50c5a3
task04 -- initial
VashchilkoAV Apr 23, 2026
746a4a5
gitignores
VashchilkoAV Apr 24, 2026
8818047
Merge branch 'task04' into task05
VashchilkoAV Apr 24, 2026
065906f
baseline
VashchilkoAV Apr 27, 2026
c0d33d2
fixed calibration
VashchilkoAV Apr 27, 2026
b14af3b
fixed costAvg
VashchilkoAV Apr 28, 2026
38dd832
ACMH
VashchilkoAV Apr 28, 2026
c3cef19
refactored propagation + implemented bilinear interpolation in estima…
VashchilkoAV May 1, 2026
8a106b4
uncertanty + big cost filtering
VashchilkoAV May 2, 2026
6a91cf3
self-cost evaluation
VashchilkoAV May 3, 2026
9d47648
some photos
VashchilkoAV May 4, 2026
54f16b0
photos2
VashchilkoAV May 4, 2026
7ceefa6
Merge branch 'task05' into task06
VashchilkoAV May 4, 2026
3e19a41
todo 200*
VashchilkoAV May 18, 2026
b26f8c7
todo 300* simple
VashchilkoAV May 20, 2026
63fdd25
todo 300* full
VashchilkoAV Jun 3, 2026
c03740d
to prev
VashchilkoAV Jun 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/cmake.yml
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,7 @@ jobs:
run: |
$env:OPENCV_IO_ENABLE_OPENEXR = "1"
.\build\${{ env.BUILD_TYPE }}\test_mesh_min_cut.exe
# - name: Run test_depth_maps_pm (Windows)
# if: runner.os == 'Windows'
# shell: pwsh
# run: .\build\${{ env.BUILD_TYPE }}\test_depth_maps_pm.exe
9 changes: 8 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
**/*_cl.h
.idea
build
.DS_store
build*
cmake-build*
data/src/test_sfm/saharov/*.JPG
opencv-4.11.0
.github/scripts/macos/4.11.0.zip
2.2.0.zip
ceres-solver-2.2.0
eigen-3.4.0
eigen-3.4.0.tar.gz
35 changes: 35 additions & 0 deletions Q&A2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Перечислите идеи и коротко обозначьте мысли которые у вас возникали по мере выполнения задания, в частности попробуйте ответить на вопросы:

1) Зачем фильтровать матчи, если потом мы запускаем устойчивый к выбросам RANSAC и отфильтровываем шумные сопоставления? \
\
Число запусков в алгоритме RANSAC (см homography.cpp:182) зависит от w (переменная singlePointInlierProbability) -- вероятности того, что метч является инлаером. Чем больше эта вероятность, тем меньше нужно итераций RANSAC. Фильтрация метчей перед запускам RANSAC нужна чтобы увеличить эту вероятность.

2) Cluster filtering довольно хорошо работает и без Ratio test. Однако, если оставить только Cluster filtering, некоторые тесты начнут падать. Почему так происходит? В каких случаях наоборот, не хватает Ratio test и необходима дополнительная фильтрация?
- Cluster filtering слабо себя показывает в случае если на картинке присутсвуют регулярные структуры, за которые цепляется дескриптор => образуются множественные очень близкие друг к другу кластера, которые могут найти метчи из другого кластера. В этом случае cluster filtering такие матчи посчитает верными, что может быть ошибочно.
- Ratio test наоборот не учитывает пространственные окрестности, из-за чего может сметчить цветочки (элементы) из двух разных клумб (окрестностей).
3) С какой проблемой можно столкнуться при приравнивании единице элемента H33 матрицы гомографии? Как ее решить? \
\
В случае если матрица полученной системы численно нестабильна (это может произойти если в одной из нормировок H_33~0, остальные значения конечны и не бесконечно малы => при нормировке на H_33 получим огромные значения оставшихся элементов), тогда
- будет проблематично обращать такую матрицу, чтобы получить преобразованные точки
- флотовые вычисления вносят дополнительную ошибку когда складываем числа разного порядка

4) Какой подвох таится в попытке склеивать большие панорамы и ортофото методом, реализованным в данной домашке? (Для интуиции можно посмотреть на результат склейки, когда за корень взята какая-нибудь другая картинка) \
\
Заметно, что чем ближе пара склеенных фоток к корню, тем лучше склейка. Следовательно от выбора корня зависит общая невязка -- лучше выбирать корень таким образом, чтобы корень оказался в наиболее важной части композиции, тогда, согласно наблюдению, в зонах интереса склейка будет менее резкой.

5) Как можно автоматически построить граф для построения панорамы, чтобы на вход метод принимал только список картинок? \
(Мысли именно насчет однострочной панорамы)
- провести метчинг для каждой пары картинок
- для каждой пары картинок вычислить MSE заметченных дескрипторов
- для каждой картинки находим по две картинки с минимумом MSE -- это окрестность картинки
- далее находим две картинки с максимальными минимумами -- это краевые картинки
- начиная с любой из этих двух картинок используя минимальный из ее минимумов начинаем собирать граф-путь

6) Если с вашей реализацией SIFT пройти тесты не получилось, напишите (если пробовали дебажить), где, как вам кажется, проблема и как вы пробовали ее решать. \
\
Изначально была проблема с тайм-лимитами, пофиксил поправив настройки FLANN.

7) Если есть, фидбек по заданию: какая часть больше всего понравилась, где-то слишком сложно/просто (что именно), где-то слишком мало ссылок и тд.
\
\
Подбор гиперпарматеров в алгоритме FLANN оказался весьма неприятным -- приходилось искать компромисс между тайм-лимитами и скором, при этом у фейлов низкая воспроизводимость, что усложняло дебаг.
10 changes: 10 additions & 0 deletions Q&A3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Перечислите идеи и коротко обозначьте мысли которые у вас возникали по мере выполнения задания, в частности попробуйте ответить на вопросы:

1) Мы можем получить облако точек и взаимную ориентацию по двум камерам. Почему для выравнивания трёх камер мы использовали резекцию, а не посчитали E матрицу для второй пары камер и не разложили ее? \
При работе с двумя камерами, мы получаем матрицу E с точностью до масштаба. При добавлении последующих камер масштабы могут не метэчиться.
2) Как реализовать выравнивание если мы все же хотим использовать Е матрицу?
- Фиттить первоначально полученную матрицу P_n таким образом, чтобы 3х-мерные точки, полученные из первых двух камер при триангуляции не перемещались, но описанный процесс сильно похож на резекцию. Наверное потому что без иных вводных и критериев правильности облака точек сложно придумать иную концепцию.
- С другой стороны можно попробовать повторить нахождение матрицы E для следующей пары (одна из камер уже была в наборе, ее берем за основную с единичной P-матрицей), а потом RANSAC-ом связывать два облака, фиттируя преобразование масштаба для P-матрицы новой камеры. Проблема появялется при росте числа камер: если связывать новую пару только с предыдущей -- невязка будет накапливаться, если связывать все облака -- большая стоимость одной итерации RANSAC.

3) Если есть, фидбек по заданию: какая часть больше всего понравилась, где-то слишком сложно/просто (что именно), где-то слишком мало ссылок и тд. \
Как и в прошлом задании -- подбор параметров RANSAC для прохождения тестов. Хотелось бы больше интуиции, ведь по сути так как для разных тестов необходимо разное количество итераций RANSAC (причем по порядкам), из формулы числа итераций следует, что вероятности инлаеров сильно отличаются, возможно стоит добавить оценку этих параметров отдельным подзаданием.
38 changes: 38 additions & 0 deletions Q&A4.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Перечислите идеи и коротко обозначьте мысли которые у вас возникали по мере выполнения задания, в частности попробуйте ответить на вопросы:

1) test_ceres_solver/FitLine: почему найденная прямая и эталонная - не совпадают? Как это исправить пост-обработкой? Как это исправить формулировкой задачи?\
\
Прямые геометрически совпадают (одна прямая задается семейством наборов коэффициентов {a, b, c}, определенных с точностью до масштаба), коэффициенты же могут отличаться масштабом. \
На постобработке можно исправить, поделив коэффициенты на некий скейл (такой, чтобы c_0==c_ideal, тут можно любой из коэффициентов приравнять, но в решении c имеет наибольший модуль и вычисления получаются более стабильными?)\
В формулировку задачи можно добавить ограничение на величину одного из коэффициентов или на длину вектора (a, b)

2) BA: представьте что вы написали преобразование phg::Calibration -> блок параметров и обратное блок параметров -> phg::Calibration. Как проверить простым образом что эти преобразования сделаны корректно? Что должно быть в логе про процент inliers до/после BA если runBA() вызывать всегда два раза пордяд? Иначе говоря - что следует из того что в идеале runBA() должна быть (мне очень нравится это слово) - [идемпотентна](https://ru.wikipedia.org/wiki/%D0%98%D0%B4%D0%B5%D0%BC%D0%BF%D0%BE%D1%82%D0%B5%D0%BD%D1%82%D0%BD%D0%BE%D1%81%D1%82%D1%8C)?\
\
Написать темплейт-функцию, считающую, например, проекцию точки в фокальную плоскость и сделать ассерт на равенство проекций. \
Идемпотентность означает, что BA(BA(X)) = BA(X) => результат (процент inliers после однократного/двухкратного BA) должен совпадать.


3) Какое максимальное число кадров у вас получилось хорошо выравнять для каждого из датасетов? (проверьте хотя бы saharov32 и herzjesu25) Не забудьте приложить скриншоты. \
\
saharov32 -- 32/32 ![Alt Text](saharov32.png)
herzjesu25 -- 22/25 ![Alt Text](herzjesu22.png)

4) Если бы вычисления в double были абсолютно точны - можно ли было бы назвать вычисления в Calibration::project/unproject строго зеркальными? \
\
Нет, т.к. мы полностью теряем информацию о координате z исходной точки. Кстати, в задании 3 при условии обратимости матрицы K project/unproject были взаимно обратными. Мне кажется стоит в задании 3 функционал проецирования однородных координат также перенести в project.

5) Почему фокальная длина меняется от того что мы уменьшаем картинку? Почему именно f/downscale? \
\
$x_p = x_r \dfrac{f}{z} \Leftrightarrow x_r = \dfrac{x_p}{f} * z$ . \
При даунсемпле картинки в s раз $x_p^{'} = \dfrac{x_p}{s} \Rightarrow $ \
$x_r^{'} = \dfrac{x_p^{'}}{f} * z = \dfrac{x_p / s} {f} * z = \dfrac{x_p}{(f^{'} * s)} * z$ \
Так как $x_r^{'} = x_r \Rightarrow f^{'} * s = f \Rightarrow f^{'} = \dfrac{f}{s}$

6) Имеет ли право BA двигать точку отсчета системы координат (т.е. добавить константу ко всем координатам)? Как это повлияет на суммарную Loss? \\
В целом может, но зачем, это же не изменит координат векторов, не повлияет на Loss.

7) Каким образом можно гарантировать чтобы при сравнении нескольких последовательно построенных облаков точек одного и того же датасета (созданных по мере добавления фотографии за фотографией) в MeshLab - облака не были хаотично смещены/отмасштабированы/повернуты друг от друга? \\
Не оптимизировать параметры уже добавленных камер -- использовать систему координат 0-й камеры как якорную. Таким образом при сравнении в качестве осей брать оси 0-й камеры, в качестве масштаба брать среднее расстояние до триангулированных метчей первых двух камер. А еще лучше -- расстояние между первыми двумя камерами

100) Если есть - фидбек/идеи по улучшению задания.
Сделать более плавный переход от 3 задания к 4-му (как минимум project/unproject).
4 changes: 4 additions & 0 deletions data/debug/test_matching/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Ignore everything in this directory
*
# Except this file
!.gitignore
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added herzjesu22.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added saharov32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
44 changes: 37 additions & 7 deletions src/phg/core/calibration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,20 @@ int phg::Calibration::height() const {

cv::Vec3d phg::Calibration::project(const cv::Vec3d &point) const
{
// return K() * point; // original from task03
double x = point[0] / point[2];
double y = point[1] / point[2];

double r2 = x * x + y * y;
double r4 = r2 * r2;
// from task04
// // 11: добавьте учет радиальных искажений (k1_, k2_) (после деления на Z, но до умножения на f)
// double r_squared = x * x + y * y;
// double r_fourth = r_squared * r_squared;
// double radial_coef = 1. + k1_ * r_squared + k2_ * r_fourth;

// x *= radial_coef;
// y *= radial_coef;

x = x * (1.0 + k1_ * r2 + k2_ * r4);
y = y * (1.0 + k1_ * r2 + k2_ * r4);
Expand All @@ -52,17 +61,38 @@ cv::Vec3d phg::Calibration::project(const cv::Vec3d &point) const

cv::Vec3d phg::Calibration::unproject(const cv::Vec2d &pixel) const
{
// K().inv() * vector3d(pixel[0], pixel[1], 1.0);
double x = pixel[0] - cx_ - width_ * 0.5;
double y = pixel[1] - cy_ - height_ * 0.5;

x /= f_;
y /= f_;

double r2 = x * x + y * y;
double r4 = r2 * r2;

x = x / (1.0 + k1_ * r2 + k2_ * r4);
y = y / (1.0 + k1_ * r2 + k2_ * r4);

return cv::Vec3d(x, y, 1.0);
// from task05 -- probably wrong
// double r2 = x * x + y * y;
// double r4 = r2 * r2;

// x = x / (1.0 + k1_ * r2 + k2_ * r4);
// y = y / (1.0 + k1_ * r2 + k2_ * r4);

// return cv::Vec3d(x, y, 1.0);

// from task04
// 12: добавьте учет радиальных искажений, когда реализуете - подумайте: почему строго говоря это - не симметричная формула формуле из project? (но лишь приближение)
// потому что мы имеем дело с функцией 4 степени относительно x и y.
double x_u = x, y_u = y;
// while (1) {
for (size_t i = 0; i < 1000; i++) {
double r_squared = x_u * x_u + y_u * y_u;
double r_fourth = r_squared * r_squared;
double dr = 1 + k1_ * r_squared + k2_ * r_fourth;
x_u = x / dr;
y_u = y / dr;

if (std::abs(dr * x_u - x) + std::abs(dr * y_u - y) < 1e-10) {
break;
}
}

return cv::Vec3d(x_u, y_u, 1.0);
}
Loading
Loading