Skip to content

[GSoC] Add Submaps and PoseGraph optimization for Large Scale Depth Fusion #2619

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 45 commits into from
Oct 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
4dbdee4
Merge pull request #1 from opencv/master
akashsharma02 Mar 22, 2020
dcbe5a8
Merge remote-tracking branch 'upstream/master'
akashsharma02 May 9, 2020
a7c3ab0
Merge remote-tracking branch 'upstream/master'
akashsharma02 May 22, 2020
3fa8a3c
- Add HashTSDF class
akashsharma02 May 24, 2020
98ce3d0
Integration seems to be working, raycasting does not
akashsharma02 Jun 3, 2020
01a172c
Update integration code
akashsharma02 Jun 4, 2020
5a3f537
Integration and Raycasting fixes, (both work now)
akashsharma02 Jun 7, 2020
9b5b0ce
- Format code
akashsharma02 Jun 9, 2020
bdbafd0
Add Kinect Fusion backup file
akashsharma02 Jun 10, 2020
70b1dfb
- Add interpolation for vertices and normals (slow and unreliable!)
akashsharma02 Jun 10, 2020
fcfd6dd
Bug fix for integration and noisy odometry
akashsharma02 Jun 12, 2020
ddf5c18
- Create volume abstract class
akashsharma02 Jun 15, 2020
a00d7eb
- Add getPoints and getNormals function
akashsharma02 Jun 18, 2020
75656bd
- Add tests for hashTSDF
akashsharma02 Jun 23, 2020
776c8f8
Merge branch 'master' of https://github.com/opencv/opencv_contrib
akashsharma02 Jul 29, 2020
d5ccfde
- Use CRTP based static polymorphism to choose between CPU and GPU for
akashsharma02 Jul 4, 2020
8eaa125
Create submap and submapMgr
akashsharma02 Jul 6, 2020
362ec1a
Early draft of posegraph and submaps (Doesn't even compile)
akashsharma02 Jul 15, 2020
7264be2
Minor cleanup (no compilation)
akashsharma02 Jul 15, 2020
a96cf66
Track all submaps (no posegraph update yet)
akashsharma02 Jul 19, 2020
02fd312
Return inliers from ICP for weighting the constraints
akashsharma02 Jul 28, 2020
034970a
Add updating constraints between submaps and retain same current map
akashsharma02 Aug 1, 2020
8553212
Fix constraints creation between submaps and allow for switching between
akashsharma02 Aug 4, 2020
05db54b
- Fix bug in allocate volumeUnits
akashsharma02 Aug 4, 2020
5085884
Remove inlier calculation in fast_icp (not required)
akashsharma02 Aug 4, 2020
de7ba96
Modify readFile to allow reading other datasets easily
akashsharma02 Aug 4, 2020
963b086
- Implement posegraph update, Gauss newton is unstable
akashsharma02 Aug 8, 2020
713cdef
Implement simplified levenberg marquardt
akashsharma02 Aug 17, 2020
64dca2f
Merge branch 'master' of https://github.com/opencv/opencv_contrib int…
akashsharma02 Aug 18, 2020
bac316b
Bug fixes for Levenberg Marquardt and minor changes
akashsharma02 Aug 19, 2020
bbe56b7
minor changes
akashsharma02 Aug 19, 2020
6c0cd5c
Fixes, but Optimizer is still not well behaved
akashsharma02 Aug 22, 2020
53b149d
Working Ceres optimizer
akashsharma02 Aug 24, 2020
5ede5b1
- Reorganize IO code for samples in a separate file
akashsharma02 Aug 27, 2020
386b2ac
- Reorganize IO code for samples in a separate file
akashsharma02 Aug 27, 2020
4099a0e
Merge branch 'submap' of https://github.com/akashsharma02/opencv_cont…
akashsharma02 Aug 27, 2020
60523b6
- Add Python bindings for volume struct
akashsharma02 Aug 28, 2020
aea037a
- Remove dynafu::Params() since it is identical to kinfu::Params()
akashsharma02 Aug 31, 2020
fe01b57
Merge branch 'master' of https://github.com/akashsharma02/opencv_cont…
akashsharma02 Sep 22, 2020
9599c3a
Minor API changes
akashsharma02 Sep 22, 2020
b5051a4
Merge branch 'master' of https://github.com/opencv/opencv_contrib int…
akashsharma02 Sep 22, 2020
dfce899
Minor
akashsharma02 Sep 22, 2020
8f82ccc
Merge branch 'master' of https://github.com/opencv/opencv_contrib int…
akashsharma02 Oct 10, 2020
48ee51e
Remove CRTP for HashTSDF class
akashsharma02 Oct 10, 2020
daa800f
Bug fixes for HashTSDF integration
akashsharma02 Oct 11, 2020
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
9 changes: 9 additions & 0 deletions modules/rgbd/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,11 @@
set(the_description "RGBD algorithms")

find_package(Ceres QUIET)
ocv_define_module(rgbd opencv_core opencv_calib3d opencv_imgproc OPTIONAL opencv_viz WRAP python)
ocv_target_link_libraries(${the_module} ${CERES_LIBRARIES})

if(Ceres_FOUND)
ocv_target_compile_definitions(${the_module} PUBLIC CERES_FOUND)
else()
message(STATUS "CERES support is disabled. Ceres Solver is Required for Posegraph optimization")
endif()
1 change: 1 addition & 0 deletions modules/rgbd/include/opencv2/rgbd.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "opencv2/rgbd/depth.hpp"
#include "opencv2/rgbd/kinfu.hpp"
#include "opencv2/rgbd/dynafu.hpp"
#include "opencv2/rgbd/large_kinfu.hpp"


/** @defgroup rgbd RGB-Depth Processing
Expand Down
100 changes: 4 additions & 96 deletions modules/rgbd/include/opencv2/rgbd/dynafu.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,103 +10,11 @@
#include "opencv2/core.hpp"
#include "opencv2/core/affine.hpp"

#include "kinfu.hpp"

namespace cv {
namespace dynafu {

struct CV_EXPORTS_W Params
{
/** @brief Default parameters
A set of parameters which provides better model quality, can be very slow.
*/
CV_WRAP static Ptr<Params> defaultParams();

/** @brief Coarse parameters
A set of parameters which provides better speed, can fail to match frames
in case of rapid sensor motion.
*/
CV_WRAP static Ptr<Params> coarseParams();

/** @brief frame size in pixels */
CV_PROP_RW Size frameSize;

/** @brief camera intrinsics */
CV_PROP Matx33f intr;

/** @brief pre-scale per 1 meter for input values

Typical values are:
* 5000 per 1 meter for the 16-bit PNG files of TUM database
* 1000 per 1 meter for Kinect 2 device
* 1 per 1 meter for the 32-bit float images in the ROS bag files
*/
CV_PROP_RW float depthFactor;

/** @brief Depth sigma in meters for bilateral smooth */
CV_PROP_RW float bilateral_sigma_depth;
/** @brief Spatial sigma in pixels for bilateral smooth */
CV_PROP_RW float bilateral_sigma_spatial;
/** @brief Kernel size in pixels for bilateral smooth */
CV_PROP_RW int bilateral_kernel_size;

/** @brief Number of pyramid levels for ICP */
CV_PROP_RW int pyramidLevels;

/** @brief Resolution of voxel space

Number of voxels in each dimension.
*/
CV_PROP_RW Vec3i volumeDims;
/** @brief Size of voxel in meters */
CV_PROP_RW float voxelSize;

/** @brief Minimal camera movement in meters

Integrate new depth frame only if camera movement exceeds this value.
*/
CV_PROP_RW float tsdf_min_camera_movement;

/** @brief initial volume pose in meters */
Affine3f volumePose;

/** @brief distance to truncate in meters

Distances to surface that exceed this value will be truncated to 1.0.
*/
CV_PROP_RW float tsdf_trunc_dist;

/** @brief max number of frames per voxel

Each voxel keeps running average of distances no longer than this value.
*/
CV_PROP_RW int tsdf_max_weight;

/** @brief A length of one raycast step

How much voxel sizes we skip each raycast step
*/
CV_PROP_RW float raycast_step_factor;

// gradient delta in voxel sizes
// fixed at 1.0f
// float gradient_delta_factor;

/** @brief light pose for rendering in meters */
CV_PROP Vec3f lightPose;

/** @brief distance theshold for ICP in meters */
CV_PROP_RW float icpDistThresh;
/** angle threshold for ICP in radians */
CV_PROP_RW float icpAngleThresh;
/** number of ICP iterations for each pyramid level */
CV_PROP std::vector<int> icpIterations;

/** @brief Threshold for depth truncation in meters

All depth values beyond this threshold will be set to zero
*/
CV_PROP_RW float truncateThreshold;
};

