Skip to content

Commit

Permalink
task05
Browse files Browse the repository at this point in the history
  • Loading branch information
I-7 committed Jun 16, 2024
1 parent 10c9433 commit 636ae46
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 26 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/cmake.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,7 @@ jobs:
- name: test_depth_maps_pm
working-directory: ${{github.workspace}}
run: ./build/test_depth_maps_pm

- uses: actions/upload-artifact@v4
with:
path: data/debug/test_depth_maps_pm/
66 changes: 49 additions & 17 deletions src/phg/mvs/depth_maps/pm_depth_maps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "pm_geometry.h"
#include "pm_depth_maps_defines.h"

#define SOFT_PERTURBATION 1

namespace phg {

Expand Down Expand Up @@ -47,14 +48,17 @@ namespace phg {
return pixel_with_depth;
}

// TODO 101 реализуйте unproject (вам поможет тест на идемпотентность project -> unproject в test_depth_maps_pm)
// 101 реализуйте unproject (вам поможет тест на идемпотентность project -> unproject в test_depth_maps_pm)
vector3d unproject(const vector3d &pixel, const phg::Calibration &calibration, const matrix34d &PtoWorld)
{
double depth = pixel[2]; // на самом деле это не глубина, это координата по оси +Z (вдоль которой смотрит камера в ее локальной системе координат)

vector3d local_point; // TODO 102 пустите луч pixel из calibration а затем возьмите ан нем точку у которой по оси +Z координата=depth
vector3d local_point; // 102 пустите луч pixel из calibration а затем возьмите ан нем точку у которой по оси +Z координата=depth
local_point = calibration.unproject({ pixel[0], pixel[1] });
local_point *= depth / local_point[2];

vector3d global_point; // TODO 103 переведите точку из локальной системы в глобальную
vector3d global_point; // 103 переведите точку из локальной системы в глобальную
global_point = PtoWorld * homogenize(local_point);

return global_point;
}
Expand Down Expand Up @@ -116,16 +120,24 @@ namespace phg {
n0 = normal_map.at<vector3f>(j, i);

// 2) случайной пертурбации текущей гипотезы (мутация и уточнение того что уже смогли найти)
dp = r.nextf(d0 * 0.5f, d0 * 1.5); // TODO 104: сделайте так чтобы отклонение было тем меньше, чем номер итерации ближе к NITERATIONS, улучшило ли это результат?
np = cv::normalize(n0 + randomNormalObservedFromCamera(cameras_RtoWorld[ref_cam], r) * 0.5); // TODO 105: сделайте так чтобы отклонение было тем меньше, чем номер итерации ближе к NITERATIONS, улучшило ли это результат?
#ifdef SOFT_PERTURBATION
float w = 1.0f + 1.0f * (NITERATIONS - iter) / NITERATIONS; // decreasing from 2 to 1
dp = r.nextf(d0 / w, d0 * w);
np = cv::normalize(n0 + randomNormalObservedFromCamera(cameras_RtoWorld[ref_cam], r) * w / 4);
#else
dp = r.nextf(d0 * 0.5f, d0 * 1.5f);
np = cv::normalize(n0 + randomNormalObservedFromCamera(cameras_RtoWorld[ref_cam], r) * 0.5);
#endif

dp = std::max(ref_depth_min, std::min(ref_depth_max, dp));

// 3) новой случайной гипотезы из фрустума поиска (новые идеи, вечный поиск во всем пространстве)
// TODO 106: создайте случайную гипотезу dr+nr, вам поможет:
// 106: создайте случайную гипотезу dr+nr, вам поможет:
// - r.nextf(...)
// - ref_depth_min, ref_depth_max
// - randomNormalObservedFromCamera - поможет создать нормаль которая гарантированно смотрит на нас
// - randomNormalObservedFromCamera - поможет создать нормаль которая гарантированно смотрит на нас
dr = r.nextf(ref_depth_min, ref_depth_max);
nr = randomNormalObservedFromCamera(cameras_RtoWorld[ref_cam], r);
}

float best_depth = d0;
Expand Down Expand Up @@ -351,31 +363,43 @@ namespace phg {
ptrdiff_t u = x;
ptrdiff_t v = y;

// TODO 108: добавьте проверку "попали ли мы в камеру номер neighb_cam?" если не попали - возвращаем NO_COST
// 108: добавьте проверку "попали ли мы в камеру номер neighb_cam?" если не попали - возвращаем NO_COST
if (u < 0 || u >= width || v < 0 || v >= height) {
return NO_COST;
}

float intensity = cameras_imgs_grey[neighb_cam].at<unsigned char>(v, u) / 255.0f;
patch1.push_back(intensity);
}
}

