diff --git a/components/renderers/cpp/src/carver.cu b/components/renderers/cpp/src/carver.cu index 19435598cee8fdf5c70cec4e3b1344f2752ad36c..96e5b16fd11157589f7e07f14e0748f9e73b447e 100644 --- a/components/renderers/cpp/src/carver.cu +++ b/components/renderers/cpp/src/carver.cu @@ -1,5 +1,9 @@ #include "carver.hpp" +__device__ inline float depthErrorCoef(const ftl::rgbd::Camera &cam, float disps=1.0f) { + return disps / (cam.baseline*cam.fx); +} + // ==== Reverse Verify Result ================================================== __global__ void reverse_check_kernel( @@ -17,9 +21,11 @@ __global__ void reverse_check_kernel( if (x < 0 || x >= vintrin.width || y < 0 || y >= vintrin.height) return; float d = depth_in[y*pitch4+x]; + + const float err_coef = 0.001f; //depthErrorCoef(ointrin); - // FIXME: This is dangerous, need to check through alternates instead - while (true) { + int count = 10; // Allow max 2cm of carving. + while (--count >= 0) { float3 campos = transformR * vintrin.screenToCam(x,y,d); int2 spos = ointrin.camToScreen<int2>(campos); int ox = spos.x; @@ -27,16 +33,21 @@ __global__ void reverse_check_kernel( 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; + + // TODO: Threshold comes from depth error characteristics + // If the value is significantly further then carve. Depth error + // is not always easy to calculate, depends on source. + if (!(d2 < ointrin.maxDepth && d2 - campos.z > d2*d2*err_coef)) break; d += 0.002f; } else break; } - depth_in[y*pitch4+x] = d; + // Too much carving means just outright remove the point. + depth_in[y*pitch4+x] = (count < 0) ? 0.0f : 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_X = 16; 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);