/** @brief DynamicFusion implementation

This class implements a 3d reconstruction algorithm as described in @cite dynamicfusion.
Expand All @@ -132,11 +40,11 @@ struct CV_EXPORTS_W Params
class CV_EXPORTS_W DynaFu
{
public:
CV_WRAP static Ptr<DynaFu> create(const Ptr<Params>& _params);
CV_WRAP static Ptr<DynaFu> create(const Ptr<kinfu::Params>& _params);
virtual ~DynaFu();

/** @brief Get current parameters */
virtual const Params& getParams() const = 0;
virtual const kinfu::Params& getParams() const = 0;

/** @brief Renders a volume into an image

Expand Down
16 changes: 8 additions & 8 deletions modules/rgbd/include/opencv2/rgbd/kinfu.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,22 @@ struct CV_EXPORTS_W Params
/**
* @brief Constructor for Params
* Sets the initial pose of the TSDF volume.
* @param volumeIntialPoseRot rotation matrix
* @param volumeIntialPoseTransl translation vector
* @param volumeInitialPoseRot rotation matrix
* @param volumeInitialPoseTransl translation vector
*/
CV_WRAP Params(Matx33f volumeIntialPoseRot, Vec3f volumeIntialPoseTransl)
CV_WRAP Params(Matx33f volumeInitialPoseRot, Vec3f volumeInitialPoseTransl)
{
setInitialVolumePose(volumeIntialPoseRot,volumeIntialPoseTransl);
setInitialVolumePose(volumeInitialPoseRot,volumeInitialPoseTransl);
}

