diff --git a/components/renderers/cpp/CMakeLists.txt b/components/renderers/cpp/CMakeLists.txt index fe93b78bb84000a5a499eda8dd136a5f7c153fae..4b3c7e2d72ed9c50ed347b2801b6992e18ed08c4 100644 --- a/components/renderers/cpp/CMakeLists.txt +++ b/components/renderers/cpp/CMakeLists.txt @@ -13,6 +13,7 @@ add_library(ftlrender src/gltexture.cpp src/touch.cu src/GLRender.cpp + src/carver.cu #src/assimp_render.cpp #src/assimp_scene.cpp ) diff --git a/components/renderers/cpp/src/CUDARender.cpp b/components/renderers/cpp/src/CUDARender.cpp index d44a8cfd102b4a1bf90d250ded75a543f09e01b2..0e16d901377019275954e146b82d7e6bd77a0268 100644 --- a/components/renderers/cpp/src/CUDARender.cpp +++ b/components/renderers/cpp/src/CUDARender.cpp @@ -7,6 +7,7 @@ #include <ftl/render/colouriser.hpp> #include <ftl/cuda/transform.hpp> #include <ftl/operators/cuda/smoothing_cuda.hpp> +#include "carver.hpp" #include <ftl/cuda/colour_cuda.hpp> @@ -254,6 +255,57 @@ void CUDARender::_mesh(ftl::rgbd::Frame &out, const Eigen::Matrix4d &t, cudaStre // FIXME: Is it possible to remember previously if there should be depth? bool use_depth = scene_->anyHasChannel(Channel::Depth) || scene_->anyHasChannel(Channel::GroundTruth); + // For each source depth map, verify results + if (value("pre_carve_inputs", true)) { + for (size_t i=0; i < scene_->frames.size(); ++i) { + //if (!scene_->hasFrame(i)) continue; + auto &f = scene_->frames[i].cast<ftl::rgbd::Frame>(); + //auto *s = scene_->sources[i]; + + if (!f.has(Channel::Colour)) { + //LOG(ERROR) << "Missing required channel"; + continue; + } + + // We have the needed depth data? + if (use_depth && !f.hasOwn(Channel::Depth) && !f.hasOwn(Channel::GroundTruth)) { + continue; + } + + for (size_t j=0; j < scene_->frames.size(); ++j) { + if (i == j) continue; + + //if (!scene_->hasFrame(i)) continue; + auto &ref = scene_->frames[j].cast<ftl::rgbd::Frame>(); + //auto *s = scene_->sources[i]; + + if (!ref.has(Channel::Colour)) { + //LOG(ERROR) << "Missing required channel"; + continue; + } + + // We have the needed depth data? + if (use_depth && !ref.hasOwn(Channel::Depth) && !ref.hasOwn(Channel::GroundTruth)) { + continue; + } + + //auto pose = MatrixConversion::toCUDA(t.cast<float>() * f.getPose().cast<float>()); + //Eigen::Matrix4f refpose = ref.getPose().cast<float>(); + auto transformR = MatrixConversion::toCUDA(ref.getPose().cast<float>().inverse() * f.getPose().cast<float>()); //poseInverse_; + //auto transform = pose_ * MatrixConversion::toCUDA(t.cast<float>() * f.getPose().cast<float>()); + + ftl::cuda::depth_carve( + f.create<cv::cuda::GpuMat>(_getDepthChannel()), + ref.get<cv::cuda::GpuMat>(Channel::Depth), + transformR, + f.getLeft(), + ref.getLeft(), + stream_ + ); + } + } + } + // For each source depth map for (size_t i=0; i < scene_->frames.size(); ++i) { //if (!scene_->hasFrame(i)) continue; @@ -365,7 +417,7 @@ void CUDARender::_mesh(ftl::rgbd::Frame &out, const Eigen::Matrix4d &t, cudaStre ftl::cuda::touch_merge(depth_out_, out.createTexture<float>(_getDepthChannel()), collisions_, 1024, touch_dist_, stream_); // For each source depth map, verify results - if (value("carve_result", true)) { + if (value("post_carve_result", false)) { for (size_t i=0; i < scene_->frames.size(); ++i) { //if (!scene_->hasFrame(i)) continue; auto &f = scene_->frames[i].cast<ftl::rgbd::Frame>(); @@ -383,13 +435,12 @@ void CUDARender::_mesh(ftl::rgbd::Frame &out, const Eigen::Matrix4d &t, cudaStre //auto pose = MatrixConversion::toCUDA(t.cast<float>() * f.getPose().cast<float>()); auto transformR = MatrixConversion::toCUDA(f.getPose().cast<float>().inverse() * t.cast<float>().inverse()) * poseInverse_; - auto transform = pose_ * MatrixConversion::toCUDA(t.cast<float>() * f.getPose().cast<float>()); + //auto transform = pose_ * MatrixConversion::toCUDA(t.cast<float>() * f.getPose().cast<float>()); - ftl::cuda::reverse_verify( + ftl::cuda::depth_carve( out.create<cv::cuda::GpuMat>(_getDepthChannel()), f.get<cv::cuda::GpuMat>(Channel::Depth), transformR, - transform, params_.camera, f.getLeft(), stream_ diff --git a/components/renderers/cpp/src/carver.cu b/components/renderers/cpp/src/carver.cu new file mode 100644 index 0000000000000000000000000000000000000000..19435598cee8fdf5c70cec4e3b1344f2752ad36c --- /dev/null +++ b/components/renderers/cpp/src/carver.cu @@ -0,0 +1,47 @@ +#include "carver.hpp" + +// ==== Reverse Verify Result ================================================== + +__global__ void reverse_check_kernel( + float* __restrict__ depth_in, + const float* __restrict__ depth_original, + int pitch4, + int opitch4, + float4x4 transformR, + ftl::rgbd::Camera vintrin, + ftl::rgbd::Camera ointrin +) { + const int x = blockIdx.x*blockDim.x + threadIdx.x; + const int y = blockIdx.y*blockDim.y + threadIdx.y; + + if (x < 0 || x >= vintrin.width || y < 0 || y >= vintrin.height) return; + + float d = depth_in[y*pitch4+x]; + + // FIXME: This is dangerous, need to check through alternates instead + while (true) { + float3 campos = transformR * vintrin.screenToCam(x,y,d); + int2 spos = ointrin.camToScreen<int2>(campos); + int ox = spos.x; + int oy = spos.y; + + if (campos.z > 0.0f && ox >= 0 && ox < ointrin.width && oy >= 0 && oy < ointrin.height) { + float d2 = depth_original[oy*opitch4+ox]; + if (!(d2 < ointrin.maxDepth && d2 - campos.z > d2*0.001f)) break; + d += 0.002f; + } else break; + } + + depth_in[y*pitch4+x] = d; +} + +void ftl::cuda::depth_carve(cv::cuda::GpuMat &depth_in, const cv::cuda::GpuMat &depth_original, const float4x4 &transformR, const ftl::rgbd::Camera &vintrin, const ftl::rgbd::Camera &ointrin, cudaStream_t stream) { + static constexpr int THREADS_X = 8; + static constexpr int THREADS_Y = 8; + + const dim3 gridSize((depth_in.cols + THREADS_X - 1)/THREADS_X, (depth_in.rows + THREADS_Y - 1)/THREADS_Y); + const dim3 blockSize(THREADS_X, THREADS_Y); + + reverse_check_kernel<<<gridSize, blockSize, 0, stream>>>(depth_in.ptr<float>(), depth_original.ptr<float>(), depth_in.step1(), depth_original.step1(), transformR, vintrin, ointrin); + cudaSafeCall( cudaGetLastError() ); +} diff --git a/components/renderers/cpp/src/carver.hpp b/components/renderers/cpp/src/carver.hpp new file mode 100644 index 0000000000000000000000000000000000000000..f3e6f671a531aa921c0c61ae81d3f407b5a7519d --- /dev/null +++ b/components/renderers/cpp/src/carver.hpp @@ -0,0 +1,25 @@ +#ifndef _FTL_CUDA_CARVER_HPP_ +#define _FTL_CUDA_CARVER_HPP_ + +#include <ftl/cuda_common.hpp> +#include <ftl/cuda_matrix_util.hpp> +#include <ftl/rgbd/camera.hpp> + +namespace ftl { +namespace cuda { + +/** + * Carve `in` using `ref` as visibility reference. + */ +void depth_carve( + cv::cuda::GpuMat &in, + const cv::cuda::GpuMat &ref, + const float4x4 &transform, + const ftl::rgbd::Camera &incam, + const ftl::rgbd::Camera &refcam, + cudaStream_t stream); + +} +} + +#endif \ No newline at end of file diff --git a/components/renderers/cpp/src/triangle_render.cu b/components/renderers/cpp/src/triangle_render.cu index 4c8770bdbaeabbfa8e2288c1d15a3f7a3aa0e27c..301cf2a226d0cff47c9a1672fe7d78b124f3fc99 100644 --- a/components/renderers/cpp/src/triangle_render.cu +++ b/components/renderers/cpp/src/triangle_render.cu @@ -224,53 +224,6 @@ void ftl::cuda::merge_convert_depth(TextureObject<int> &depth_in, TextureObject< cudaSafeCall( cudaGetLastError() ); } -// ==== Reverse Verify Result ================================================== - -__global__ void reverse_check_kernel( - float* __restrict__ depth_in, - const float* __restrict__ depth_original, - int pitch4, - int opitch4, - float4x4 transformR, - float4x4 transform, - ftl::rgbd::Camera vintrin, - ftl::rgbd::Camera ointrin -) { - const int x = blockIdx.x*blockDim.x + threadIdx.x; - const int y = blockIdx.y*blockDim.y + threadIdx.y; - - if (x < 0 || x >= vintrin.width || y < 0 || y >= vintrin.height) return; - - float d = depth_in[y*pitch4+x]; - - // FIXME: This is dangerous, need to check through alternates instead - while (true) { - float3 campos = transformR * vintrin.screenToCam(x,y,d); - int2 spos = ointrin.camToScreen<int2>(campos); - int ox = spos.x; - int oy = spos.y; - - if (campos.z > 0.0f && ox >= 0 && ox < ointrin.width && oy >= 0 && oy < ointrin.height) { - float d2 = depth_original[oy*opitch4+ox]; - if (!(d2 < ointrin.maxDepth && d2 - campos.z > d2*0.001f)) break; - d += 0.002f; - } else break; - } - - depth_in[y*pitch4+x] = d; -} - -void ftl::cuda::reverse_verify(cv::cuda::GpuMat &depth_in, const cv::cuda::GpuMat &depth_original, const float4x4 &transformR, const float4x4 &transform, const ftl::rgbd::Camera &vintrin, const ftl::rgbd::Camera &ointrin, cudaStream_t stream) { - static constexpr int THREADS_X = 8; - static constexpr int THREADS_Y = 8; - - const dim3 gridSize((depth_in.cols + THREADS_X - 1)/THREADS_X, (depth_in.rows + THREADS_Y - 1)/THREADS_Y); - const dim3 blockSize(THREADS_X, THREADS_Y); - - reverse_check_kernel<<<gridSize, blockSize, 0, stream>>>(depth_in.ptr<float>(), depth_original.ptr<float>(), depth_in.step1(), depth_original.step1(), transformR, transform, vintrin, ointrin); - cudaSafeCall( cudaGetLastError() ); -} - // ==== BLENDER ======== /*