From 8a604901a2eb0f7bba4895245fc8820208a7b93b Mon Sep 17 00:00:00 2001 From: Nicolas Pope <nicolas.pope@utu.fi> Date: Sat, 29 Jun 2019 13:44:25 +0300 Subject: [PATCH] Resolves #40 by colouring registration errors --- applications/gui/src/screen.cpp | 65 +++++++++++---- .../reconstruct/include/ftl/voxel_scene.hpp | 1 + applications/reconstruct/src/garbage.cu | 21 ++++- applications/reconstruct/src/garbage.hpp | 1 + applications/reconstruct/src/integrators.cu | 80 +++++++++++++++++++ applications/reconstruct/src/integrators.hpp | 3 + applications/reconstruct/src/voxel_scene.cpp | 26 ++++-- .../rgbd-sources/src/snapshot_source.cpp | 19 +++++ 8 files changed, 193 insertions(+), 23 deletions(-) diff --git a/applications/gui/src/screen.cpp b/applications/gui/src/screen.cpp index 63965a3fc..00d46ee58 100644 --- a/applications/gui/src/screen.cpp +++ b/applications/gui/src/screen.cpp @@ -9,6 +9,7 @@ #include <nanogui/combobox.h> #include <nanogui/label.h> #include <nanogui/toolbutton.h> +#include <nanogui/popupbutton.h> #include <opencv2/opencv.hpp> @@ -121,6 +122,7 @@ ftl::gui::Screen::Screen(ftl::Configurable *proot, ftl::net::Universe *pnet, ftl button->setFixedSize(Vector2i(40,40)); button->setCallback([this]() { //swindow_->setVisible(true); + setActiveCamera(nullptr); }); /*button = new ToolButton(innertool, ENTYPO_ICON_PLUS); @@ -132,22 +134,54 @@ ftl::gui::Screen::Screen(ftl::Configurable *proot, ftl::net::Universe *pnet, ftl //swindow_->setVisible(true); });*/ - button = new ToolButton(innertool, ENTYPO_ICON_PLUS); - button->setIconExtraScale(1.5f); - button->setTheme(toolbuttheme); - button->setTooltip("Camera Sources"); - button->setFixedSize(Vector2i(40,40)); - button->setCallback([this]() { + auto popbutton = new PopupButton(innertool, "", ENTYPO_ICON_PLUS); + popbutton->setIconExtraScale(1.5f); + popbutton->setTheme(toolbuttheme); + popbutton->setTooltip("Add"); + popbutton->setFixedSize(Vector2i(40,40)); + popbutton->setSide(Popup::Side::Right); + popbutton->setChevronIcon(0); + Popup *popup = popbutton->popup(); + popup->setLayout(new GroupLayout()); + popup->setTheme(toolbuttheme); + //popup->setAnchorHeight(100); + + auto itembutton = new Button(popup, "Add Camera", ENTYPO_ICON_CAMERA); + itembutton->setCallback([this,popup]() { swindow_->setVisible(true); + popup->setVisible(false); }); - button = new ToolButton(innertool, ENTYPO_ICON_TOOLS); - button->setIconExtraScale(1.5f); - button->setTheme(toolbuttheme); - button->setTooltip("Connections"); - button->setFixedSize(Vector2i(40,40)); - button->setCallback([this]() { + itembutton = new Button(popup, "Add Node", ENTYPO_ICON_LAPTOP); + itembutton->setCallback([this,popup]() { + cwindow_->setVisible(true); + popup->setVisible(false); + }); + + popbutton = new PopupButton(innertool, "", ENTYPO_ICON_TOOLS); + popbutton->setIconExtraScale(1.5f); + popbutton->setTheme(toolbuttheme); + popbutton->setTooltip("Tools"); + popbutton->setFixedSize(Vector2i(40,40)); + popbutton->setSide(Popup::Side::Right); + popbutton->setChevronIcon(0); + popup = popbutton->popup(); + popup->setLayout(new GroupLayout()); + popup->setTheme(toolbuttheme); + //popbutton->setCallback([this]() { + // cwindow_->setVisible(true); + //}); + + itembutton = new Button(popup, "Connections"); + itembutton->setCallback([this,popup]() { cwindow_->setVisible(true); + popup->setVisible(false); + }); + + itembutton = new Button(popup, "Manual Registration"); + itembutton->setCallback([this,popup]() { + // Show pose win... + popup->setVisible(false); }); button = new ToolButton(toolbar, ENTYPO_ICON_COG); @@ -164,9 +198,10 @@ ftl::gui::Screen::Screen(ftl::Configurable *proot, ftl::net::Universe *pnet, ftl mwindow_->setVisible(false); cwindow_->setPosition(Eigen::Vector2i(80, 20)); - swindow_->setPosition(Eigen::Vector2i(80, 400)); + //swindow_->setPosition(Eigen::Vector2i(80, 400)); cwindow_->setVisible(false); - swindow_->setVisible(false); + swindow_->setVisible(true); + swindow_->center(); cwindow_->setTheme(windowtheme); swindow_->setTheme(windowtheme); @@ -201,8 +236,10 @@ void ftl::gui::Screen::setActiveCamera(ftl::gui::Camera *cam) { if (cam) { status_ = cam->source()->getURI(); mwindow_->setVisible(true); + swindow_->setVisible(false); } else { mwindow_->setVisible(false); + swindow_->setVisible(true); status_ = "No camera..."; } } diff --git a/applications/reconstruct/include/ftl/voxel_scene.hpp b/applications/reconstruct/include/ftl/voxel_scene.hpp index 44cdf9750..1babf0145 100644 --- a/applications/reconstruct/include/ftl/voxel_scene.hpp +++ b/applications/reconstruct/include/ftl/voxel_scene.hpp @@ -101,6 +101,7 @@ class SceneRep : public ftl::Configurable { bool do_reset_; std::vector<Cameras> cameras_; cudaStream_t integ_stream_; + bool reg_mode_; }; }; // namespace voxhash diff --git a/applications/reconstruct/src/garbage.cu b/applications/reconstruct/src/garbage.cu index f0ba686e4..beb7027b9 100644 --- a/applications/reconstruct/src/garbage.cu +++ b/applications/reconstruct/src/garbage.cu @@ -35,6 +35,25 @@ void ftl::cuda::starveVoxels(HashData& hashData, const HashParams& hashParams) { #endif } +__global__ void clearVoxelsKernel(HashData hashData) { + + // Stride over all allocated blocks + for (int bi=blockIdx.x; bi<*hashData.d_hashCompactifiedCounter; bi+=NUM_CUDA_BLOCKS) { + + const HashEntry& entry = hashData.d_hashCompactified[bi]; + hashData.d_SDFBlocks[entry.ptr + threadIdx.x].weight = 0; + + } +} + +void ftl::cuda::clearVoxels(HashData& hashData, const HashParams& hashParams) { + const unsigned int threadsPerBlock = SDF_BLOCK_SIZE*SDF_BLOCK_SIZE*SDF_BLOCK_SIZE; + const dim3 gridSize(NUM_CUDA_BLOCKS, 1); + const dim3 blockSize(threadsPerBlock, 1); + + clearVoxelsKernel << <gridSize, blockSize >> >(hashData); +} + __shared__ float shared_MinSDF[SDF_BLOCK_SIZE * SDF_BLOCK_SIZE * SDF_BLOCK_SIZE / 2]; __shared__ uint shared_MaxWeight[SDF_BLOCK_SIZE * SDF_BLOCK_SIZE * SDF_BLOCK_SIZE / 2]; @@ -118,7 +137,7 @@ void ftl::cuda::garbageCollectIdentify(HashData& hashData, const HashParams& has __global__ void garbageCollectFreeKernel(HashData hashData) { // Stride over all allocated blocks - for (int bi=blockIdx.x*blockDim.x + threadIdx.x; bi<*hashData.d_hashCompactifiedCounter; bi+=NUM_CUDA_BLOCKS) { + for (int bi=blockIdx.x*blockDim.x + threadIdx.x; bi<*hashData.d_hashCompactifiedCounter; bi+=NUM_CUDA_BLOCKS*blockDim.x) { if (hashData.d_hashDecision[bi] != 0) { //decision to delete the hash entry diff --git a/applications/reconstruct/src/garbage.hpp b/applications/reconstruct/src/garbage.hpp index a7bdbc245..477db1ae8 100644 --- a/applications/reconstruct/src/garbage.hpp +++ b/applications/reconstruct/src/garbage.hpp @@ -4,6 +4,7 @@ namespace ftl { namespace cuda { +void clearVoxels(ftl::voxhash::HashData& hashData, const ftl::voxhash::HashParams& hashParams); void starveVoxels(ftl::voxhash::HashData& hashData, const ftl::voxhash::HashParams& hashParams); void garbageCollectIdentify(ftl::voxhash::HashData& hashData, const ftl::voxhash::HashParams& hashParams, cudaStream_t stream); void garbageCollectFree(ftl::voxhash::HashData& hashData, const ftl::voxhash::HashParams& hashParams, cudaStream_t stream); diff --git a/applications/reconstruct/src/integrators.cu b/applications/reconstruct/src/integrators.cu index 07f0834d4..d34c02125 100644 --- a/applications/reconstruct/src/integrators.cu +++ b/applications/reconstruct/src/integrators.cu @@ -189,3 +189,83 @@ void ftl::cuda::integrateDepthMap(HashData& hashData, const HashParams& hashPara //cutilCheckMsg(__FUNCTION__); #endif } + + +__global__ void integrateRegistrationKernel(HashData hashData, HashParams hashParams, DepthCameraParams cameraParams, cudaTextureObject_t depthT, cudaTextureObject_t colourT) { + + // Stride over all allocated blocks + for (int bi=blockIdx.x; bi<*hashData.d_hashCompactifiedCounter; bi+=NUM_CUDA_BLOCKS) { + + //TODO check if we should load this in shared memory + HashEntry& entry = hashData.d_hashCompactified[bi]; + + + int3 pi_base = hashData.SDFBlockToVirtualVoxelPos(entry.pos); + + uint i = threadIdx.x; //inside of an SDF block + int3 pi = pi_base + make_int3(hashData.delinearizeVoxelIndex(i)); + float3 pf = hashData.virtualVoxelPosToWorld(pi); + + pf = hashParams.m_rigidTransformInverse * pf; + uint2 screenPos = make_uint2(cameraParams.cameraToKinectScreenInt(pf)); + + // For this voxel in hash, get its screen position and check it is on screen + if (screenPos.x < cameraParams.m_imageWidth && screenPos.y < cameraParams.m_imageHeight) { //on screen + + //float depth = g_InputDepth[screenPos]; + float depth = tex2D<float>(depthT, screenPos.x, screenPos.y); + //if (depth > 20.0f) return; + + uchar4 color = make_uchar4(0, 0, 0, 0); + color = tex2D<uchar4>(colourT, screenPos.x, screenPos.y); + + // Depth is within accepted max distance from camera + if (depth > 0.01f && depth < hashParams.m_maxIntegrationDistance) { // valid depth and color (Nick: removed colour check) + float depthZeroOne = cameraParams.cameraToKinectProjZ(depth); + + // Calculate SDF of this voxel wrt the depth map value + float sdf = depth - pf.z; + float truncation = hashData.getTruncation(depth); + + if (sdf > -truncation) { + float weightUpdate = max(hashParams.m_integrationWeightSample * 1.5f * (1.0f-depthZeroOne), 1.0f); + + Voxel curr; //construct current voxel + curr.sdf = sdf; + curr.weight = weightUpdate; + curr.color = make_uchar3(color.x, color.y, color.z); + + uint idx = entry.ptr + i; + + Voxel out; + const Voxel &v1 = curr; + const Voxel &v0 = hashData.d_SDFBlocks[idx]; + + float redshift = (v0.weight > 0) ? 1.0f - ((v1.sdf - v0.sdf) / hashParams.m_truncation)*0.5f : 1.0f; + + out.color.x = min(max(v1.color.x*redshift,0.0f),255.0f); + out.color.y = min(max(v1.color.y*redshift,0.0f),255.0f); + out.color.z = min(max(v1.color.z*(1.0f / redshift),0.0f),255.0f); + + out.sdf = (v0.sdf * (float)v0.weight + v1.sdf * (float)v1.weight) / ((float)v0.weight + (float)v1.weight); + out.weight = min(c_hashParams.m_integrationWeightMax, (unsigned int)v0.weight + (unsigned int)v1.weight); + + hashData.d_SDFBlocks[idx] = out; + + } + } + } + + } // Stride loop +} + + +void ftl::cuda::integrateRegistration(HashData& hashData, const HashParams& hashParams, + const DepthCameraData& depthCameraData, const DepthCameraParams& depthCameraParams, cudaStream_t stream) { + const unsigned int threadsPerBlock = SDF_BLOCK_SIZE*SDF_BLOCK_SIZE*SDF_BLOCK_SIZE; + const dim3 gridSize(NUM_CUDA_BLOCKS, 1); + const dim3 blockSize(threadsPerBlock, 1); + + integrateRegistrationKernel << <gridSize, blockSize, 0, stream >> >(hashData, hashParams, depthCameraParams, depthCameraData.depth_obj_, depthCameraData.colour_obj_); + +} \ No newline at end of file diff --git a/applications/reconstruct/src/integrators.hpp b/applications/reconstruct/src/integrators.hpp index df9f425c9..756ff2ea4 100644 --- a/applications/reconstruct/src/integrators.hpp +++ b/applications/reconstruct/src/integrators.hpp @@ -10,6 +10,9 @@ namespace cuda { void integrateDepthMap(ftl::voxhash::HashData& hashData, const ftl::voxhash::HashParams& hashParams, const DepthCameraData& depthCameraData, const DepthCameraParams& depthCameraParams, cudaStream_t stream); +void integrateRegistration(ftl::voxhash::HashData& hashData, const ftl::voxhash::HashParams& hashParams, + const DepthCameraData& depthCameraData, const DepthCameraParams& depthCameraParams, cudaStream_t stream); + } } diff --git a/applications/reconstruct/src/voxel_scene.cpp b/applications/reconstruct/src/voxel_scene.cpp index eb4628858..216325ded 100644 --- a/applications/reconstruct/src/voxel_scene.cpp +++ b/applications/reconstruct/src/voxel_scene.cpp @@ -47,6 +47,11 @@ SceneRep::SceneRep(nlohmann::json &config) : Configurable(config), do_reset_(fal on("SDFMaxIntegrationDistance", [this](const ftl::config::Event &e) { m_hashParams.m_maxIntegrationDistance = value("SDFMaxIntegrationDistance", 10.0f); }); + on("showRegistration", [this](const ftl::config::Event &e) { + reg_mode_ = value("showRegistration", false); + }); + + reg_mode_ = value("showRegistration", false); cudaSafeCall(cudaStreamCreate(&integ_stream_)); //integ_stream_ = 0; @@ -79,12 +84,14 @@ int SceneRep::upload() { continue; } else { auto in = cam.source; + + cam.params.fx = in->parameters().fx; + cam.params.fy = in->parameters().fy; + cam.params.mx = -in->parameters().cx; + cam.params.my = -in->parameters().cy; + // Only now do we have camera parameters for allocations... if (cam.params.m_imageWidth == 0) { - cam.params.fx = in->parameters().fx; - cam.params.fy = in->parameters().fy; - cam.params.mx = -in->parameters().cx; - cam.params.my = -in->parameters().cy; cam.params.m_imageWidth = in->parameters().width; cam.params.m_imageHeight = in->parameters().height; cam.params.m_sensorDepthWorldMax = in->parameters().maxDepth; @@ -144,7 +151,7 @@ void SceneRep::integrate() { //volumetrically integrate the depth data into the depth SDFBlocks _integrateDepthMap(cam.gpu, cam.params); - //_garbageCollect(cam.gpu); + //_garbageCollect(); m_numIntegratedFrames++; } @@ -180,7 +187,7 @@ void SceneRep::garbage() { void SceneRep::setLastRigidTransform(const Eigen::Matrix4f& lastRigidTransform) { m_hashParams.m_rigidTransform = MatrixConversion::toCUDA(lastRigidTransform); - m_hashParams.m_rigidTransformInverse = m_hashParams.m_rigidTransform.getInverse(); + m_hashParams.m_rigidTransformInverse = MatrixConversion::toCUDA(lastRigidTransform.inverse()); //m_hashParams.m_rigidTransform.getInverse(); } /*void SceneRep::setLastRigidTransformAndCompactify(const Eigen::Matrix4f& lastRigidTransform, const DepthCameraData& depthCameraData) { @@ -200,7 +207,9 @@ void SceneRep::nextFrame() { _destroy(); _create(_parametersFromConfig()); } else { - ftl::cuda::starveVoxels(m_hashData, m_hashParams); + //ftl::cuda::compactifyAllocated(m_hashData, m_hashParams, integ_stream_); + if (reg_mode_) ftl::cuda::clearVoxels(m_hashData, m_hashParams); + else ftl::cuda::starveVoxels(m_hashData, m_hashParams); m_numIntegratedFrames = 0; } } @@ -407,7 +416,8 @@ void SceneRep::_compactifyAllocated() { } void SceneRep::_integrateDepthMap(const DepthCameraData& depthCameraData, const DepthCameraParams& depthCameraParams) { - ftl::cuda::integrateDepthMap(m_hashData, m_hashParams, depthCameraData, depthCameraParams, integ_stream_); + if (!reg_mode_) ftl::cuda::integrateDepthMap(m_hashData, m_hashParams, depthCameraData, depthCameraParams, integ_stream_); + else ftl::cuda::integrateRegistration(m_hashData, m_hashParams, depthCameraData, depthCameraParams, integ_stream_); } void SceneRep::_garbageCollect() { diff --git a/components/rgbd-sources/src/snapshot_source.cpp b/components/rgbd-sources/src/snapshot_source.cpp index 0e8dec08b..d3e70524e 100644 --- a/components/rgbd-sources/src/snapshot_source.cpp +++ b/components/rgbd-sources/src/snapshot_source.cpp @@ -23,5 +23,24 @@ SnapshotSource::SnapshotSource(ftl::rgbd::Source *host, SnapshotReader &reader, ftl::rgbd::colourCorrection(rgb_, host->value("gamma", 1.0f), host->value("temperature", 6500)); }); + // Add calibration to config object + host_->getConfig()["focal"] = params_.fx; + host_->getConfig()["centre_x"] = params_.cx; + host_->getConfig()["centre_y"] = params_.cy; + host_->getConfig()["baseline"] = params_.baseline; + + host_->on("focal", [this](const ftl::config::Event &e) { + params_.fx = host_->value("focal", params_.fx); + params_.fy = params_.fx; + }); + + host_->on("centre_x", [this](const ftl::config::Event &e) { + params_.cx = host_->value("centre_x", params_.cx); + }); + + host_->on("centre_y", [this](const ftl::config::Event &e) { + params_.cy = host_->value("centre_y", params_.cy); + }); + setPose(pose); } -- GitLab