/**
* @brief Constructor for Params
* Sets the initial pose of the TSDF volume.
* @param volumeIntialPose 4 by 4 Homogeneous Transform matrix to set the intial pose of TSDF volume
* @param volumeInitialPose 4 by 4 Homogeneous Transform matrix to set the intial pose of TSDF volume
*/
CV_WRAP Params(Matx44f volumeIntialPose)
CV_WRAP Params(Matx44f volumeInitialPose)
{
setInitialVolumePose(volumeIntialPose);
setInitialVolumePose(volumeInitialPose);
}

/**
Expand Down Expand Up @@ -77,7 +77,7 @@ struct CV_EXPORTS_W Params
/** @brief frame size in pixels */
CV_PROP_RW Size frameSize;

CV_PROP_RW cv::kinfu::VolumeType volumeType;
CV_PROP_RW kinfu::VolumeType volumeType;

/** @brief camera intrinsics */
CV_PROP_RW Matx33f intr;
Expand Down
143 changes: 143 additions & 0 deletions modules/rgbd/include/opencv2/rgbd/large_kinfu.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html

// This code is also subject to the license terms in the LICENSE_KinectFusion.md file found in this
// module's directory

#ifndef __OPENCV_RGBD_LARGEKINFU_HPP__
#define __OPENCV_RGBD_LARGEKINFU_HPP__

#include <opencv2/rgbd/volume.hpp>

#include "opencv2/core.hpp"
#include "opencv2/core/affine.hpp"