// TODO 109: реализуйте ZNCC https://en.wikipedia.org/wiki/Cross-correlation#Zero-normalized_cross-correlation_(ZNCC)
// 109: реализуйте ZNCC https://en.wikipedia.org/wiki/Cross-correlation#Zero-normalized_cross-correlation_(ZNCC)
// или слайд #25 в лекции 5 про SGM и Cost-функции - https://my.compscicenter.ru/attachments/classes/slides_w2n8WNLY/photogrammetry_lecture_090321.pdf
rassert(patch0.size() == patch1.size(), 12489185129326);
size_t n = patch0.size();
float mean0 = 0.0f;
float mean1 = 0.0f;
// ...
for (size_t k = 0; k < n; ++k) {
float a = patch0[k];
float b = patch1[k];
mean0 += a;
mean1 += b;
// ...
}
mean0 /= n;
mean1 /= n;
// ...
float zncc = 0.0f;
float s0 = 0.0f;
float s1 = 0.0f;
for (size_t k = 0; k < n; ++k) {
zncc += (patch0[k] - mean0) * (patch1[k] - mean1);
s0 += (patch0[k] - mean0) * (patch0[k] - mean0);
s1 += (patch1[k] - mean1) * (patch1[k] - mean1);
}
if (s0 * s1 < 1e-8) {
zncc = NO_COST;
} else {
zncc = zncc / std::sqrt(s0 * s1);
}

// ZNCC в диапазоне [-1; 1], 1: идеальное совпадение, -1: ничего общего
rassert(zncc == zncc, 23141241210380); // проверяем что не nan
Expand All @@ -399,14 +423,22 @@ namespace phg {

float best_cost = costs[0];

float cost_sum = best_cost;
float cost_w = 1.0f;
float cost_sum = 0;
float cost_w = 0;

// TODO 110 реализуйте какое-то "усреднение cost-ов по всем соседям", с ограничением что участвуют только COSTS_BEST_K_LIMIT лучших
// TODO 111 добавьте к этому усреднению еще одно ограничение: если cost больше чем best_cost*COSTS_K_RATIO - то такой cost подозрительно плохой и мы его не хотим учитывать (вероятно occlusion)
// TODO 112 а что если в пикселе occlusion, но best_cost - большой и поэтому отсечение по best_cost*COSTS_K_RATIO не срабатывает? можно ли это отсечение как-то выправить для такого случая?
// 110 реализуйте какое-то "усреднение cost-ов по всем соседям", с ограничением что участвуют только COSTS_BEST_K_LIMIT лучших
// 111 добавьте к этому усреднению еще одно ограничение: если cost больше чем best_cost*COSTS_K_RATIO - то такой cost подозрительно плохой и мы его не хотим учитывать (вероятно occlusion)
// 112 а что если в пикселе occlusion, но best_cost - большой и поэтому отсечение по best_cost*COSTS_K_RATIO не срабатывает? можно ли это отсечение как-то выправить для такого случая?
// TODO 207 а что если добавить какой-нибудь бонус в случае если больше чем Х камер засчиталось? улучшается/ухудшается ли от этого что-то на herzjezu25? а при большем числе фотографий

for (size_t i = 0; i < costs.size() && i < COSTS_BEST_K_LIMIT; i++) {
if (costs[i] > best_cost * COSTS_K_RATIO) {
continue;
}
cost_sum += costs[i];
cost_w += 1;
}

float avg_cost = cost_sum / cost_w;
return avg_cost;
}
Expand Down
13 changes: 4 additions & 9 deletions tests/test_depth_maps_pm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,18 @@
// Datasets:

// достаточно чтобы у вас работало на этом датасете, тестирование на Travis CI тоже ведется на нем
#define DATASET_DIR "saharov32"
#define DATASET_DOWNSCALE 4
//#define DATASET_DIR "saharov32"
//#define DATASET_DOWNSCALE 4

//#define DATASET_DIR "temple47"
//#define DATASET_DOWNSCALE 2
#define DATASET_DIR "temple47"
#define DATASET_DOWNSCALE 2

// скачайте картинки этого датасета в папку data/src/datasets/herzjesu25/ по ссылке из файла LINK.txt в папке датасета
//#define DATASET_DIR "herzjesu25"
//#define DATASET_DOWNSCALE 8
//________________________________________________________________________________

TEST (test_depth_maps_pm, SingleDepthMap) {
// TODO этот код надо раскомментировать чтобы запустить тестирование:
/*
Dataset dataset = loadDataset(DATASET_DIR, DATASET_DOWNSCALE);
phg::PMDepthMapsBuilder builder(dataset.ncameras, dataset.cameras_imgs, dataset.cameras_imgs_grey, dataset.cameras_labels, dataset.cameras_P, dataset.calibration);

Expand All @@ -43,11 +41,9 @@ TEST (test_depth_maps_pm, SingleDepthMap) {
dataset.ncameras = cameras_limit;
cv::Mat depth_map, normal_map, cost_map;
builder.buildDepthMap(ci, depth_map, cost_map, normal_map, dataset.cameras_depth_min[ci], dataset.cameras_depth_max[ci]);
*/
}

TEST (test_depth_maps_pm, AllDepthMaps) {
/* TODO этот код можно раскомментировать чтобы построить много карт глубины и сохранить их облака точек:
Dataset full_dataset = loadDataset(DATASET_DIR, DATASET_DOWNSCALE);

const size_t ref_camera_shift = 2;
Expand Down Expand Up @@ -75,5 +71,4 @@ TEST (test_depth_maps_pm, AllDepthMaps) {
std::string tie_points_filename = std::string("data/debug/test_depth_maps_pm/") + getTestName() + "/all_points_" + to_string(ndepth_maps) + ".ply";
phg::exportPointCloud(all_points, tie_points_filename, all_colors, all_normals);
}
*/
}

0 comments on commit 636ae46

Please sign in to comment.