namespace cv
{
namespace large_kinfu
{
struct CV_EXPORTS_W Params
{
/** @brief Default parameters
A set of parameters which provides better model quality, can be very slow.
*/
CV_WRAP static Ptr<Params> defaultParams();

/** @brief Coarse parameters
A set of parameters which provides better speed, can fail to match frames
in case of rapid sensor motion.
*/
CV_WRAP static Ptr<Params> coarseParams();

/** @brief HashTSDF parameters
A set of parameters suitable for use with HashTSDFVolume
*/
CV_WRAP static Ptr<Params> hashTSDFParams(bool isCoarse);

/** @brief frame size in pixels */
CV_PROP_RW Size frameSize;

/** @brief camera intrinsics */
CV_PROP_RW Matx33f intr;

/** @brief pre-scale per 1 meter for input values
Typical values are:
* 5000 per 1 meter for the 16-bit PNG files of TUM database
* 1000 per 1 meter for Kinect 2 device
* 1 per 1 meter for the 32-bit float images in the ROS bag files
*/
CV_PROP_RW float depthFactor;

/** @brief Depth sigma in meters for bilateral smooth */
CV_PROP_RW float bilateral_sigma_depth;
/** @brief Spatial sigma in pixels for bilateral smooth */
CV_PROP_RW float bilateral_sigma_spatial;
/** @brief Kernel size in pixels for bilateral smooth */
CV_PROP_RW int bilateral_kernel_size;

/** @brief Number of pyramid levels for ICP */
CV_PROP_RW int pyramidLevels;

/** @brief Minimal camera movement in meters
Integrate new depth frame only if camera movement exceeds this value.
*/
CV_PROP_RW float tsdf_min_camera_movement;

/** @brief light pose for rendering in meters */
CV_PROP_RW Vec3f lightPose;

/** @brief distance theshold for ICP in meters */
CV_PROP_RW float icpDistThresh;
/** @brief angle threshold for ICP in radians */
CV_PROP_RW float icpAngleThresh;
/** @brief number of ICP iterations for each pyramid level */
CV_PROP_RW std::vector<int> icpIterations;

/** @brief Threshold for depth truncation in meters
All depth values beyond this threshold will be set to zero
*/
CV_PROP_RW float truncateThreshold;

/** @brief Volume parameters
*/
kinfu::VolumeParams volumeParams;
};

/** @brief Large Scale Dense Depth Fusion implementation

This class implements a 3d reconstruction algorithm for larger environments using
Spatially hashed TSDF volume "Submaps".
It also runs a periodic posegraph optimization to minimize drift in tracking over long sequences.
Currently the algorithm does not implement a relocalization or loop closure module.
Potentially a Bag of words implementation or RGBD relocalization as described in
Glocker et al. ISMAR 2013 will be implemented

It takes a sequence of depth images taken from depth sensor
(or any depth images source such as stereo camera matching algorithm or even raymarching
renderer). The output can be obtained as a vector of points and their normals or can be
Phong-rendered from given camera pose.

An internal representation of a model is a spatially hashed voxel cube that stores TSDF values
which represent the distance to the closest surface (for details read the @cite kinectfusion article
about TSDF). There is no interface to that representation yet.

For posegraph optimization, a Submap abstraction over the Volume class is created.
New submaps are added to the model when there is low visibility overlap between current viewing frustrum
and the existing volume/model. Multiple submaps are simultaneously tracked and a posegraph is created and
optimized periodically.

LargeKinfu does not use any OpenCL acceleration yet.
To enable or disable it explicitly use cv::setUseOptimized() or cv::ocl::setUseOpenCL().

This implementation is inspired from Kintinuous, InfiniTAM and other SOTA algorithms

You need to set the OPENCV_ENABLE_NONFREE option in CMake to use KinectFusion.
*/
class CV_EXPORTS_W LargeKinfu
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Docs should be rewritten later

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have modified the docs a bit. Do let me know if there are any concerns or issues.

{
public:
CV_WRAP static Ptr<LargeKinfu> create(const Ptr<Params>& _params);
virtual ~LargeKinfu() = default;

virtual const Params& getParams() const = 0;

CV_WRAP virtual void render(OutputArray image,
const Matx44f& cameraPose = Matx44f::eye()) const = 0;

CV_WRAP virtual void getCloud(OutputArray points, OutputArray normals) const = 0;

CV_WRAP virtual void getPoints(OutputArray points) const = 0;

CV_WRAP virtual void getNormals(InputArray points, OutputArray normals) const = 0;

CV_WRAP virtual void reset() = 0;

virtual const Affine3f getPose() const = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use Matx44f instead, Affine3f has problems with Python bindings

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.


CV_WRAP virtual bool update(InputArray depth) = 0;
};

} // namespace large_kinfu
} // namespace cv
#endif
Loading