From f09f407db124c68953c83aaf223f544715a65a7b Mon Sep 17 00:00:00 2001
From: Rishabh Singh <reyanshsolis@gmail.com>
Date: Sat, 21 May 2022 14:57:06 +0530
Subject: [PATCH] Add default dataset loading in reconstruction system. (#4954)

---
 cpp/open3d/data/Dataset.cpp                   | 127 +++++++++++-
 cpp/open3d/data/Dataset.h                     |  94 ++++++++-
 cpp/open3d/t/io/sensor/RGBDVideoReader.cpp    |  10 +-
 cpp/pybind/data/data.cpp                      | 190 ++++++++++++++----
 cpp/tests/data/Dataset.cpp                    |   6 -
 docs/tutorial/data/index.rst                  |  78 +++++++
 .../reconstruction_system/integrate_scene.rst |   2 +-
 .../reconstruction_system/make_fragments.rst  |  18 +-
 .../reconstruction_system/system_overview.rst |  72 +++++--
 .../t_reconstruction_system/index.rst         |  70 +++++++
 .../t_reconstruction_system/integration.rst   |   2 +-
 examples/cpp/OfflineSLAM.cpp                  |   3 +-
 examples/cpp/OnlineSLAMRGBD.cpp               |  48 ++++-
 examples/cpp/OnlineSLAMRealSense.cpp          |   2 +-
 examples/python/open3d_example.py             |  35 ++--
 .../reconstruction_system/colored_icp.py      |  87 --------
 .../config/indoor_lidar_rgbd/apartment.json   |  14 --
 .../config/indoor_lidar_rgbd/bedroom.json     |  14 --
 .../config/indoor_lidar_rgbd/boardroom.json   |  14 --
 .../config/indoor_lidar_rgbd/lobby.json       |  14 --
 .../config/indoor_lidar_rgbd/loft.json        |  14 --
 .../config/redwood_objects/car.json           |  14 --
 .../config/redwood_objects/chair.json         |  14 --
 .../config/redwood_objects/motorcycle.json    |  14 --
 .../config/redwood_objects/plant.json         |  14 --
 .../config/redwood_objects/sofa.json          |  14 --
 .../config/redwood_objects/truck.json         |  14 --
 .../redwood_simulated/livingroom1-clean.json  |  23 ---
 .../livingroom1-simulated.json                |  15 --
 .../redwood_simulated/livingroom2-clean.json  |  14 --
 .../livingroom2-simulated.json                |  15 --
 .../redwood_simulated/office1-clean.json      |  14 --
 .../redwood_simulated/office1-simulated.json  |  15 --
 .../redwood_simulated/office2-clean.json      |  14 --
 .../redwood_simulated/office2-simulated.json  |  15 --
 .../config/stanford/burghers.json             |  14 --
 .../config/stanford/cactusgarden.json         |  14 --
 .../config/stanford/copyroom.json             |  14 --
 .../config/stanford/lounge.json               |  14 --
 .../config/stanford/stonewall.json            |  14 --
 .../config/stanford/totempole.json            |  14 --
 .../reconstruction_system/data_loader.py      |  96 +++++++++
 .../initialize_config.py                      |  53 ++++-
 .../reconstruction_system/integrate_scene.py  |   3 -
 .../reconstruction_system/make_fragments.py   |  14 +-
 .../reconstruction_system/run_system.py       |  20 +-
 .../reconstruction_system/scripts/__init__.py |   0
 .../scripts/download_dataset.py               |  90 ---------
 .../scripts/download_indoor_lidar_rgbd.sh     |  18 --
 .../scripts/download_redwood_objects.sh       |  21 --
 .../scripts/download_redwood_simulated.sh     |  48 -----
 .../scripts/download_stanford.sh              |  19 --
 .../scripts/download_tutorial.sh              |   7 -
 .../scripts/gdrive_download.sh                |  22 --
 .../scripts/requirements.txt                  |   2 -
 .../scripts/synchronize_frames.py             | 115 -----------
 .../python/t_reconstruction_system/common.py  |  91 +++++++--
 .../t_reconstruction_system/dense_slam.py     |  17 +-
 .../t_reconstruction_system/dense_slam_gui.py |  21 +-
 .../t_reconstruction_system/integrate.py      |   4 +-
 .../integrate_custom.py                       |  19 +-
 .../t_reconstruction_system/ray_casting.py    |  20 +-
 62 files changed, 941 insertions(+), 966 deletions(-)
 delete mode 100644 examples/python/reconstruction_system/colored_icp.py
 delete mode 100644 examples/python/reconstruction_system/config/indoor_lidar_rgbd/apartment.json
 delete mode 100644 examples/python/reconstruction_system/config/indoor_lidar_rgbd/bedroom.json
 delete mode 100644 examples/python/reconstruction_system/config/indoor_lidar_rgbd/boardroom.json
 delete mode 100644 examples/python/reconstruction_system/config/indoor_lidar_rgbd/lobby.json
 delete mode 100644 examples/python/reconstruction_system/config/indoor_lidar_rgbd/loft.json
 delete mode 100644 examples/python/reconstruction_system/config/redwood_objects/car.json
 delete mode 100644 examples/python/reconstruction_system/config/redwood_objects/chair.json
 delete mode 100644 examples/python/reconstruction_system/config/redwood_objects/motorcycle.json
 delete mode 100644 examples/python/reconstruction_system/config/redwood_objects/plant.json
 delete mode 100644 examples/python/reconstruction_system/config/redwood_objects/sofa.json
 delete mode 100644 examples/python/reconstruction_system/config/redwood_objects/truck.json
 delete mode 100644 examples/python/reconstruction_system/config/redwood_simulated/livingroom1-clean.json
 delete mode 100644 examples/python/reconstruction_system/config/redwood_simulated/livingroom1-simulated.json
 delete mode 100644 examples/python/reconstruction_system/config/redwood_simulated/livingroom2-clean.json
 delete mode 100644 examples/python/reconstruction_system/config/redwood_simulated/livingroom2-simulated.json
 delete mode 100644 examples/python/reconstruction_system/config/redwood_simulated/office1-clean.json
 delete mode 100644 examples/python/reconstruction_system/config/redwood_simulated/office1-simulated.json
 delete mode 100644 examples/python/reconstruction_system/config/redwood_simulated/office2-clean.json
 delete mode 100644 examples/python/reconstruction_system/config/redwood_simulated/office2-simulated.json
 delete mode 100644 examples/python/reconstruction_system/config/stanford/burghers.json
 delete mode 100644 examples/python/reconstruction_system/config/stanford/cactusgarden.json
 delete mode 100644 examples/python/reconstruction_system/config/stanford/copyroom.json
 delete mode 100644 examples/python/reconstruction_system/config/stanford/lounge.json
 delete mode 100644 examples/python/reconstruction_system/config/stanford/stonewall.json
 delete mode 100644 examples/python/reconstruction_system/config/stanford/totempole.json
 create mode 100644 examples/python/reconstruction_system/data_loader.py
 delete mode 100644 examples/python/reconstruction_system/scripts/__init__.py
 delete mode 100644 examples/python/reconstruction_system/scripts/download_dataset.py
 delete mode 100755 examples/python/reconstruction_system/scripts/download_indoor_lidar_rgbd.sh
 delete mode 100755 examples/python/reconstruction_system/scripts/download_redwood_objects.sh
 delete mode 100755 examples/python/reconstruction_system/scripts/download_redwood_simulated.sh
 delete mode 100755 examples/python/reconstruction_system/scripts/download_stanford.sh
 delete mode 100755 examples/python/reconstruction_system/scripts/download_tutorial.sh
 delete mode 100755 examples/python/reconstruction_system/scripts/gdrive_download.sh
 delete mode 100644 examples/python/reconstruction_system/scripts/requirements.txt
 delete mode 100644 examples/python/reconstruction_system/scripts/synchronize_frames.py

diff --git a/cpp/open3d/data/Dataset.cpp b/cpp/open3d/data/Dataset.cpp
index 34acfa90599..5b18b4426d8 100644
--- a/cpp/open3d/data/Dataset.cpp
+++ b/cpp/open3d/data/Dataset.cpp
@@ -61,22 +61,22 @@ Dataset::Dataset(const std::string& prefix, const std::string& data_root)
 
 SingleDownloadDataset::SingleDownloadDataset(
         const std::string& prefix,
-        const std::vector<std::string>& urls,
+        const std::vector<std::string>& url_mirrors,
         const std::string& md5,
         const bool no_extract,
         const std::string& data_root)
     : Dataset(prefix, data_root) {
     const std::string filename =
-            utility::filesystem::GetFileNameWithoutDirectory(urls[0]);
+            utility::filesystem::GetFileNameWithoutDirectory(url_mirrors[0]);
 
-    const bool is_extract_present =
+    const bool is_extract_folder_present =
             utility::filesystem::DirectoryExists(Dataset::GetExtractDir());
 
-    if (!is_extract_present) {
+    if (!is_extract_folder_present) {
         // `download_dir` is relative path from `${data_root}`.
         const std::string download_dir = "download/" + GetPrefix();
-        const std::string download_file_path =
-                utility::DownloadFromURL(urls, md5, download_dir, data_root_);
+        const std::string download_file_path = utility::DownloadFromURL(
+                url_mirrors, md5, download_dir, data_root_);
 
         // Extract / Copy data.
         if (!no_extract) {
@@ -90,6 +90,52 @@ SingleDownloadDataset::SingleDownloadDataset(
     }
 }
 
+MultiDownloadDataset::MultiDownloadDataset(
+        const std::string& prefix,
+        const std::vector<std::vector<std::string>>& url_mirrors_list,
+        const std::vector<std::string>& md5_list,
+        const bool no_extract,
+        const std::string& data_root)
+    : Dataset(prefix, data_root) {
+    std::vector<std::string> filenames;
+    for (auto& file_mirrors : url_mirrors_list) {
+        filenames.push_back(file_mirrors[0]);
+    }
+    const bool is_extract_folder_present =
+            utility::filesystem::DirectoryExists(Dataset::GetExtractDir());
+
+    if (!is_extract_folder_present) {
+        size_t number_of_files = url_mirrors_list.size();
+        if (md5_list.size() != number_of_files) {
+            utility::LogError(
+                    "md5_list and url_mirrors_list must be of same length.");
+        }
+
+        // `download_dir` is relative path from `${data_root}`.
+        const std::string download_dir = "download/" + GetPrefix();
+        std::vector<std::string> download_file_paths;
+        for (size_t i = 0; i < number_of_files; ++i) {
+            download_file_paths.push_back(
+                    utility::DownloadFromURL(url_mirrors_list[i], md5_list[i],
+                                             download_dir, data_root_));
+        }
+
+        // Extract / Copy data.
+        if (!no_extract) {
+            for (auto& download_file_path : download_file_paths) {
+                utility::Extract(download_file_path, Dataset::GetExtractDir());
+            }
+        } else {
+            utility::filesystem::MakeDirectoryHierarchy(
+                    Dataset::GetExtractDir());
+            for (auto& download_file_path : download_file_paths) {
+                utility::filesystem::Copy(download_file_path,
+                                          Dataset::GetExtractDir());
+            }
+        }
+    }
+}
+
 DemoICPPointClouds::DemoICPPointClouds(const std::string& data_root)
     : SingleDownloadDataset(
               "DemoICPPointClouds",
@@ -690,5 +736,74 @@ std::string OfficePointClouds::GetPaths(size_t index) const {
     return paths_[index];
 }
 
+LoungeRGBDImages::LoungeRGBDImages(const std::string& data_root)
+    : SingleDownloadDataset(
+              "LoungeRGBDImages",
+              {"https://github.com/isl-org/open3d_downloads/releases/download/"
+               "20220301-data/LoungeRGBDImages.zip"},
+              "cdd307caef898519a8829ce1b6ab9f75",
+              /*no_extract =*/false,
+              data_root) {
+    color_paths_.reserve(3000);
+    depth_paths_.reserve(3000);
+    const std::string extract_dir = Dataset::GetExtractDir();
+    const size_t n_zero = 6;
+    for (int i = 1; i < 3000; ++i) {
+        std::string idx = std::to_string(i);
+        idx = std::string(n_zero - std::min(n_zero, idx.length()), '0') + idx;
+        color_paths_.push_back(extract_dir + "/color/" + idx + ".png");
+        depth_paths_.push_back(extract_dir + "/depth/" + idx + ".png");
+    }
+
+    trajectory_log_path_ = extract_dir + "/lounge_trajectory.log";
+    reconstruction_path_ = extract_dir + "/lounge.ply";
+}
+
+BedroomRGBDImages::BedroomRGBDImages(const std::string& data_root)
+    : MultiDownloadDataset(
+              "BedroomRGBDImages",
+              {{"https://github.com/isl-org/open3d_downloads/releases/download/"
+                "20220301-data/bedroom01.zip"},
+               {"https://github.com/isl-org/open3d_downloads/releases/download/"
+                "20220301-data/bedroom02.zip"},
+               {"https://github.com/isl-org/open3d_downloads/releases/download/"
+                "20220301-data/bedroom03.zip"},
+               {"https://github.com/isl-org/open3d_downloads/releases/download/"
+                "20220301-data/bedroom04.zip"},
+               {"https://github.com/isl-org/open3d_downloads/releases/download/"
+                "20220301-data/bedroom05.zip"}},
+              {"2d1018ceeb72680f5d16b2f419da9bb1",
+               "5e6ffbccc0907dc5acc374aa76a79081",
+               "ebf13b89ec364b1788dd492c27b9b800",
+               "94c0e6c862a54588582b06520946fb15",
+               "54b927edb6fd61838025bc66ed767408"},
+              /*no_extract =*/false,
+              data_root) {
+    color_paths_.reserve(21931);
+    depth_paths_.reserve(21931);
+    const std::string extract_dir = Dataset::GetExtractDir();
+    const size_t n_zero = 6;
+    for (int i = 1; i < 21931; ++i) {
+        std::string idx = std::to_string(i);
+        idx = std::string(n_zero - std::min(n_zero, idx.length()), '0') + idx;
+        color_paths_.push_back(extract_dir + "/image/" + idx + ".jpg");
+        depth_paths_.push_back(extract_dir + "/depth/" + idx + ".png");
+    }
+
+    trajectory_log_path_ = extract_dir + "/bedroom.log";
+    reconstruction_path_ = extract_dir + "/bedroom.ply";
+}
+
+JackJackL515Bag::JackJackL515Bag(const std::string& data_root)
+    : SingleDownloadDataset(
+              "JackJackL515Bag",
+              {"https://github.com/isl-org/open3d_downloads/releases/download/"
+               "20220301-data/JackJackL515Bag.bag"},
+              "9f670dc92569b986b739c4179a659176",
+              /*no_extract =*/true,
+              data_root) {
+    path_ = Dataset::GetExtractDir() + "/JackJackL515Bag.bag";
+}
+
 }  // namespace data
 }  // namespace open3d
diff --git a/cpp/open3d/data/Dataset.h b/cpp/open3d/data/Dataset.h
index 7031c2cc442..f66e417aa19 100644
--- a/cpp/open3d/data/Dataset.h
+++ b/cpp/open3d/data/Dataset.h
@@ -114,7 +114,7 @@ class Dataset {
 class SingleDownloadDataset : public Dataset {
 public:
     SingleDownloadDataset(const std::string& prefix,
-                          const std::vector<std::string>& urls,
+                          const std::vector<std::string>& url_mirrors,
                           const std::string& md5,
                           const bool no_extract = false,
                           const std::string& data_root = "");
@@ -122,6 +122,21 @@ class SingleDownloadDataset : public Dataset {
     virtual ~SingleDownloadDataset() {}
 };
 
+/// \class MultiDownloadDataset
+/// \brief This class allows user to create simple dataset which includes
+/// multiple file downloading and extracting / copying.
+class MultiDownloadDataset : public Dataset {
+public:
+    MultiDownloadDataset(
+            const std::string& prefix,
+            const std::vector<std::vector<std::string>>& url_mirrors_list,
+            const std::vector<std::string>& md5_list,
+            const bool no_extract = false,
+            const std::string& data_root = "");
+
+    virtual ~MultiDownloadDataset() {}
+};
+
 /// \class DemoICPPointClouds
 /// \brief Data class for `DemoICPPointClouds` contains 3 point clouds of binary
 /// PCD format. This data is used in Open3D for ICP demo.
@@ -860,5 +875,82 @@ class OfficePointClouds : public SingleDownloadDataset {
     std::vector<std::string> paths_;
 };
 
+/// \class LoungeRGBDImages
+/// \brief Data class for `LoungeRGBDImages` contains a sample set of 3000 color
+/// and depth images from Stanford Lounge RGBD dataset. Additionally it also
+/// contains camera trajectory log, and mesh reconstruction.
+class LoungeRGBDImages : public SingleDownloadDataset {
+public:
+    LoungeRGBDImages(const std::string& data_root = "");
+
+    /// \brief Returns List of paths to color image samples of size 3000.
+    std::vector<std::string> GetColorPaths() const { return color_paths_; };
+    /// \brief Returns List of paths to depth image samples of size 3000.
+    std::vector<std::string> GetDepthPaths() const { return depth_paths_; };
+
+    /// \brief Returns path to camera trajectory log file
+    /// `lounge_trajectory.log`.
+    std::string GetTrajectoryLogPath() const { return trajectory_log_path_; };
+    /// \brief Returns path to mesh reconstruction `lounge.ply`.
+    std::string GetReconstructionPath() const { return reconstruction_path_; };
+
+private:
+    /// List of paths to color image samples of size 3000.
+    std::vector<std::string> color_paths_;
+    /// List of paths to depth image samples of size 3000.
+    std::vector<std::string> depth_paths_;
+
+    /// Path to camera trajectory log file `lounge_trajectory.log`.
+    std::string trajectory_log_path_;
+    /// Path to mesh reconstruction.
+    std::string reconstruction_path_;
+};
+
+/// \class BedroomRGBDImages
+/// \brief Data class for `BedroomRGBDImages` contains a sample set of 21931
+/// color and depth images from Redwood RGBD dataset. Additionally it also
+/// contains camera trajectory log, and mesh reconstruction.
+class BedroomRGBDImages : public MultiDownloadDataset {
+public:
+    BedroomRGBDImages(const std::string& data_root = "");
+
+    /// \brief Returns List of paths to color image samples of size 21931.
+    std::vector<std::string> GetColorPaths() const { return color_paths_; };
+    /// \brief Returns List of paths to depth image samples of size 21931.
+    std::vector<std::string> GetDepthPaths() const { return depth_paths_; };
+
+    /// \brief Returns path to camera trajectory log file
+    /// `lounge_trajectory.log`.
+    std::string GetTrajectoryLogPath() const { return trajectory_log_path_; };
+    /// \brief Returns path to mesh reconstruction `bedroom.ply`.
+    std::string GetReconstructionPath() const { return reconstruction_path_; };
+
+private:
+    /// List of paths to color image samples of size 3000.
+    std::vector<std::string> color_paths_;
+    /// List of paths to depth image samples of size 3000.
+    std::vector<std::string> depth_paths_;
+
+    /// Path to camera trajectory log file `bedroom.log`.
+    std::string trajectory_log_path_;
+    /// Path to mesh reconstruction.
+    std::string reconstruction_path_;
+};
+
+/// \class JackJackL515Bag
+/// \brief Data class for `JackJackL515Bag` contains the RealSense L515
+/// `JackJackL515Bag.bag` file.
+class JackJackL515Bag : public SingleDownloadDataset {
+public:
+    JackJackL515Bag(const std::string& data_root = "");
+
+    /// \brief Returns path to the `JackJackL515Bag.bag` file.
+    std::string GetPath() const { return path_; };
+
+private:
+    /// Path to `JackJackL515Bag.bag` file.
+    std::string path_;
+};
+
 }  // namespace data
 }  // namespace open3d
diff --git a/cpp/open3d/t/io/sensor/RGBDVideoReader.cpp b/cpp/open3d/t/io/sensor/RGBDVideoReader.cpp
index fc84ce34225..016a354648b 100644
--- a/cpp/open3d/t/io/sensor/RGBDVideoReader.cpp
+++ b/cpp/open3d/t/io/sensor/RGBDVideoReader.cpp
@@ -102,12 +102,14 @@ std::unique_ptr<RGBDVideoReader> RGBDVideoReader::Create(
         auto reader = std::make_unique<RSBagReader>();
         reader->Open(filename);
         return reader;
-    } else
-#endif
-    {
-        utility::LogError("Unsupported file format for {}", filename);
+    } else {
+        utility::LogError("Unsupported file format for {}.", filename);
     }
+#endif
+    utility::LogError(
+            "Build with -DBUILD_LIBREALSENSE=ON to use RealSense bag file.");
 }
+
 }  // namespace io
 }  // namespace t
 }  // namespace open3d
diff --git a/cpp/pybind/data/data.cpp b/cpp/pybind/data/data.cpp
index b0fa95586d2..5c8f274650d 100644
--- a/cpp/pybind/data/data.cpp
+++ b/cpp/pybind/data/data.cpp
@@ -39,10 +39,16 @@ class PyDataset : public DatasetBase {
     using DatasetBase::DatasetBase;
 };
 
-template <class SimpleDatasetBase = SingleDownloadDataset>
-class PySimpleDataset : public PyDataset<SimpleDatasetBase> {
+template <class SingleDownloadDatasetBase = SingleDownloadDataset>
+class PySingleDownloadDataset : public PyDataset<SingleDownloadDatasetBase> {
 public:
-    using PyDataset<SimpleDatasetBase>::PyDataset;
+    using PyDataset<SingleDownloadDatasetBase>::PyDataset;
+};
+
+template <class MultiDownloadDatasetBase = MultiDownloadDataset>
+class PyMultiDownloadDataset : public PyDataset<MultiDownloadDatasetBase> {
+public:
+    using PyDataset<MultiDownloadDatasetBase>::PyDataset;
 };
 
 void pybind_data_classes(py::module& m) {
@@ -71,22 +77,39 @@ void pybind_data_classes(py::module& m) {
     docstring::ClassMethodDocInject(m, "Dataset", "extract_dir");
 
     // open3d.data.SingleDownloadDataset
-    py::class_<SingleDownloadDataset, PySimpleDataset<SingleDownloadDataset>,
+    py::class_<SingleDownloadDataset,
+               PySingleDownloadDataset<SingleDownloadDataset>,
                std::shared_ptr<SingleDownloadDataset>, Dataset>
             single_download_dataset(m, "SingleDownloadDataset",
                                     "Single file download dataset class.");
     single_download_dataset.def(
             py::init<const std::string&, const std::vector<std::string>&,
                      const std::string&, const bool, const std::string&>(),
-            "prefix"_a, "urls"_a, "md5"_a, "no_extract"_a = false,
+            "prefix"_a, "url_mirrors"_a, "md5"_a, "no_extract"_a = false,
             "data_root"_a = "",
             "This class allows user to create simple dataset which includes "
             "single file downloading and extracting / copying.");
+
+    // open3d.data.MultiDownloadDataset
+    py::class_<MultiDownloadDataset,
+               PyMultiDownloadDataset<MultiDownloadDataset>,
+               std::shared_ptr<MultiDownloadDataset>, Dataset>
+            multi_download_dataset(m, "MultiDownloadDataset",
+                                   "Multiple files download dataset class.");
+    multi_download_dataset.def(
+            py::init<const std::string&,
+                     const std::vector<std::vector<std::string>>&,
+                     const std::vector<std::string>&, const bool,
+                     const std::string&>(),
+            "prefix"_a, "url_mirrors_list"_a, "md5_list"_a,
+            "no_extract"_a = false, "data_root"_a = "",
+            "This class allows user to create simple dataset which includes "
+            "multiple files downloading and extracting / copying.");
 }
 
 void pybind_demo_icp_pointclouds(py::module& m) {
     // open3d.data.DemoICPPointClouds
-    py::class_<DemoICPPointClouds, PySimpleDataset<DemoICPPointClouds>,
+    py::class_<DemoICPPointClouds, PySingleDownloadDataset<DemoICPPointClouds>,
                std::shared_ptr<DemoICPPointClouds>, SingleDownloadDataset>
             demo_icp_pointclouds(m, "DemoICPPointClouds",
                                  "Data class for `DemoICPPointClouds` contains "
@@ -113,7 +136,7 @@ void pybind_demo_icp_pointclouds(py::module& m) {
 void pybind_demo_colored_icp_pointclouds(py::module& m) {
     // open3d.data.DemoColoredICPPointClouds
     py::class_<DemoColoredICPPointClouds,
-               PySimpleDataset<DemoColoredICPPointClouds>,
+               PySingleDownloadDataset<DemoColoredICPPointClouds>,
                std::shared_ptr<DemoColoredICPPointClouds>,
                SingleDownloadDataset>
             demo_colored_icp_pointclouds(
@@ -136,7 +159,7 @@ void pybind_demo_colored_icp_pointclouds(py::module& m) {
 
 void pybind_demo_crop_pointcloud(py::module& m) {
     // open3d.data.DemoCropPointCloud
-    py::class_<DemoCropPointCloud, PySimpleDataset<DemoCropPointCloud>,
+    py::class_<DemoCropPointCloud, PySingleDownloadDataset<DemoCropPointCloud>,
                std::shared_ptr<DemoCropPointCloud>, SingleDownloadDataset>
             demo_crop_pointcloud(
                     m, "DemoCropPointCloud",
@@ -161,7 +184,7 @@ void pybind_demo_crop_pointcloud(py::module& m) {
 void pybind_demo_feature_matching_point_clouds(py::module& m) {
     // open3d.data.DemoFeatureMatchingPointClouds
     py::class_<DemoFeatureMatchingPointClouds,
-               PySimpleDataset<DemoFeatureMatchingPointClouds>,
+               PySingleDownloadDataset<DemoFeatureMatchingPointClouds>,
                std::shared_ptr<DemoFeatureMatchingPointClouds>,
                SingleDownloadDataset>
             demo_feature_matching(
@@ -200,7 +223,7 @@ void pybind_demo_feature_matching_point_clouds(py::module& m) {
 void pybind_demo_pose_graph_optimization(py::module& m) {
     // open3d.data.DemoPoseGraphOptimization
     py::class_<DemoPoseGraphOptimization,
-               PySimpleDataset<DemoPoseGraphOptimization>,
+               PySingleDownloadDataset<DemoPoseGraphOptimization>,
                std::shared_ptr<DemoPoseGraphOptimization>,
                SingleDownloadDataset>
             demo_pose_graph_optimization(
@@ -228,7 +251,7 @@ void pybind_demo_pose_graph_optimization(py::module& m) {
 void pybind_demo_custom_visualization(py::module& m) {
     // open3d.data.DemoCustomVisualization
     py::class_<DemoCustomVisualization,
-               PySimpleDataset<DemoCustomVisualization>,
+               PySingleDownloadDataset<DemoCustomVisualization>,
                std::shared_ptr<DemoCustomVisualization>, SingleDownloadDataset>
             demo_custom_visualization(
                     m, "DemoCustomVisualization",
@@ -260,7 +283,7 @@ void pybind_demo_custom_visualization(py::module& m) {
 
 void pybind_pcd_point_cloud(py::module& m) {
     // open3d.data.PCDPointCloud
-    py::class_<PCDPointCloud, PySimpleDataset<PCDPointCloud>,
+    py::class_<PCDPointCloud, PySingleDownloadDataset<PCDPointCloud>,
                std::shared_ptr<PCDPointCloud>, SingleDownloadDataset>
             pcd_pointcloud(m, "PCDPointCloud",
                            "Data class for `PCDPointCloud` contains the "
@@ -274,7 +297,7 @@ void pybind_pcd_point_cloud(py::module& m) {
 
 void pybind_ply_point_cloud(py::module& m) {
     // open3d.data.PLYPointCloud
-    py::class_<PLYPointCloud, PySimpleDataset<PLYPointCloud>,
+    py::class_<PLYPointCloud, PySingleDownloadDataset<PLYPointCloud>,
                std::shared_ptr<PLYPointCloud>, SingleDownloadDataset>
             ply_pointcloud(m, "PLYPointCloud",
                            "Data class for `PLYPointCloud` contains the "
@@ -288,7 +311,7 @@ void pybind_ply_point_cloud(py::module& m) {
 
 void pybind_pts_point_cloud(py::module& m) {
     // open3d.data.PTSPointCloud
-    py::class_<PTSPointCloud, PySimpleDataset<PTSPointCloud>,
+    py::class_<PTSPointCloud, PySingleDownloadDataset<PTSPointCloud>,
                std::shared_ptr<PTSPointCloud>, SingleDownloadDataset>
             pts_point_cloud(m, "PTSPointCloud",
                             "Data class for `PTSPointCloud` contains a sample "
@@ -301,7 +324,7 @@ void pybind_pts_point_cloud(py::module& m) {
 
 void pybind_sample_nyu_rgbd_image(py::module& m) {
     // open3d.data.SampleNYURGBDImage
-    py::class_<SampleNYURGBDImage, PySimpleDataset<SampleNYURGBDImage>,
+    py::class_<SampleNYURGBDImage, PySingleDownloadDataset<SampleNYURGBDImage>,
                std::shared_ptr<SampleNYURGBDImage>, SingleDownloadDataset>
             rgbd_image_nyu(m, "SampleNYURGBDImage",
                            "Data class for `SampleNYURGBDImage` contains a "
@@ -320,7 +343,7 @@ void pybind_sample_nyu_rgbd_image(py::module& m) {
 
 void pybind_sample_sun_rgbd_image(py::module& m) {
     // open3d.data.SampleSUNRGBDImage
-    py::class_<SampleSUNRGBDImage, PySimpleDataset<SampleSUNRGBDImage>,
+    py::class_<SampleSUNRGBDImage, PySingleDownloadDataset<SampleSUNRGBDImage>,
                std::shared_ptr<SampleSUNRGBDImage>, SingleDownloadDataset>
             rgbd_image_sun(m, "SampleSUNRGBDImage",
                            "Data class for `SampleSUNRGBDImage` contains a "
@@ -339,7 +362,7 @@ void pybind_sample_sun_rgbd_image(py::module& m) {
 
 void pybind_sample_tum_rgbd_image(py::module& m) {
     // open3d.data.SampleTUMRGBDImage
-    py::class_<SampleTUMRGBDImage, PySimpleDataset<SampleTUMRGBDImage>,
+    py::class_<SampleTUMRGBDImage, PySingleDownloadDataset<SampleTUMRGBDImage>,
                std::shared_ptr<SampleTUMRGBDImage>, SingleDownloadDataset>
             rgbd_image_tum(m, "SampleTUMRGBDImage",
                            "Data class for `SampleTUMRGBDImage` contains a "
@@ -359,7 +382,7 @@ void pybind_sample_tum_rgbd_image(py::module& m) {
 void pybind_sample_redwood_rgbd_images(py::module& m) {
     // open3d.data.SampleRedwoodRGBDImages
     py::class_<SampleRedwoodRGBDImages,
-               PySimpleDataset<SampleRedwoodRGBDImages>,
+               PySingleDownloadDataset<SampleRedwoodRGBDImages>,
                std::shared_ptr<SampleRedwoodRGBDImages>, SingleDownloadDataset>
             rgbd_dataset_redwood(
                     m, "SampleRedwoodRGBDImages",
@@ -418,7 +441,7 @@ void pybind_sample_redwood_rgbd_images(py::module& m) {
 void pybind_sample_fountain_rgbd_images(py::module& m) {
     // open3d.data.SampleFountainRGBDImages
     py::class_<SampleFountainRGBDImages,
-               PySimpleDataset<SampleFountainRGBDImages>,
+               PySingleDownloadDataset<SampleFountainRGBDImages>,
                std::shared_ptr<SampleFountainRGBDImages>, SingleDownloadDataset>
             fountain_rgbd_dataset(
                     m, "SampleFountainRGBDImages",
@@ -459,7 +482,7 @@ void pybind_sample_fountain_rgbd_images(py::module& m) {
 
 void pybind_sample_l515_bag(py::module& m) {
     // open3d.data.SampleL515Bag
-    py::class_<SampleL515Bag, PySimpleDataset<SampleL515Bag>,
+    py::class_<SampleL515Bag, PySingleDownloadDataset<SampleL515Bag>,
                std::shared_ptr<SampleL515Bag>, SingleDownloadDataset>
             sample_l515_bag(m, "SampleL515Bag",
                             "Data class for `SampleL515Bag` contains the "
@@ -472,7 +495,7 @@ void pybind_sample_l515_bag(py::module& m) {
 
 void pybind_eagle(py::module& m) {
     // open3d.data.EaglePointCloud
-    py::class_<EaglePointCloud, PySimpleDataset<EaglePointCloud>,
+    py::class_<EaglePointCloud, PySingleDownloadDataset<EaglePointCloud>,
                std::shared_ptr<EaglePointCloud>, SingleDownloadDataset>
             eagle(m, "EaglePointCloud",
                   "Data class for `EaglePointCloud` contains the "
@@ -485,7 +508,7 @@ void pybind_eagle(py::module& m) {
 
 void pybind_armadillo(py::module& m) {
     // open3d.data.ArmadilloMesh
-    py::class_<ArmadilloMesh, PySimpleDataset<ArmadilloMesh>,
+    py::class_<ArmadilloMesh, PySingleDownloadDataset<ArmadilloMesh>,
                std::shared_ptr<ArmadilloMesh>, SingleDownloadDataset>
             armadillo(m, "ArmadilloMesh",
                       "Data class for `ArmadilloMesh` contains the "
@@ -499,7 +522,7 @@ void pybind_armadillo(py::module& m) {
 
 void pybind_bunny(py::module& m) {
     // open3d.data.BunnyMesh
-    py::class_<BunnyMesh, PySimpleDataset<BunnyMesh>,
+    py::class_<BunnyMesh, PySingleDownloadDataset<BunnyMesh>,
                std::shared_ptr<BunnyMesh>, SingleDownloadDataset>
             bunny(m, "BunnyMesh",
                   "Data class for `BunnyMesh` contains the `BunnyMesh.ply` "
@@ -513,8 +536,8 @@ void pybind_bunny(py::module& m) {
 
 void pybind_knot(py::module& m) {
     // open3d.data.KnotMesh
-    py::class_<KnotMesh, PySimpleDataset<KnotMesh>, std::shared_ptr<KnotMesh>,
-               SingleDownloadDataset>
+    py::class_<KnotMesh, PySingleDownloadDataset<KnotMesh>,
+               std::shared_ptr<KnotMesh>, SingleDownloadDataset>
             knot(m, "KnotMesh",
                  "Data class for `KnotMesh` contains the `KnotMesh.ply`.");
     knot.def(py::init<const std::string&>(), "data_root"_a = "")
@@ -525,7 +548,7 @@ void pybind_knot(py::module& m) {
 
 void pybind_monkey(py::module& m) {
     // open3d.data.MonkeyModel
-    py::class_<MonkeyModel, PySimpleDataset<MonkeyModel>,
+    py::class_<MonkeyModel, PySingleDownloadDataset<MonkeyModel>,
                std::shared_ptr<MonkeyModel>, SingleDownloadDataset>
             monkey(m, "MonkeyModel",
                    "Data class for `MonkeyModel` contains a monkey model file, "
@@ -547,7 +570,7 @@ void pybind_monkey(py::module& m) {
 
 void pybind_sword(py::module& m) {
     // open3d.data.SwordModel
-    py::class_<SwordModel, PySimpleDataset<SwordModel>,
+    py::class_<SwordModel, PySingleDownloadDataset<SwordModel>,
                std::shared_ptr<SwordModel>, SingleDownloadDataset>
             sword(m, "SwordModel",
                   "Data class for `SwordModel` contains a monkey model file, "
@@ -569,7 +592,7 @@ void pybind_sword(py::module& m) {
 
 void pybind_crate(py::module& m) {
     // open3d.data.CrateModel
-    py::class_<CrateModel, PySimpleDataset<CrateModel>,
+    py::class_<CrateModel, PySingleDownloadDataset<CrateModel>,
                std::shared_ptr<CrateModel>, SingleDownloadDataset>
             crate(m, "CrateModel",
                   "Data class for `CrateModel` contains a crate model file, "
@@ -591,7 +614,7 @@ void pybind_crate(py::module& m) {
 
 void pybind_helmet(py::module& m) {
     // open3d.data.FlightHelmetModel
-    py::class_<FlightHelmetModel, PySimpleDataset<FlightHelmetModel>,
+    py::class_<FlightHelmetModel, PySingleDownloadDataset<FlightHelmetModel>,
                std::shared_ptr<FlightHelmetModel>, SingleDownloadDataset>
             helmet(m, "FlightHelmetModel",
                    "Data class for `FlightHelmetModel` contains a flight "
@@ -615,7 +638,7 @@ void pybind_helmet(py::module& m) {
 
 void pybind_metal_texture(py::module& m) {
     // open3d.data.MetalTexture
-    py::class_<MetalTexture, PySimpleDataset<MetalTexture>,
+    py::class_<MetalTexture, PySingleDownloadDataset<MetalTexture>,
                std::shared_ptr<MetalTexture>, SingleDownloadDataset>
             metal_texture(m, "MetalTexture",
                           "Data class for `MetalTexture` contains albedo, "
@@ -646,7 +669,8 @@ void pybind_metal_texture(py::module& m) {
 
 void pybind_painted_plaster_texture(py::module& m) {
     // open3d.data.PaintedPlasterTexture
-    py::class_<PaintedPlasterTexture, PySimpleDataset<PaintedPlasterTexture>,
+    py::class_<PaintedPlasterTexture,
+               PySingleDownloadDataset<PaintedPlasterTexture>,
                std::shared_ptr<PaintedPlasterTexture>, SingleDownloadDataset>
             painted_plaster_texture(
                     m, "PaintedPlasterTexture",
@@ -679,7 +703,7 @@ void pybind_painted_plaster_texture(py::module& m) {
 
 void pybind_tiles_texture(py::module& m) {
     // open3d.data.TilesTexture
-    py::class_<TilesTexture, PySimpleDataset<TilesTexture>,
+    py::class_<TilesTexture, PySingleDownloadDataset<TilesTexture>,
                std::shared_ptr<TilesTexture>, SingleDownloadDataset>
             tiles_texture(
                     m, "TilesTexture",
@@ -706,7 +730,7 @@ void pybind_tiles_texture(py::module& m) {
 
 void pybind_terrazzo_texture(py::module& m) {
     // open3d.data.TerrazzoTexture
-    py::class_<TerrazzoTexture, PySimpleDataset<TerrazzoTexture>,
+    py::class_<TerrazzoTexture, PySingleDownloadDataset<TerrazzoTexture>,
                std::shared_ptr<TerrazzoTexture>, SingleDownloadDataset>
             terrazzo_texture(
                     m, "TerrazzoTexture",
@@ -735,7 +759,7 @@ void pybind_terrazzo_texture(py::module& m) {
 
 void pybind_wood_texture(py::module& m) {
     // open3d.data.WoodTexture
-    py::class_<WoodTexture, PySimpleDataset<WoodTexture>,
+    py::class_<WoodTexture, PySingleDownloadDataset<WoodTexture>,
                std::shared_ptr<WoodTexture>, SingleDownloadDataset>
             wood_texture(
                     m, "WoodTexture",
@@ -761,7 +785,7 @@ void pybind_wood_texture(py::module& m) {
 
 void pybind_wood_floor_texture(py::module& m) {
     // open3d.data.WoodFloorTexture
-    py::class_<WoodFloorTexture, PySimpleDataset<WoodFloorTexture>,
+    py::class_<WoodFloorTexture, PySingleDownloadDataset<WoodFloorTexture>,
                std::shared_ptr<WoodFloorTexture>, SingleDownloadDataset>
             wood_floor_texture(m, "WoodFloorTexture",
                                " Data class for `WoodFloorTexture` contains "
@@ -790,7 +814,7 @@ void pybind_wood_floor_texture(py::module& m) {
 
 void pybind_juneau(py::module& m) {
     // open3d.data.JuneauImage
-    py::class_<JuneauImage, PySimpleDataset<JuneauImage>,
+    py::class_<JuneauImage, PySingleDownloadDataset<JuneauImage>,
                std::shared_ptr<JuneauImage>, SingleDownloadDataset>
             juneau(m, "JuneauImage",
                    "Data class for `JuneauImage` contains the "
@@ -804,7 +828,8 @@ void pybind_juneau(py::module& m) {
 
 void pybind_living_room_point_clouds(py::module& m) {
     // open3d.data.LivingRoomPointClouds
-    py::class_<LivingRoomPointClouds, PySimpleDataset<LivingRoomPointClouds>,
+    py::class_<LivingRoomPointClouds,
+               PySingleDownloadDataset<LivingRoomPointClouds>,
                std::shared_ptr<LivingRoomPointClouds>, SingleDownloadDataset>
             living_room_point_clouds(
                     m, "LivingRoomPointClouds",
@@ -825,7 +850,7 @@ void pybind_living_room_point_clouds(py::module& m) {
 
 void pybind_office_point_clouds(py::module& m) {
     // open3d.data.OfficePointClouds
-    py::class_<OfficePointClouds, PySimpleDataset<OfficePointClouds>,
+    py::class_<OfficePointClouds, PySingleDownloadDataset<OfficePointClouds>,
                std::shared_ptr<OfficePointClouds>, SingleDownloadDataset>
             office_point_clouds(
                     m, "OfficePointClouds",
@@ -843,6 +868,92 @@ void pybind_office_point_clouds(py::module& m) {
     docstring::ClassMethodDocInject(m, "OfficePointClouds", "paths");
 }
 
+void pybind_lounge_rgbd_images(py::module& m) {
+    // open3d.data.LoungeRGBDImages
+    py::class_<LoungeRGBDImages, PySingleDownloadDataset<LoungeRGBDImages>,
+               std::shared_ptr<LoungeRGBDImages>, SingleDownloadDataset>
+            lounge_rgbd_images(
+                    m, "LoungeRGBDImages",
+                    "Data class for `LoungeRGBDImages` contains a sample set "
+                    "of 3000 color and depth images from Stanford Lounge RGBD "
+                    "dataset. Additionally it also contains camera trajectory "
+                    "log, and mesh reconstruction.");
+    lounge_rgbd_images.def(py::init<const std::string&>(), "data_root"_a = "")
+            .def_property_readonly(
+                    "color_paths", &LoungeRGBDImages::GetColorPaths,
+                    "List of paths to color image samples of size 3000. Use "
+                    "`color_paths[0]`, `color_paths[1]` ... "
+                    "`color_paths[2999]` to access the paths.")
+            .def_property_readonly(
+                    "depth_paths", &LoungeRGBDImages::GetDepthPaths,
+                    "List of paths to depth image samples of size 3000. Use "
+                    "`depth_paths[0]`, `depth_paths[1]` ... "
+                    "`depth_paths[2999]` to access the paths.")
+            .def_property_readonly(
+                    "trajectory_log_path",
+                    &LoungeRGBDImages::GetTrajectoryLogPath,
+                    "Path to camera trajectory log file `trajectory.log`.")
+            .def_property_readonly("reconstruction_path",
+                                   &LoungeRGBDImages::GetReconstructionPath,
+                                   "Path to mesh reconstruction.");
+    docstring::ClassMethodDocInject(m, "LoungeRGBDImages", "color_paths");
+    docstring::ClassMethodDocInject(m, "LoungeRGBDImages", "depth_paths");
+    docstring::ClassMethodDocInject(m, "LoungeRGBDImages",
+                                    "trajectory_log_path");
+    docstring::ClassMethodDocInject(m, "LoungeRGBDImages",
+                                    "reconstruction_path");
+}
+
+void pybind_bedroom_rgbd_images(py::module& m) {
+    // open3d.data.BedroomRGBDImages
+    py::class_<BedroomRGBDImages, PyMultiDownloadDataset<BedroomRGBDImages>,
+               std::shared_ptr<BedroomRGBDImages>, MultiDownloadDataset>
+            lounge_rgbd_images(
+                    m, "BedroomRGBDImages",
+                    "Data class for `BedroomRGBDImages` contains a sample set "
+                    "of 21931 color and depth images from Redwood Bedroom RGBD "
+                    "dataset. Additionally it also contains camera trajectory "
+                    "log, and mesh reconstruction.");
+    lounge_rgbd_images.def(py::init<const std::string&>(), "data_root"_a = "")
+            .def_property_readonly("color_paths",
+                                   &BedroomRGBDImages::GetColorPaths,
+                                   "List of paths to color image samples of "
+                                   "size 21931. Use `color_paths[0]`, "
+                                   "`color_paths[1]` ... `color_paths[21930]` "
+                                   "to access the paths.")
+            .def_property_readonly(
+                    "depth_paths", &BedroomRGBDImages::GetDepthPaths,
+                    "List of paths to depth image samples of size 21931. Use "
+                    "`depth_paths[0]`, `depth_paths[1]` ... "
+                    "`depth_paths[21930]` to access the paths.")
+            .def_property_readonly(
+                    "trajectory_log_path",
+                    &BedroomRGBDImages::GetTrajectoryLogPath,
+                    "Path to camera trajectory log file `trajectory.log`.")
+            .def_property_readonly("reconstruction_path",
+                                   &BedroomRGBDImages::GetReconstructionPath,
+                                   "Path to mesh reconstruction.");
+    docstring::ClassMethodDocInject(m, "BedroomRGBDImages", "color_paths");
+    docstring::ClassMethodDocInject(m, "BedroomRGBDImages", "depth_paths");
+    docstring::ClassMethodDocInject(m, "BedroomRGBDImages",
+                                    "trajectory_log_path");
+    docstring::ClassMethodDocInject(m, "BedroomRGBDImages",
+                                    "reconstruction_path");
+}
+
+void pybind_jackjack_l515_bag(py::module& m) {
+    // open3d.data.JackJackL515Bag
+    py::class_<JackJackL515Bag, PySingleDownloadDataset<JackJackL515Bag>,
+               std::shared_ptr<JackJackL515Bag>, SingleDownloadDataset>
+            jackjack_l515_bag(m, "JackJackL515Bag",
+                              "Data class for `SampleL515Bag` contains the "
+                              "`JackJackL515Bag.bag` file.");
+    jackjack_l515_bag.def(py::init<const std::string&>(), "data_root"_a = "")
+            .def_property_readonly("path", &JackJackL515Bag::GetPath,
+                                   "Path to the `JackJackL515Bag.bag` file.");
+    docstring::ClassMethodDocInject(m, "JackJackL515Bag", "path");
+}
+
 void pybind_data(py::module& m) {
     py::module m_submodule = m.def_submodule("data", "Data handling module.");
     pybind_data_classes(m_submodule);
@@ -887,6 +998,9 @@ void pybind_data(py::module& m) {
     // Point Cloud fragments data.
     pybind_living_room_point_clouds(m_submodule);
     pybind_office_point_clouds(m_submodule);
+    pybind_lounge_rgbd_images(m_submodule);
+    pybind_bedroom_rgbd_images(m_submodule);
+    pybind_jackjack_l515_bag(m_submodule);
 }
 
 }  // namespace data
diff --git a/cpp/tests/data/Dataset.cpp b/cpp/tests/data/Dataset.cpp
index 483b21be2dd..0c7ee44048e 100644
--- a/cpp/tests/data/Dataset.cpp
+++ b/cpp/tests/data/Dataset.cpp
@@ -997,12 +997,6 @@ TEST(Dataset, DISABLED_RedwoodOfficePointClouds) {
         EXPECT_TRUE(utility::filesystem::FileExists(dataset.GetPaths(i)));
     }
 
-    EXPECT_EQ(dataset.GetPaths(), paths);
-    for (size_t i = 0; i < paths.size(); ++i) {
-        EXPECT_EQ(dataset.GetPaths(i), paths[i]);
-        EXPECT_TRUE(utility::filesystem::FileExists(dataset.GetPaths(i)));
-    }
-
     EXPECT_EQ(dataset.GetPrefix(), prefix);
     EXPECT_EQ(dataset.GetDataRoot(), data_root);
     EXPECT_EQ(dataset.GetDownloadDir(), download_dir);
diff --git a/docs/tutorial/data/index.rst b/docs/tutorial/data/index.rst
index f4aba5f20ad..aa9dd025d53 100644
--- a/docs/tutorial/data/index.rst
+++ b/docs/tutorial/data/index.rst
@@ -586,6 +586,84 @@ RGBD dataset.
     auto rgbd_image = geometry::RGBDImage::CreateFromTUMFormat(
         *color_raw, *depth_raw, /*convert_rgb_to_intensity =*/ false);
 
+LoungeRGBDImages
+------------------
+
+Lounge RGBD dataset from Stanford containing ``color`` and ``depth`` 
+sequence of 3000 images, along with ``camera trajectory`` and ``reconstruction``.
+
+.. code-block:: python
+
+    dataset = o3d.data.LoungeRGBDImages()
+
+    rgbd_images = []
+    for i in range(len(dataset.depth_paths)):
+        color_raw = o3d.io.read_image(dataset.color_paths[i])
+        depth_raw = o3d.io.read_image(dataset.depth_paths[i])
+        rgbd_image = o3d.geometry.RGBDImage.create_from_color_and_depth(
+                                                   color_raw, depth_raw)
+        rgbd_images.append(rgbd_image)
+
+    mesh = o3d.io.read_triangle_mesh(dataset.reconstruction_path)
+
+.. code-block:: cpp
+
+    data::LoungeRGBDImages dataset;
+
+    std::vector<std::shared_ptr<geometry::RGBDImage>> rgbd_images;
+    for(size_t i = 0; i < dataset.GetDepthPaths().size(); ++i) {
+        auto color_raw = io::CreateImageFromFile(dataset.GetColorPaths()[i]);
+        auto depth_raw = io::CreateImageFromFile(dataset.GetDepthPaths()[i]);
+
+        auto rgbd_image = geometry::RGBDImage::CreateFromColorAndDepth(
+                *color_raw, *depth_raw,
+                /*depth_scale =*/1000.0,
+                /*depth_trunc =*/3.0,
+                /*convert_rgb_to_intensity =*/false);
+        rgbd_images.push_back(rgbd_image);
+    }
+
+    auto mesh = io::CreateTriangleMeshFromFile(dataset.GetReconstructionPath());
+
+BedroomRGBDImages
+------------------
+
+Bedroom RGBD dataset from Redwood containing ``color`` and ``depth`` 
+sequence of 21931 images, along with ``camera trajectory`` and ``reconstruction``.
+
+.. code-block:: python
+
+    dataset = o3d.data.BedroomRGBDImages()
+
+    rgbd_images = []
+    for i in range(len(dataset.depth_paths)):
+        color_raw = o3d.io.read_image(dataset.color_paths[i])
+        depth_raw = o3d.io.read_image(dataset.depth_paths[i])
+        rgbd_image = o3d.geometry.RGBDImage.create_from_color_and_depth(
+                                                   color_raw, depth_raw)
+        rgbd_images.append(rgbd_image)
+
+    mesh = o3d.io.read_triangle_mesh(dataset.reconstruction_path)
+
+.. code-block:: cpp
+
+    data::BedroomRGBDImages dataset;
+
+    std::vector<std::shared_ptr<geometry::RGBDImage>> rgbd_images;
+    for(size_t i = 0; i < dataset.GetDepthPaths().size(); ++i) {
+        auto color_raw = io::CreateImageFromFile(dataset.GetColorPaths()[i]);
+        auto depth_raw = io::CreateImageFromFile(dataset.GetDepthPaths()[i]);
+
+        auto rgbd_image = geometry::RGBDImage::CreateFromColorAndDepth(
+                *color_raw, *depth_raw,
+                /*depth_scale =*/1000.0,
+                /*depth_trunc =*/3.0,
+                /*convert_rgb_to_intensity =*/false);
+        rgbd_images.push_back(rgbd_image);
+    }
+
+    auto mesh = io::CreateTriangleMeshFromFile(dataset.GetReconstructionPath());
+
 Demo
 ~~~~
 
diff --git a/docs/tutorial/reconstruction_system/integrate_scene.rst b/docs/tutorial/reconstruction_system/integrate_scene.rst
index 328d7f47055..4a56b188ab3 100644
--- a/docs/tutorial/reconstruction_system/integrate_scene.rst
+++ b/docs/tutorial/reconstruction_system/integrate_scene.rst
@@ -22,7 +22,7 @@ Integrate RGBD frames
 .. literalinclude:: ../../../examples/python/reconstruction_system/integrate_scene.py
    :language: python
    :lineno-start: 38
-   :lines: 27,39-75
+   :lines: 27,40-72
    :linenos:
 
 This function first reads the alignment results from both
diff --git a/docs/tutorial/reconstruction_system/make_fragments.rst b/docs/tutorial/reconstruction_system/make_fragments.rst
index 6df2578abda..2485bfad2b3 100644
--- a/docs/tutorial/reconstruction_system/make_fragments.rst
+++ b/docs/tutorial/reconstruction_system/make_fragments.rst
@@ -25,8 +25,8 @@ Register RGBD image pairs
 
 .. literalinclude:: ../../../examples/python/reconstruction_system/make_fragments.py
    :language: python
-   :lineno-start: 58
-   :lines: 27,59-88
+   :lineno-start: 46
+   :lines: 27,47-76
    :linenos:
 
 The function reads a pair of RGBD images and registers the ``source_rgbd_image``
@@ -45,8 +45,8 @@ Multiway registration
 
 .. literalinclude:: ../../../examples/python/reconstruction_system/make_fragments.py
    :language: python
-   :lineno-start: 88
-   :lines: 27,89-136
+   :lineno-start: 76
+   :lines: 27,77-123
    :linenos:
 
 This script uses the technique demonstrated in
@@ -62,7 +62,7 @@ function ``optimize_posegraph_for_fragment``.
 .. literalinclude:: ../../../examples/python/reconstruction_system/optimize_posegraph.py
    :language: python
    :lineno-start: 51
-   :lines: 27,52-64
+   :lines: 27,52-63
    :linenos:
 
 This function calls ``global_optimization`` to estimate poses of the RGBD images.
@@ -74,8 +74,8 @@ Make a fragment
 
 .. literalinclude:: ../../../examples/python/reconstruction_system/make_fragments.py
    :language: python
-   :lineno-start: 136
-   :lines: 27,137-158
+   :lineno-start: 124
+   :lines: 27,125-146
    :linenos:
 
 Once the poses are estimates, :ref:`/tutorial/pipelines/rgbd_integration.ipynb`
@@ -86,8 +86,8 @@ Batch processing
 
 .. literalinclude:: ../../../examples/python/reconstruction_system/make_fragments.py
    :language: python
-   :lineno-start: 193
-   :lines: 27,194-217
+   :lineno-start: 181
+   :lines: 27,182-205
    :linenos:
 
 The main function calls each individual function explained above.
diff --git a/docs/tutorial/reconstruction_system/system_overview.rst b/docs/tutorial/reconstruction_system/system_overview.rst
index 3aa76cd16f9..2cae7ed387e 100644
--- a/docs/tutorial/reconstruction_system/system_overview.rst
+++ b/docs/tutorial/reconstruction_system/system_overview.rst
@@ -32,38 +32,66 @@ the scene. This part uses :ref:`/tutorial/pipelines/rgbd_integration.ipynb`.
 Example dataset
 ``````````````````````````````````````
 
-We use `the SceneNN dataset <http://people.sutd.edu.sg/~saikit/projects/sceneNN/>`_
-to demonstrate the system in this tutorial. Alternatively, there are lots of
-excellent RGBD datasets such as `Redwood data <http://redwood-data.org/>`_,
-`TUM RGBD data <https://vision.in.tum.de/data/datasets/rgbd-dataset>`_,
-`ICL-NUIM data <https://www.doc.ic.ac.uk/~ahanda/VaFRIC/iclnuim.html>`_, and
-`SUN3D data <http://sun3d.cs.princeton.edu/>`_.
-
-The tutorial uses sequence ``016`` from the SceneNN dataset. This is a
-`quick link <https://drive.google.com/open?id=11U8jEDYKvB5lXsK3L1rQcGTjp0YmRrzT>`_
-to download the RGBD sequence used in this tutorial. Alternatively, you can
-download the original dataset from
-`SceneNN oni file archive <https://drive.google.com/drive/folders/0B-aa7y5Ox4eZUmhJdmlYc3BQSG8>`_,
-and then extract the ``oni`` file into color and depth image sequence using
-`OniParser from the Redwood reconstruction system <http://redwood-data.org/indoor/tutorial.html>`_
-or other conversion tools. Some helper scripts can be found from
-``reconstruction_system/scripts``.
+We provide default datasets such as Lounge RGB-D dataset from Stanford, Bedroom RGB-D dataset from Redwood,
+Jack Jack RealSense L515 bag file dataset to demonstrate the system in this tutorial.
+Other than this, one may user any RGB-D data.
+There are lots of excellent RGBD datasets such as: 
+`Redwood data <http://redwood-data.org/>`_, `TUM RGBD data <https://vision.in.tum.de/data/datasets/rgbd-dataset>`_, 
+`ICL-NUIM data <https://www.doc.ic.ac.uk/~ahanda/VaFRIC/iclnuim.html>`_, 
+`the SceneNN dataset <http://people.sutd.edu.sg/~saikit/projects/sceneNN/>`_ and `SUN3D data <http://sun3d.cs.princeton.edu/>`_.
 
 .. _reconstruction_system_how_to_run_the_pipeline:
 
 Quick start
 ``````````````````````````````````````
-
-Put all color images in the ``image`` folder, and all depth images in the
-``depth`` folder. Run the following commands from the root folder.
+Getting the example code
 
 .. code-block:: sh
 
+    # Activate your conda enviroment, where you have installed open3d pip package.
+    # Clone the Open3D github repository and go to the example.
     cd examples/python/reconstruction_system/
-    python run_system.py [config_file] [--make] [--register] [--refine] [--integrate]
 
-``config_file`` has parameters and file paths. For example,
-``reconstruction_system/config/tutorial.json`` has the following script.
+    # Show CLI help for `run_system.py`
+    python dense_slam_gui.py --help
+
+Running the example with default dataset.
+
+.. code-block:: sh
+
+    # The following command, will download and use the default dataset,
+    # which is ``lounge`` dataset from stanford. 
+    # --make will make fragments from RGBD sequence.
+    # --register will register all fragments to detect loop closure.
+    # --refine flag will refine rough registrations.
+    # --integrate flag will integrate the whole RGBD sequence to make final mesh.
+    # [Optional] Use --slac and --slac_integrate flags to perform SLAC optimisation.
+    python run_system.py --make --register --refine --integrate
+
+Changing the default dataset.
+One may change the default dataset to other avaialble datasets. 
+Currently the following datasets are available:
+
+1. Lounge (keyword: ``lounge``) (Default)
+
+2. Bedroom (keyword: ``bedroom``)
+
+3. Jack Jack (keyword: ``jack_jack``)
+
+
+.. code-block:: sh
+
+    # Using jack_jack as the default dataset.
+    python run_system.py --default_dataset 'bedroom' --make --register --refine --integrate
+
+Running the example with custom dataset using config file.
+Manually download or store the data in a folder and store all the color images 
+in the ``image`` sub-folder, and all the depth images in the ``depth`` sub-folder. 
+Create a ``config.json`` file and set the ``path_dataset`` to the data directory.
+Override the parameters for which you want to change the default values.
+
+Example config file for offline reconstruction system has been provided in 
+``examples/python/reconstruction_system/config/tutorial.json``, which looks like the following:
 
 .. literalinclude:: ../../../examples/python/reconstruction_system/config/tutorial.json
    :language: json
diff --git a/docs/tutorial/t_reconstruction_system/index.rst b/docs/tutorial/t_reconstruction_system/index.rst
index bd41306741b..31322f613c0 100644
--- a/docs/tutorial/t_reconstruction_system/index.rst
+++ b/docs/tutorial/t_reconstruction_system/index.rst
@@ -19,6 +19,76 @@ If you use any part of the tensor-based reconstruction system or the hash map ba
 .. note::
    As of now the tutorial is only for **online** dense SLAM, and **offline** integration **with** provided poses. The tutorials for tensor-based **offline** reconstruction system, Simultaneous localization and calibration (SLAC), and shape from shading (SfS) tutorials as mentioned in [Dong2021]_ are still under construction. At current, please refer to :ref:`reconstruction_system` for the legacy versions.
 
+Quick start
+``````````````````````````````````````
+Getting the example code
+
+.. code-block:: sh
+
+    # Activate your conda enviroment, where you have installed open3d pip package.
+    # Clone the Open3D github repository and go to the example.
+    cd examples/python/t_reconstruction_system/
+
+    # Show CLI help for ``dense_slam_gui.py``
+    python dense_slam_gui.py --help
+
+Running the example with default dataset.
+
+.. code-block:: sh
+
+    # The following command, will download and use the default dataset,
+    # which is ``lounge`` dataset from stanford. 
+    python dense_slam_gui.py 
+
+It is recommended to use CUDA if avaialble.
+
+.. code-block:: sh
+
+    # The following command, will download and use the default dataset,
+    # which is ``lounge`` dataset from stanford. 
+    python dense_slam_gui.py --device 'cuda:0'
+
+Changing the default dataset.
+One may change the default dataset to other avaialble datasets. 
+Currently the following datasets are available:
+
+1. Lounge (keyword: ``lounge``) (Default)
+
+2. Bedroom (keyword: ``bedroom``)
+
+3. Jack Jack (keyword: ``jack_jack``)
+
+.. code-block:: sh
+
+    # Using jack_jack as the default dataset.
+    python dense_slam_gui.py --default_dataset 'bedroom'
+
+
+Running the example with custom dataset using config file.
+Manually download or store the data in a folder and store all the color images 
+in the ``image`` sub-folder, and all the depth images in the ``depth`` sub-folder. 
+Create a ``config.yml`` file and set the ``path_dataset`` to the data directory.
+Override the parameters for which you want to change the default values.
+
+Example config file for online reconstruction system has been provided in 
+``examples/python/t_reconstruction_system/default_config.yml``, which looks like the following:
+
+.. literalinclude:: ../../../examples/python/t_reconstruction_system/default_config.yml
+   :language: yml
+   :lineno-start: 1
+   :lines: 1-
+   :linenos:
+
+Capture your own dataset
+``````````````````````````````````````
+
+This tutorial provides an example that can record synchronized and aligned RGBD
+images using the Intel RealSense camera. For more details, please see
+:ref:`capture_your_own_dataset`.
+
+Getting started with online reconstruction system
+``````````````````````````````````````
+
 .. toctree::
 
    voxel_block_grid
diff --git a/docs/tutorial/t_reconstruction_system/integration.rst b/docs/tutorial/t_reconstruction_system/integration.rst
index 971d164f5d9..e62d9bf3cfc 100644
--- a/docs/tutorial/t_reconstruction_system/integration.rst
+++ b/docs/tutorial/t_reconstruction_system/integration.rst
@@ -62,7 +62,7 @@ The voxel block grids can be saved to and loaded from `.npz` files that are acce
    :lineno-start: 47
    :lines: 27,48,98
 
-The `.npz` file of the aforementioned voxel block grid contains the following entries:
+The ``.npz`` file of the aforementioned voxel block grid contains the following entries:
 
 - ``attr_name_tsdf``: stores the value buffer index: 0
 - ``attr_name_weight``: stores the value buffer index: 1
diff --git a/examples/cpp/OfflineSLAM.cpp b/examples/cpp/OfflineSLAM.cpp
index a0c8ddb47c4..a2b668be44b 100644
--- a/examples/cpp/OfflineSLAM.cpp
+++ b/examples/cpp/OfflineSLAM.cpp
@@ -32,7 +32,7 @@ void PrintHelp() {
     PrintOpen3DVersion();
     // clang-format off
     utility::LogInfo("Usage:");
-    utility::LogInfo("    > DenseSLAM [options]");
+    utility::LogInfo("    > OfflineSLAM [options]");
     utility::LogInfo("      Given an RGBD image sequence, perform frame-to-model tracking and mapping, and reconstruct the surface.");
     utility::LogInfo("");
     utility::LogInfo("Basic options:");
@@ -47,6 +47,7 @@ void PrintHelp() {
     utility::LogInfo("    --device [CPU:0]");
     utility::LogInfo("    --pointcloud [file path to save the extracted pointcloud]");
     utility::LogInfo("    --mesh [file path to save the extracted mesh]");
+    utility::LogInfo("To run similar example with a default dataset, try the `OnlineSLAMRGBD` example");
     // clang-format on
     utility::LogInfo("");
 }
diff --git a/examples/cpp/OnlineSLAMRGBD.cpp b/examples/cpp/OnlineSLAMRGBD.cpp
index b37b4913117..e5c213c91c7 100644
--- a/examples/cpp/OnlineSLAMRGBD.cpp
+++ b/examples/cpp/OnlineSLAMRGBD.cpp
@@ -84,12 +84,21 @@ void PrintHelp() {
 
     // clang-format off
     utility::LogInfo("Usage:");
-    utility::LogInfo("    > RGBDDenseSLAM [dataset_path] [options]");
+    utility::LogInfo("    > OnlineSLAMRGBD [options]");
     utility::LogInfo("Basic options:");
     utility::LogInfo("    [-V]");
+    utility::LogInfo("    [--dataset_path /path/to/dataset]"); 
+    utility::LogInfo("                    - To use your own dataset, pass the path");
+    utility::LogInfo("                      to the dataset root folder containing");
+    utility::LogInfo("                      `image` and `depth` folder. If not");
+    utility::LogInfo("                      provided, default dataset will be used.");
     utility::LogInfo("    [--intrinsic_path camera_intrinsic.json]");
     utility::LogInfo("    [--align]");
     utility::LogInfo("    [--device CUDA:0]");
+    utility::LogInfo("    [--default_dataset lounge]");
+    utility::LogInfo("                    - To change default dataset (used when");
+    utility::LogInfo("                      dataset_path is not set).");
+    utility::LogInfo("                      Available options: `lounge` and `bedroom`.");
     // clang-format on
     utility::LogInfo("");
 }
@@ -100,18 +109,41 @@ int main(int argc, char* argv[]) {
 
     utility::SetVerbosityLevel(utility::VerbosityLevel::Debug);
 
-    if (argc < 2 ||
+    if (argc < 1 ||
         utility::ProgramOptionExistsAny(argc, argv, {"-h", "--help"})) {
         PrintHelp();
         return 1;
     }
 
-    std::string dataset_path = argv[1];
-    if (!utility::filesystem::DirectoryExists(dataset_path)) {
-        utility::LogWarning(
-                "Expected an existing directory, but {} does not exist.",
-                dataset_path);
-        return -1;
+    bool use_default_dataset = true;
+
+    std::string dataset_path =
+            utility::GetProgramOptionAsString(argc, argv, "--dataset_path", "");
+    if (!dataset_path.empty()) {
+        if (!utility::filesystem::DirectoryExists(dataset_path)) {
+            utility::LogError(
+                    "Expected an existing directory, but {} does not exist.",
+                    dataset_path);
+        }
+
+        use_default_dataset = false;
+    }
+
+    if (use_default_dataset) {
+        const std::string default_dataset = utility::GetProgramOptionAsString(
+                argc, argv, "--default_dataset", "lounge");
+        if (default_dataset == "lounge") {
+            data::LoungeRGBDImages dataset;
+            dataset_path = dataset.GetExtractDir();
+        } else if (default_dataset == "bedroom") {
+            data::BedroomRGBDImages dataset;
+            dataset_path = dataset.GetExtractDir();
+        } else {
+            utility::LogError(
+                    "The default_dataset {}, is not available. Please select "
+                    "from `lounge` (default) and `bedroom` dataset.",
+                    default_dataset);
+        }
     }
 
     if (utility::ProgramOptionExists(argc, argv, "-V")) {
diff --git a/examples/cpp/OnlineSLAMRealSense.cpp b/examples/cpp/OnlineSLAMRealSense.cpp
index ea594ab4627..92e67ac61c1 100644
--- a/examples/cpp/OnlineSLAMRealSense.cpp
+++ b/examples/cpp/OnlineSLAMRealSense.cpp
@@ -37,7 +37,7 @@ void PrintHelp() {
 
     // clang-format off
     utility::LogInfo("Usage:");
-    utility::LogInfo("    > RealSenseDenseSLAMGUI [options]");
+    utility::LogInfo("    > OnlineSLAMRealSense [options]");
     utility::LogInfo("Basic options:");
     utility::LogInfo("    [-V]");
     utility::LogInfo("    [--use_bag_file /path/to/realsense_video_file.bag] If not provided, it will look for realsense sensor.");
diff --git a/examples/python/open3d_example.py b/examples/python/open3d_example.py
index 4447fdba2dd..2058ffa496a 100644
--- a/examples/python/open3d_example.py
+++ b/examples/python/open3d_example.py
@@ -207,6 +207,18 @@ def add_if_exists(path_dataset, folder_names):
         f"None of the folders {folder_names} found in {path_dataset}")
 
 
+def read_rgbd_image(color_file, depth_file, convert_rgb_to_intensity, config):
+    color = o3d.io.read_image(color_file)
+    depth = o3d.io.read_image(depth_file)
+    rgbd_image = o3d.geometry.RGBDImage.create_from_color_and_depth(
+        color,
+        depth,
+        depth_scale=config["depth_scale"],
+        depth_trunc=config["max_depth"],
+        convert_rgb_to_intensity=convert_rgb_to_intensity)
+    return rgbd_image
+
+
 def get_rgbd_folders(path_dataset):
     path_color = add_if_exists(path_dataset, ["image/", "rgb/", "color/"])
     path_depth = join(path_dataset, "depth/")
@@ -277,29 +289,6 @@ def read_poses_from_log(traj_log):
     return trans_arr
 
 
-def extract_rgbd_frames(rgbd_video_file):
-    """
-    Extract color and aligned depth frames and intrinsic calibration from an
-    RGBD video file (currently only RealSense bag files supported). Folder
-    structure is:
-        <directory of rgbd_video_file/<rgbd_video_file name without extension>/
-            {depth/00000.jpg,color/00000.png,intrinsic.json}
-    """
-    frames_folder = join(dirname(rgbd_video_file),
-                         basename(splitext(rgbd_video_file)[0]))
-    path_intrinsic = join(frames_folder, "intrinsic.json")
-    if isfile(path_intrinsic):
-        warn(f"Skipping frame extraction for {rgbd_video_file} since files are"
-             " present.")
-    else:
-        rgbd_video = o3d.t.io.RGBDVideoReader.create(rgbd_video_file)
-        rgbd_video.save_frames(frames_folder)
-    with open(path_intrinsic) as intr_file:
-        intr = json.load(intr_file)
-    depth_scale = intr["depth_scale"]
-    return frames_folder, path_intrinsic, depth_scale
-
-
 flip_transform = [[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]]
 
 
diff --git a/examples/python/reconstruction_system/colored_icp.py b/examples/python/reconstruction_system/colored_icp.py
deleted file mode 100644
index 8e2c5cf2523..00000000000
--- a/examples/python/reconstruction_system/colored_icp.py
+++ /dev/null
@@ -1,87 +0,0 @@
-# ----------------------------------------------------------------------------
-# -                        Open3D: www.open3d.org                            -
-# ----------------------------------------------------------------------------
-# The MIT License (MIT)
-#
-# Copyright (c) 2018-2021 www.open3d.org
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-# IN THE SOFTWARE.
-# ----------------------------------------------------------------------------
-
-# examples/python/reconstruction_system/colored_icp.py
-
-import numpy as np
-import open3d as o3d
-import os, sys
-
-pyexample_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
-sys.path.append(pyexample_path)
-
-from utility.visualization import draw_registration_result_original_color
-import argparse
-
-
-def multiscale_icp(source,
-                   target,
-                   voxel_size,
-                   max_iter,
-                   init_transformation=np.identity(4)):
-    current_transformation = init_transformation
-    for i, scale in enumerate(range(len(max_iter))):  # multi-scale approach
-        iter = max_iter[scale]
-        distance_threshold = 0.07
-        print("voxel_size {}".format(voxel_size[scale]))
-        source_down = source.voxel_down_sample(voxel_size[scale])
-        target_down = target.voxel_down_sample(voxel_size[scale])
-        source_down.estimate_normals(
-            o3d.geometry.KDTreeSearchParamHybrid(radius=voxel_size[scale] * 2.0,
-                                                 max_nn=30))
-        target_down.estimate_normals(
-            o3d.geometry.KDTreeSearchParamHybrid(radius=voxel_size[scale] * 2.0,
-                                                 max_nn=30))
-        result_icp = o3d.pipelines.registration.registration_colored_icp(
-            source_down, target_down, distance_threshold,
-            current_transformation,
-            o3d.pipelines.registration.TransformationEstimationForColoredICP(),
-            o3d.pipelines.registration.ICPConvergenceCriteria(
-                relative_fitness=1e-6, relative_rmse=1e-6, max_iteration=iter))
-
-        current_transformation = result_icp.transformation
-        draw_registration_result_original_color(source, target,
-                                                current_transformation)
-        print(current_transformation)
-
-    return result_icp.transformation
-
-
-if __name__ == '__main__':
-    parser = argparse.ArgumentParser()
-    parser.add_argument('src')
-    parser.add_argument('dst')
-    parser.add_argument('--voxel_size', default=0.05, type=float)
-    args = parser.parse_args()
-
-    o3d.utility.set_verbosity_level(o3d.utility.Debug)
-    source = o3d.io.read_point_cloud(args.src)
-    target = o3d.io.read_point_cloud(args.dst)
-    voxel_size = args.voxel_size
-
-    trans = multiscale_icp(source, target,
-                           [voxel_size, voxel_size / 2.0, voxel_size / 4.0],
-                           [50, 30, 14], np.identity(4))
diff --git a/examples/python/reconstruction_system/config/indoor_lidar_rgbd/apartment.json b/examples/python/reconstruction_system/config/indoor_lidar_rgbd/apartment.json
deleted file mode 100644
index 0c2aa90052f..00000000000
--- a/examples/python/reconstruction_system/config/indoor_lidar_rgbd/apartment.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-    "name": "Indoor Lidar-RGBD Dataset: http://redwood-data.org/indoor_lidar_rgbd/download.html",
-    "path_dataset": "dataset/indoor_lidar_rgbd/apartment/",
-    "path_intrinsic": "",
-    "max_depth": 3.0,
-    "voxel_size": 0.05,
-    "max_depth_diff": 0.07,
-    "preference_loop_closure_odometry": 0.1,
-    "preference_loop_closure_registration": 5.0,
-    "tsdf_cubic_size": 3.0,
-    "icp_method": "color",
-    "global_registration": "ransac",
-    "python_multi_threading": true
-}
diff --git a/examples/python/reconstruction_system/config/indoor_lidar_rgbd/bedroom.json b/examples/python/reconstruction_system/config/indoor_lidar_rgbd/bedroom.json
deleted file mode 100644
index 18b22284fa8..00000000000
--- a/examples/python/reconstruction_system/config/indoor_lidar_rgbd/bedroom.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-    "name": "Indoor Lidar-RGBD Dataset: http://redwood-data.org/indoor_lidar_rgbd/download.html",
-    "path_dataset": "dataset/indoor_lidar_rgbd/bedroom/",
-    "path_intrinsic": "",
-    "max_depth": 3.0,
-    "voxel_size": 0.05,
-    "max_depth_diff": 0.07,
-    "preference_loop_closure_odometry": 0.1,
-    "preference_loop_closure_registration": 5.0,
-    "tsdf_cubic_size": 3.0,
-    "icp_method": "color",
-    "global_registration": "ransac",
-    "python_multi_threading": true
-}
diff --git a/examples/python/reconstruction_system/config/indoor_lidar_rgbd/boardroom.json b/examples/python/reconstruction_system/config/indoor_lidar_rgbd/boardroom.json
deleted file mode 100644
index 0da6c60a9a7..00000000000
--- a/examples/python/reconstruction_system/config/indoor_lidar_rgbd/boardroom.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-    "name": "Indoor Lidar-RGBD Dataset: http://redwood-data.org/indoor_lidar_rgbd/download.html",
-    "path_dataset": "dataset/indoor_lidar_rgbd/boardroom/",
-    "path_intrinsic": "",
-    "max_depth": 3.0,
-    "voxel_size": 0.05,
-    "max_depth_diff": 0.07,
-    "preference_loop_closure_odometry": 0.1,
-    "preference_loop_closure_registration": 5.0,
-    "tsdf_cubic_size": 3.0,
-    "icp_method": "color",
-    "global_registration": "ransac",
-    "python_multi_threading": true
-}
diff --git a/examples/python/reconstruction_system/config/indoor_lidar_rgbd/lobby.json b/examples/python/reconstruction_system/config/indoor_lidar_rgbd/lobby.json
deleted file mode 100644
index e5a42b73aaf..00000000000
--- a/examples/python/reconstruction_system/config/indoor_lidar_rgbd/lobby.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-    "name": "Indoor Lidar-RGBD Dataset: http://redwood-data.org/indoor_lidar_rgbd/download.html",
-    "path_dataset": "dataset/indoor_lidar_rgbd/lobby/",
-    "path_intrinsic": "",
-    "max_depth": 3.0,
-    "voxel_size": 0.05,
-    "max_depth_diff": 0.07,
-    "preference_loop_closure_odometry": 0.1,
-    "preference_loop_closure_registration": 5.0,
-    "tsdf_cubic_size": 3.0,
-    "icp_method": "color",
-    "global_registration": "ransac",
-    "python_multi_threading": true
-}
diff --git a/examples/python/reconstruction_system/config/indoor_lidar_rgbd/loft.json b/examples/python/reconstruction_system/config/indoor_lidar_rgbd/loft.json
deleted file mode 100644
index 24fdacb11b7..00000000000
--- a/examples/python/reconstruction_system/config/indoor_lidar_rgbd/loft.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-    "name": "Indoor Lidar-RGBD Dataset: http://redwood-data.org/indoor_lidar_rgbd/download.html",
-    "path_dataset": "dataset/indoor_lidar_rgbd/loft/",
-    "path_intrinsic": "",
-    "max_depth": 3.0,
-    "voxel_size": 0.05,
-    "max_depth_diff": 0.07,
-    "preference_loop_closure_odometry": 0.1,
-    "preference_loop_closure_registration": 5.0,
-    "tsdf_cubic_size": 3.0,
-    "icp_method": "color",
-    "global_registration": "ransac",
-    "python_multi_threading": true
-}
diff --git a/examples/python/reconstruction_system/config/redwood_objects/car.json b/examples/python/reconstruction_system/config/redwood_objects/car.json
deleted file mode 100644
index cfa062f6dfc..00000000000
--- a/examples/python/reconstruction_system/config/redwood_objects/car.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-    "name": "Single object scans http://redwood-data.org/3dscan/index.html",
-    "path_dataset": "dataset/redwood_objects/car/",
-    "path_intrinsic": "",
-    "max_depth": 3.0,
-    "voxel_size": 0.05,
-    "max_depth_diff": 0.07,
-    "preference_loop_closure_odometry": 0.1,
-    "preference_loop_closure_registration": 5.0,
-    "tsdf_cubic_size": 3.0,
-    "icp_method": "color",
-    "global_registration": "ransac",
-    "python_multi_threading": true
-}
diff --git a/examples/python/reconstruction_system/config/redwood_objects/chair.json b/examples/python/reconstruction_system/config/redwood_objects/chair.json
deleted file mode 100644
index fe39966fa8f..00000000000
--- a/examples/python/reconstruction_system/config/redwood_objects/chair.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-    "name": "Single object scans http://redwood-data.org/3dscan/index.html",
-    "path_dataset": "dataset/redwood_objects/chair/",
-    "path_intrinsic": "",
-    "max_depth": 2.0,
-    "voxel_size": 0.02,
-    "max_depth_diff": 0.03,
-    "preference_loop_closure_odometry": 0.1,
-    "preference_loop_closure_registration": 5.0,
-    "tsdf_cubic_size": 2.0,
-    "icp_method": "point_to_point",
-    "global_registration": "ransac",
-    "python_multi_threading": true
-}
diff --git a/examples/python/reconstruction_system/config/redwood_objects/motorcycle.json b/examples/python/reconstruction_system/config/redwood_objects/motorcycle.json
deleted file mode 100644
index b50971d71a0..00000000000
--- a/examples/python/reconstruction_system/config/redwood_objects/motorcycle.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-    "name": "Single object scans http://redwood-data.org/3dscan/index.html",
-    "path_dataset": "dataset/redwood_objects/motorcycle/",
-    "path_intrinsic": "",
-    "max_depth": 3.0,
-    "voxel_size": 0.05,
-    "max_depth_diff": 0.07,
-    "preference_loop_closure_odometry": 0.1,
-    "preference_loop_closure_registration": 5.0,
-    "tsdf_cubic_size": 3.0,
-    "icp_method": "color",
-    "global_registration": "ransac",
-    "python_multi_threading": true
-}
diff --git a/examples/python/reconstruction_system/config/redwood_objects/plant.json b/examples/python/reconstruction_system/config/redwood_objects/plant.json
deleted file mode 100644
index 4d76835196a..00000000000
--- a/examples/python/reconstruction_system/config/redwood_objects/plant.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-    "name": "Single object scans http://redwood-data.org/3dscan/index.html",
-    "path_dataset": "dataset/redwood_objects/plant/",
-    "path_intrinsic": "",
-    "max_depth": 2.0,
-    "voxel_size": 0.02,
-    "max_depth_diff": 0.03,
-    "preference_loop_closure_odometry": 0.1,
-    "preference_loop_closure_registration": 5.0,
-    "tsdf_cubic_size": 2.0,
-    "icp_method": "color",
-    "global_registration": "ransac",
-    "python_multi_threading": true
-}
diff --git a/examples/python/reconstruction_system/config/redwood_objects/sofa.json b/examples/python/reconstruction_system/config/redwood_objects/sofa.json
deleted file mode 100644
index a0c69468ce3..00000000000
--- a/examples/python/reconstruction_system/config/redwood_objects/sofa.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-    "name": "Single object scans http://redwood-data.org/3dscan/index.html",
-    "path_dataset": "dataset/redwood_objects/sofa/",
-    "path_intrinsic": "",
-    "max_depth": 3.0,
-    "voxel_size": 0.05,
-    "max_depth_diff": 0.07,
-    "preference_loop_closure_odometry": 0.1,
-    "preference_loop_closure_registration": 5.0,
-    "tsdf_cubic_size": 3.0,
-    "icp_method": "color",
-    "global_registration": "ransac",
-    "python_multi_threading": true
-}
diff --git a/examples/python/reconstruction_system/config/redwood_objects/truck.json b/examples/python/reconstruction_system/config/redwood_objects/truck.json
deleted file mode 100644
index c98eeca1f2d..00000000000
--- a/examples/python/reconstruction_system/config/redwood_objects/truck.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-    "name": "Single object scans http://redwood-data.org/3dscan/index.html",
-    "path_dataset": "dataset/redwood_objects/truck/",
-    "path_intrinsic": "",
-    "max_depth": 3.0,
-    "voxel_size": 0.05,
-    "max_depth_diff": 0.07,
-    "preference_loop_closure_odometry": 0.1,
-    "preference_loop_closure_registration": 5.0,
-    "tsdf_cubic_size": 3.0,
-    "icp_method": "color",
-    "global_registration": "ransac",
-    "python_multi_threading": true
-}
diff --git a/examples/python/reconstruction_system/config/redwood_simulated/livingroom1-clean.json b/examples/python/reconstruction_system/config/redwood_simulated/livingroom1-clean.json
deleted file mode 100644
index a1a8fce4550..00000000000
--- a/examples/python/reconstruction_system/config/redwood_simulated/livingroom1-clean.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
-    "name": "Redwood Dataset: http://redwood-data.org/indoor/dataset.html",
-    "path_dataset": "dataset/redwood_simulated/livingroom1-clean/",
-    "path_intrinsic": "",
-    "max_depth": 5.0,
-    "voxel_size": 0.05,
-    "max_depth_diff": 0.07,
-    "preference_loop_closure_odometry": 0.1,
-    "preference_loop_closure_registration": 5.0,
-    "tsdf_cubic_size": 4.0,
-    "icp_method": "point_to_point",
-    "global_registration": "ransac",
-    "python_multi_threading": true,
-    "max_iterations": 5,
-    "sdf_trunc": 0.04,
-    "block_count": 40000,
-    "distance_threshold": 0.07,
-    "fitness_threshold": 0.3,
-    "regularizer_weight": 1,
-    "method": "slac",
-    "device": "CPU:0",
-    "save_output_as": "pointcloud" 
-}
diff --git a/examples/python/reconstruction_system/config/redwood_simulated/livingroom1-simulated.json b/examples/python/reconstruction_system/config/redwood_simulated/livingroom1-simulated.json
deleted file mode 100644
index 561f01a9d85..00000000000
--- a/examples/python/reconstruction_system/config/redwood_simulated/livingroom1-simulated.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-    "name": "Redwood Dataset: http://redwood-data.org/indoor/dataset.html",
-    "path_dataset": "dataset/redwood_simulated/livingroom1-simulated/",
-    "path_intrinsic": "",
-    "n_frames_per_fragment": 50,
-    "max_depth": 5.0,
-    "voxel_size": 0.05,
-    "max_depth_diff": 0.07,
-    "preference_loop_closure_odometry": 0.1,
-    "preference_loop_closure_registration": 20.0,
-    "tsdf_cubic_size": 4.0,
-    "icp_method": "point_to_point",
-    "global_registration": "ransac",
-    "python_multi_threading": true
-}
diff --git a/examples/python/reconstruction_system/config/redwood_simulated/livingroom2-clean.json b/examples/python/reconstruction_system/config/redwood_simulated/livingroom2-clean.json
deleted file mode 100644
index 261aa335d27..00000000000
--- a/examples/python/reconstruction_system/config/redwood_simulated/livingroom2-clean.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-    "name": "Redwood Dataset: http://redwood-data.org/indoor/dataset.html",
-    "path_dataset": "dataset/redwood_simulated/livingroom2-clean/",
-    "path_intrinsic": "",
-    "max_depth": 5.0,
-    "voxel_size": 0.05,
-    "max_depth_diff": 0.07,
-    "preference_loop_closure_odometry": 0.1,
-    "preference_loop_closure_registration": 5.0,
-    "tsdf_cubic_size": 4.0,
-    "icp_method": "point_to_point",
-    "global_registration": "ransac",
-    "python_multi_threading": true
-}
diff --git a/examples/python/reconstruction_system/config/redwood_simulated/livingroom2-simulated.json b/examples/python/reconstruction_system/config/redwood_simulated/livingroom2-simulated.json
deleted file mode 100644
index 3674f64682b..00000000000
--- a/examples/python/reconstruction_system/config/redwood_simulated/livingroom2-simulated.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-    "name": "Redwood Dataset: http://redwood-data.org/indoor/dataset.html",
-    "path_dataset": "dataset/redwood_simulated/livingroom2-simulated/",
-    "path_intrinsic": "",
-    "n_frames_per_fragment": 50,
-    "max_depth": 5.0,
-    "voxel_size": 0.05,
-    "max_depth_diff": 0.07,
-    "preference_loop_closure_odometry": 0.1,
-    "preference_loop_closure_registration": 20.0,
-    "tsdf_cubic_size": 4.0,
-    "icp_method": "point_to_point",
-    "global_registration": "ransac",
-    "python_multi_threading": true
-}
diff --git a/examples/python/reconstruction_system/config/redwood_simulated/office1-clean.json b/examples/python/reconstruction_system/config/redwood_simulated/office1-clean.json
deleted file mode 100644
index 27b028528de..00000000000
--- a/examples/python/reconstruction_system/config/redwood_simulated/office1-clean.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-    "name": "Redwood Dataset: http://redwood-data.org/indoor/dataset.html",
-    "path_dataset": "dataset/redwood_simulated/office1-clean/",
-    "path_intrinsic": "",
-    "max_depth": 5.0,
-    "voxel_size": 0.05,
-    "max_depth_diff": 0.07,
-    "preference_loop_closure_odometry": 0.1,
-    "preference_loop_closure_registration": 5.0,
-    "tsdf_cubic_size": 4.0,
-    "icp_method": "point_to_point",
-    "global_registration": "ransac",
-    "python_multi_threading": true
-}
diff --git a/examples/python/reconstruction_system/config/redwood_simulated/office1-simulated.json b/examples/python/reconstruction_system/config/redwood_simulated/office1-simulated.json
deleted file mode 100644
index cfd6bc27421..00000000000
--- a/examples/python/reconstruction_system/config/redwood_simulated/office1-simulated.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-    "name": "Redwood Dataset: http://redwood-data.org/indoor/dataset.html",
-    "path_dataset": "dataset/redwood_simulated/office1-simulated/",
-    "path_intrinsic": "",
-    "n_frames_per_fragment": 50,
-    "max_depth": 5.0,
-    "voxel_size": 0.05,
-    "max_depth_diff": 0.07,
-    "preference_loop_closure_odometry": 0.1,
-    "preference_loop_closure_registration": 20.0,
-    "tsdf_cubic_size": 4.0,
-    "icp_method": "point_to_point",
-    "global_registration": "ransac",
-    "python_multi_threading": true
-}
diff --git a/examples/python/reconstruction_system/config/redwood_simulated/office2-clean.json b/examples/python/reconstruction_system/config/redwood_simulated/office2-clean.json
deleted file mode 100644
index 356dfc5e8d0..00000000000
--- a/examples/python/reconstruction_system/config/redwood_simulated/office2-clean.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-    "name": "Redwood Dataset: http://redwood-data.org/indoor/dataset.html",
-    "path_dataset": "dataset/redwood_simulated/office2-clean/",
-    "path_intrinsic": "",
-    "max_depth": 5.0,
-    "voxel_size": 0.05,
-    "max_depth_diff": 0.07,
-    "preference_loop_closure_odometry": 0.1,
-    "preference_loop_closure_registration": 5.0,
-    "tsdf_cubic_size": 4.0,
-    "icp_method": "point_to_point",
-    "global_registration": "ransac",
-    "python_multi_threading": true
-}
diff --git a/examples/python/reconstruction_system/config/redwood_simulated/office2-simulated.json b/examples/python/reconstruction_system/config/redwood_simulated/office2-simulated.json
deleted file mode 100644
index e03231280c2..00000000000
--- a/examples/python/reconstruction_system/config/redwood_simulated/office2-simulated.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-    "name": "Redwood Dataset: http://redwood-data.org/indoor/dataset.html",
-    "path_dataset": "dataset/redwood_simulated/office2-simulated/",
-    "path_intrinsic": "",
-    "n_frames_per_fragment": 50,
-    "max_depth": 5.0,
-    "voxel_size": 0.05,
-    "max_depth_diff": 0.07,
-    "preference_loop_closure_odometry": 0.1,
-    "preference_loop_closure_registration": 20.0,
-    "tsdf_cubic_size": 4.0,
-    "icp_method": "point_to_point",
-    "global_registration": "ransac",
-    "python_multi_threading": true
-}
diff --git a/examples/python/reconstruction_system/config/stanford/burghers.json b/examples/python/reconstruction_system/config/stanford/burghers.json
deleted file mode 100644
index fcc1409e89d..00000000000
--- a/examples/python/reconstruction_system/config/stanford/burghers.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-    "name": "Open3D reconstruction tutorial http://open3d.org/docs/release/tutorial/reconstruction_system/system_overview.html",
-    "path_dataset": "dataset/stanford/burghers/",
-    "path_intrinsic": "",
-    "max_depth": 3.0,
-    "voxel_size": 0.05,
-    "max_depth_diff": 0.07,
-    "preference_loop_closure_odometry": 0.1,
-    "preference_loop_closure_registration": 5.0,
-    "tsdf_cubic_size": 3.0,
-    "icp_method": "color",
-    "global_registration": "ransac",
-    "python_multi_threading": true
-}
diff --git a/examples/python/reconstruction_system/config/stanford/cactusgarden.json b/examples/python/reconstruction_system/config/stanford/cactusgarden.json
deleted file mode 100644
index b6190da4a13..00000000000
--- a/examples/python/reconstruction_system/config/stanford/cactusgarden.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-    "name": "Open3D reconstruction tutorial http://open3d.org/docs/release/tutorial/reconstruction_system/system_overview.html",
-    "path_dataset": "dataset/stanford/cactusgarden/",
-    "path_intrinsic": "",
-    "max_depth": 3.0,
-    "voxel_size": 0.05,
-    "max_depth_diff": 0.07,
-    "preference_loop_closure_odometry": 0.1,
-    "preference_loop_closure_registration": 5.0,
-    "tsdf_cubic_size": 3.0,
-    "icp_method": "color",
-    "global_registration": "ransac",
-    "python_multi_threading": true
-}
diff --git a/examples/python/reconstruction_system/config/stanford/copyroom.json b/examples/python/reconstruction_system/config/stanford/copyroom.json
deleted file mode 100644
index 2146a8ae7a3..00000000000
--- a/examples/python/reconstruction_system/config/stanford/copyroom.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-    "name": "Open3D reconstruction tutorial http://open3d.org/docs/release/tutorial/reconstruction_system/system_overview.html",
-    "path_dataset": "dataset/stanford/copyroom/",
-    "path_intrinsic": "",
-    "max_depth": 3.0,
-    "voxel_size": 0.05,
-    "max_depth_diff": 0.07,
-    "preference_loop_closure_odometry": 0.1,
-    "preference_loop_closure_registration": 5.0,
-    "tsdf_cubic_size": 3.0,
-    "icp_method": "color",
-    "global_registration": "ransac",
-    "python_multi_threading": true
-}
diff --git a/examples/python/reconstruction_system/config/stanford/lounge.json b/examples/python/reconstruction_system/config/stanford/lounge.json
deleted file mode 100644
index 3c419ad4567..00000000000
--- a/examples/python/reconstruction_system/config/stanford/lounge.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-    "name": "Open3D reconstruction tutorial http://open3d.org/docs/release/tutorial/reconstruction_system/system_overview.html",
-    "path_dataset": "dataset/stanford/lounge/",
-    "path_intrinsic": "",
-    "max_depth": 3.0,
-    "voxel_size": 0.05,
-    "max_depth_diff": 0.07,
-    "preference_loop_closure_odometry": 0.1,
-    "preference_loop_closure_registration": 5.0,
-    "tsdf_cubic_size": 3.0,
-    "icp_method": "color",
-    "global_registration": "ransac",
-    "python_multi_threading": true
-}
diff --git a/examples/python/reconstruction_system/config/stanford/stonewall.json b/examples/python/reconstruction_system/config/stanford/stonewall.json
deleted file mode 100644
index b0267d174e2..00000000000
--- a/examples/python/reconstruction_system/config/stanford/stonewall.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-    "name": "Open3D reconstruction tutorial http://open3d.org/docs/release/tutorial/reconstruction_system/system_overview.html",
-    "path_dataset": "dataset/stanford/stonewall/",
-    "path_intrinsic": "",
-    "max_depth": 3.0,
-    "voxel_size": 0.05,
-    "max_depth_diff": 0.07,
-    "preference_loop_closure_odometry": 0.1,
-    "preference_loop_closure_registration": 5.0,
-    "tsdf_cubic_size": 3.0,
-    "icp_method": "color",
-    "global_registration": "ransac",
-    "python_multi_threading": true
-}
diff --git a/examples/python/reconstruction_system/config/stanford/totempole.json b/examples/python/reconstruction_system/config/stanford/totempole.json
deleted file mode 100644
index 9e1f482d5c3..00000000000
--- a/examples/python/reconstruction_system/config/stanford/totempole.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-    "name": "Open3D reconstruction tutorial http://open3d.org/docs/release/tutorial/reconstruction_system/system_overview.html",
-    "path_dataset": "dataset/stanford/totempole/",
-    "path_intrinsic": "",
-    "max_depth": 3.0,
-    "voxel_size": 0.05,
-    "max_depth_diff": 0.07,
-    "preference_loop_closure_odometry": 0.1,
-    "preference_loop_closure_registration": 5.0,
-    "tsdf_cubic_size": 3.0,
-    "icp_method": "color",
-    "global_registration": "ransac",
-    "python_multi_threading": true
-}
diff --git a/examples/python/reconstruction_system/data_loader.py b/examples/python/reconstruction_system/data_loader.py
new file mode 100644
index 00000000000..2333d88aa09
--- /dev/null
+++ b/examples/python/reconstruction_system/data_loader.py
@@ -0,0 +1,96 @@
+# ----------------------------------------------------------------------------
+# -                        Open3D: www.open3d.org                            -
+# ----------------------------------------------------------------------------
+# The MIT License (MIT)
+#
+# Copyright (c) 2018-2021 www.open3d.org
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+# IN THE SOFTWARE.
+# ----------------------------------------------------------------------------
+
+import open3d as o3d
+
+
+def lounge_data_loader():
+    print('Loading Stanford Lounge RGB-D Dataset')
+
+    # Get the dataset.
+    lounge_rgbd = o3d.data.LoungeRGBDImages()
+
+    # Set dataset specific parameters.
+    config = {}
+    config['path_dataset'] = lounge_rgbd.extract_dir
+    config['path_intrinsic'] = ""
+    config['max_depth'] = 3.0
+    config['voxel_size'] = 0.05
+    config['max_depth_diff'] = 0.07
+    config['preference_loop_closure_odometry'] = 0.1
+    config['preference_loop_closure_registration'] = 5.0
+    config['tsdf_cubic_size'] = 3.0
+    config['icp_method'] = "color"
+    config['global_registration'] = "ransac"
+    config['python_multi_threading'] = True
+
+    return config
+
+
+def bedroom_data_loader():
+    print('Loading Redwood Bedroom RGB-D Dataset')
+
+    # Get the dataset.
+    bedroom_rgbd = o3d.data.BedroomRGBDImages()
+
+    # Set dataset specific parameters.
+    config = {}
+    config['path_dataset'] = bedroom_rgbd.extract_dir
+    config['path_intrinsic'] = ""
+    config['max_depth'] = 3.0
+    config['voxel_size'] = 0.05
+    config['max_depth_diff'] = 0.07
+    config['preference_loop_closure_odometry'] = 0.1
+    config['preference_loop_closure_registration'] = 5.0
+    config['tsdf_cubic_size'] = 3.0
+    config['icp_method'] = "color"
+    config['global_registration'] = "ransac"
+    config['python_multi_threading'] = True
+
+    return config
+
+
+def jackjack_data_loader():
+    print('Loading RealSense L515 Jack-Jack RGB-D Bag Dataset')
+
+    # Get the dataset.
+    jackjack_bag = o3d.data.JackJackL515Bag()
+
+    # Set dataset specific parameters.
+    config = {}
+    config['path_dataset'] = jackjack_bag.path
+    config['path_intrinsic'] = ""
+    config['max_depth'] = 0.85
+    config['voxel_size'] = 0.025
+    config['max_depth_diff'] = 0.03
+    config['preference_loop_closure_odometry'] = 0.1
+    config['preference_loop_closure_registration'] = 5.0
+    config['tsdf_cubic_size'] = 0.75
+    config['icp_method'] = "color"
+    config['global_registration'] = "ransac"
+    config['python_multi_threading'] = True
+
+    return config
diff --git a/examples/python/reconstruction_system/initialize_config.py b/examples/python/reconstruction_system/initialize_config.py
index 750e78a8b4b..56a30569ee2 100644
--- a/examples/python/reconstruction_system/initialize_config.py
+++ b/examples/python/reconstruction_system/initialize_config.py
@@ -26,13 +26,37 @@
 
 # examples/python/reconstruction_system/initialize_config.py
 
+import open3d as o3d
+
 import os
 import sys
+import json
+from os.path import isfile, join, splitext, dirname, basename
+from warnings import warn
+from data_loader import lounge_data_loader, bedroom_data_loader, jackjack_data_loader
 
-pyexample_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
-sys.path.append(pyexample_path)
 
-from open3d_example import extract_rgbd_frames
+def extract_rgbd_frames(rgbd_video_file):
+    """
+    Extract color and aligned depth frames and intrinsic calibration from an
+    RGBD video file (currently only RealSense bag files supported). Folder
+    structure is:
+        <directory of rgbd_video_file/<rgbd_video_file name without extension>/
+            {depth/00000.jpg,color/00000.png,intrinsic.json}
+    """
+    frames_folder = join(dirname(rgbd_video_file),
+                         basename(splitext(rgbd_video_file)[0]))
+    path_intrinsic = join(frames_folder, "intrinsic.json")
+    if isfile(path_intrinsic):
+        warn(f"Skipping frame extraction for {rgbd_video_file} since files are"
+             " present.")
+    else:
+        rgbd_video = o3d.t.io.RGBDVideoReader.create(rgbd_video_file)
+        rgbd_video.save_frames(frames_folder)
+    with open(path_intrinsic) as intr_file:
+        intr = json.load(intr_file)
+    depth_scale = intr["depth_scale"]
+    return frames_folder, path_intrinsic, depth_scale
 
 
 def set_default_value(config, key, value):
@@ -102,3 +126,26 @@ def initialize_config(config):
         print("Extracting frames from RGBD video file")
         config["path_dataset"], config["path_intrinsic"], config[
             "depth_scale"] = extract_rgbd_frames(config["path_dataset"])
+
+
+def dataset_loader(dataset_name):
+    print('Config file was not passed. Using deafult dataset.')
+    # Load the dataset and config.
+    config = {}
+    if dataset_name == 'lounge':
+        config = lounge_data_loader()
+    elif dataset_name == 'bedroom':
+        config = bedroom_data_loader()
+    elif dataset_name == 'jack_jack':
+        config = jackjack_data_loader()
+    else:
+        print(
+            "The requested dataset is not available. Available dataset options include lounge and jack_jack."
+        )
+        sys.exit(1)
+
+    # Set the default values for non-specified parameters.
+    initialize_config(config)
+
+    print('Loaded data from {}'.format(config['path_dataset']))
+    return config
diff --git a/examples/python/reconstruction_system/integrate_scene.py b/examples/python/reconstruction_system/integrate_scene.py
index dc919134320..10923e99a61 100644
--- a/examples/python/reconstruction_system/integrate_scene.py
+++ b/examples/python/reconstruction_system/integrate_scene.py
@@ -36,9 +36,6 @@
 
 from open3d_example import *
 
-sys.path.append(os.path.dirname(os.path.abspath(__file__)))
-from make_fragments import read_rgbd_image
-
 
 def scalable_integrate_rgb_frames(path_dataset, intrinsic, config):
     poses = []
diff --git a/examples/python/reconstruction_system/make_fragments.py b/examples/python/reconstruction_system/make_fragments.py
index 50d767b6141..72c99f6e37a 100644
--- a/examples/python/reconstruction_system/make_fragments.py
+++ b/examples/python/reconstruction_system/make_fragments.py
@@ -34,7 +34,7 @@
 pyexample_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 sys.path.append(pyexample_path)
 
-from open3d_example import join, make_clean_folder, get_rgbd_file_lists, initialize_opencv
+from open3d_example import *
 
 sys.path.append(os.path.dirname(os.path.abspath(__file__)))
 from optimize_posegraph import optimize_posegraph_for_fragment
@@ -45,18 +45,6 @@
     from opencv_pose_estimation import pose_estimation
 
 
-def read_rgbd_image(color_file, depth_file, convert_rgb_to_intensity, config):
-    color = o3d.io.read_image(color_file)
-    depth = o3d.io.read_image(depth_file)
-    rgbd_image = o3d.geometry.RGBDImage.create_from_color_and_depth(
-        color,
-        depth,
-        depth_scale=config["depth_scale"],
-        depth_trunc=config["max_depth"],
-        convert_rgb_to_intensity=convert_rgb_to_intensity)
-    return rgbd_image
-
-
 def register_one_rgbd_pair(s, t, color_files, depth_files, intrinsic,
                            with_opencv, config):
     source_rgbd_image = read_rgbd_image(color_files[s], depth_files[s], True,
diff --git a/examples/python/reconstruction_system/run_system.py b/examples/python/reconstruction_system/run_system.py
index e4baf0f21e8..5efb3a6758a 100644
--- a/examples/python/reconstruction_system/run_system.py
+++ b/examples/python/reconstruction_system/run_system.py
@@ -41,11 +41,19 @@
 from open3d_example import check_folder_structure
 
 sys.path.append(os.path.dirname(os.path.abspath(__file__)))
-from initialize_config import initialize_config
+from initialize_config import initialize_config, dataset_loader
 
 if __name__ == "__main__":
     parser = argparse.ArgumentParser(description="Reconstruction system")
-    parser.add_argument("config", help="path to the config file")
+    parser.add_argument("--config",
+                        help="path to the config file",
+                        default=None)
+    parser.add_argument("--default_dataset",
+                        help="(optional) default dataset to be used, only if "
+                        "config file is not provided. "
+                        "Options: [lounge, bedroom, jack_jack]",
+                        type=str,
+                        default="lounge")
     parser.add_argument("--make",
                         help="Step 1) make fragments from RGBD sequence.",
                         action="store_true")
@@ -90,12 +98,16 @@
         parser.print_help(sys.stderr)
         sys.exit(1)
 
-    # check folder structure
+    # load dataset and check folder structure
     if args.config is not None:
         with open(args.config) as json_file:
             config = json.load(json_file)
             initialize_config(config)
-            check_folder_structure(config["path_dataset"])
+            check_folder_structure(config['path_dataset'])
+    else:
+        # load deafult dataset.
+        config = dataset_loader(args.default_dataset)
+
     assert config is not None
 
     if args.debug_mode:
diff --git a/examples/python/reconstruction_system/scripts/__init__.py b/examples/python/reconstruction_system/scripts/__init__.py
deleted file mode 100644
index e69de29bb2d..00000000000
diff --git a/examples/python/reconstruction_system/scripts/download_dataset.py b/examples/python/reconstruction_system/scripts/download_dataset.py
deleted file mode 100644
index 62e85784e9c..00000000000
--- a/examples/python/reconstruction_system/scripts/download_dataset.py
+++ /dev/null
@@ -1,90 +0,0 @@
-# ----------------------------------------------------------------------------
-# -                        Open3D: www.open3d.org                            -
-# ----------------------------------------------------------------------------
-# The MIT License (MIT)
-#
-# Copyright (c) 2018-2021 www.open3d.org
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-# IN THE SOFTWARE.
-# ----------------------------------------------------------------------------
-"""
-Cross-platform Python script to download and extract datasets. All common
-archive formats are supported.
-python download_dataset.py dataset_name ... [--cache download-folder]
-[--extract-to local-folder]
-"""
-import urllib.request
-import shutil
-import os
-import argparse
-
-dataset_dict = {
-    "L515_test":
-        "https://storage.googleapis.com/isl-datasets/open3d-dev/realsense/L515_test.bag",
-    "L515_paper_lantern":
-        "https://storage.googleapis.com/isl-datasets/open3d-dev/realsense/L515_paper_lantern.bag",
-    "L515_JackJack":
-        "https://storage.googleapis.com/isl-datasets/open3d-dev/realsense/L515_JackJack.bag"
-}
-
-
-def download(dataset_name, download_folder, extract_folder):
-    """
-    Download dataset 'dataset_name' to 'download_folder'. If it is an archive,
-    extract it to 'extract_folder', else move it there.
-    """
-    cache_path = os.path.join(download_folder,
-                              os.path.basename(dataset_dict[dataset_name]))
-    extract_path = os.path.join(extract_folder, dataset_name)
-    os.makedirs(os.path.realpath(extract_path), exist_ok=True)
-    with urllib.request.urlopen(dataset_dict[dataset_name]) as response:
-        with open(cache_path, 'wb') as cp_obj:
-            shutil.copyfileobj(response, cp_obj)
-            try:
-                shutil.unpack_archive(cache_path, extract_path)
-            except (ValueError, shutil.ReadError):  # Not an archive
-                shutil.move(cache_path, extract_path)
-    print(f"Downloaded dataset {dataset_name} to {extract_path}")
-
-
-if __name__ == "__main__":
-
-    parser = argparse.ArgumentParser(
-        description='Download and extract datasets.')
-    parser.add_argument('dataset_name',
-                        nargs='*',
-                        help='Names of datasets to download.')
-    parser.add_argument('-c',
-                        '--cache',
-                        default='.',
-                        help='Download folder for caching archives.')
-    parser.add_argument('-e',
-                        '--extract-to',
-                        default='../datasets/',
-                        help='Extract downloaded datasets here.')
-    parser.add_argument('-l',
-                        '--list-datasets',
-                        action='store_true',
-                        help='List datasets')
-
-    args = parser.parse_args()
-    if args.list_datasets:
-        print('Available datasets:\n\t' + '\n\t'.join(dataset_dict.keys()))
-    for ds in args.dataset_name:
-        download(ds, args.cache, args.extract_to)
diff --git a/examples/python/reconstruction_system/scripts/download_indoor_lidar_rgbd.sh b/examples/python/reconstruction_system/scripts/download_indoor_lidar_rgbd.sh
deleted file mode 100755
index 5d37eee8410..00000000000
--- a/examples/python/reconstruction_system/scripts/download_indoor_lidar_rgbd.sh
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/usr/bin/env bash
-set -e
-
-process_scene()
-{
-    DATA_NAME=$1
-    GDRIVE_ID=$2
-    ./gdrive_download.sh $GDRIVE_ID
-    unzip --qq $DATA_NAME.zip -d ../dataset/indoor_lidar_rgbd
-    rm $DATA_NAME.zip
-}
-
-mkdir ../dataset/indoor_lidar_rgbd
-process_scene "rgbd_apartment" "1TqoIE1Q1M30q8FBQ_dMcZj9JR6G0ztI5"
-process_scene "rgbd_bedroom" "1SN318pHOQn7ioSABJLY6SQ1O7gVMDvB2"
-process_scene "rgbd_boardroom" "1gRDVGgPR--cKKHkrlaXVzc1Zj9VhC3Dr"
-process_scene "rgbd_lobby" "1MhjCJuznp3pG6zxHrIbmcjPjXhvlBStu"
-process_scene "rgbd_loft" "1OOmymidV5nhmGSdk1Y7yI_9fXxLHNPjX"
diff --git a/examples/python/reconstruction_system/scripts/download_redwood_objects.sh b/examples/python/reconstruction_system/scripts/download_redwood_objects.sh
deleted file mode 100755
index 08b2ebf687a..00000000000
--- a/examples/python/reconstruction_system/scripts/download_redwood_objects.sh
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/usr/bin/env bash
-set -e
-
-process_redwood_object()
-{
-    DATA_NUM=$1
-    DATA_NAME=$2
-    GDRIVE_ID=$3
-    ./gdrive_download.sh $GDRIVE_ID
-    unzip --qq $DATA_NUM.zip -d ../dataset/redwood_objects/$DATA_NAME
-    python synchronize_frames.py ${PWD}/../dataset/redwood_objects/$DATA_NAME
-    rm $DATA_NUM.zip
-}
-
-mkdir ../dataset/redwood_objects
-process_redwood_object "00021" "chair" "1iMxjIZMFcoL3s9FzzqM0K-tM2ehO74D0"
-process_redwood_object "00577" "sofa" "1_WZK0AZTt7N3QBh9JnDypM1sPKnE0oIY"
-process_redwood_object "01833" "car" "1HCRVzlZ0huAsTyQsjOvI2OsZ_oU3zpt9"
-process_redwood_object "05984" "motorcycle" "1jZLTNrOIP2sFgzF9sHb027iI2JhOOqpu"
-process_redwood_object "06127" "plant" "1nWilJfkAA7D3a8JEc_Tx9pLD4a25u8xG"
-process_redwood_object "06822" "truck" "1TqkWcdzQZG50ZV9nXdZYZmR_aLH-WYkr"
diff --git a/examples/python/reconstruction_system/scripts/download_redwood_simulated.sh b/examples/python/reconstruction_system/scripts/download_redwood_simulated.sh
deleted file mode 100755
index c7b40f1e9bc..00000000000
--- a/examples/python/reconstruction_system/scripts/download_redwood_simulated.sh
+++ /dev/null
@@ -1,48 +0,0 @@
-#!/usr/bin/env bash
-set -e
-
-download_redwood_scene()
-{
-    DATA_NAME=$1
-
-    # Source: http://redwood-data.org/indoor/data/$DATA_NAME-color.zip
-    wget https://github.com/isl-org/open3d_downloads/releases/download/redwood-simulated/$DATA_NAME-color.zip
-
-    # Source: http://redwood-data.org/indoor/data/$DATA_NAME-depth-clean.zip
-    wget https://github.com/isl-org/open3d_downloads/releases/download/redwood-simulated/$DATA_NAME-depth-clean.zip
-
-    # Source: http://redwood-data.org/indoor/data/$DATA_NAME-depth-simulated.zip
-    wget https://github.com/isl-org/open3d_downloads/releases/download/redwood-simulated/$DATA_NAME-depth-simulated.zip
-
-}
-
-unzip_redwood_scene()
-{
-    DATA_NAME=$1
-    DATA_TYPE=$2
-    mkdir $DATA_NAME-$DATA_TYPE
-    mkdir $DATA_NAME-$DATA_TYPE/image
-    mkdir $DATA_NAME-$DATA_TYPE/depth
-    unzip --qq $DATA_NAME-color.zip -d $DATA_NAME-$DATA_TYPE/image
-    unzip --qq $DATA_NAME-depth-$DATA_TYPE.zip -d $DATA_NAME-$DATA_TYPE/depth
-}
-
-cd .. && mkdir dataset/redwood_simulated && cd dataset/redwood_simulated
-
-download_redwood_scene "livingroom1"
-unzip_redwood_scene "livingroom1" "clean"
-# unzip_redwood_scene "livingroom1" "simulated"
-
-download_redwood_scene "livingroom2"
-unzip_redwood_scene "livingroom2" "clean"
-# unzip_redwood_scene "livingroom2" "simulated"
-
-download_redwood_scene "office1"
-unzip_redwood_scene "office1" "clean"
-# unzip_redwood_scene "office1" "simulated"
-
-download_redwood_scene "office2"
-unzip_redwood_scene "office2" "clean"
-# unzip_redwood_scene "office2" "simulated"
-
-rm *.zip
diff --git a/examples/python/reconstruction_system/scripts/download_stanford.sh b/examples/python/reconstruction_system/scripts/download_stanford.sh
deleted file mode 100755
index d0d8bf33338..00000000000
--- a/examples/python/reconstruction_system/scripts/download_stanford.sh
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/env bash
-set -e
-
-process_stanford_scene()
-{
-    DATA_NAME=$1
-    GDRIVE_ID=$2
-    ./gdrive_download.sh $GDRIVE_ID
-    unzip --qq $DATA_NAME"_png.zip" -d ../dataset/stanford/$DATA_NAME
-    rm $DATA_NAME"_png.zip"
-}
-
-mkdir ../dataset/stanford
-process_stanford_scene "burghers" "0B6qjzcYetERgUU0wMkhnZVNCa28"
-process_stanford_scene "lounge" "0B6qjzcYetERgSUZFT2FWdWsxQzQ"
-process_stanford_scene "copyroom" "0B6qjzcYetERgWTBDYWdkVHN3aHc"
-process_stanford_scene "cactusgarden" "0B6qjzcYetERgYUxUSFFIYjZIb3c"
-process_stanford_scene "stonewall" "0B6qjzcYetERgOXBCM181bTdsUGc"
-process_stanford_scene "totempole" "0B6qjzcYetERgNjVEWm5sSWFlWk0"
diff --git a/examples/python/reconstruction_system/scripts/download_tutorial.sh b/examples/python/reconstruction_system/scripts/download_tutorial.sh
deleted file mode 100755
index 376b73bd89e..00000000000
--- a/examples/python/reconstruction_system/scripts/download_tutorial.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/usr/bin/env bash
-set -e
-
-./gdrive_download.sh 1dkA6Tjh-aEie1J8qGlY1NlyJVP0_FpBX
-unzip -qq tutorial.zip
-mv tutorial ../dataset/
-rm *.zip
diff --git a/examples/python/reconstruction_system/scripts/gdrive_download.sh b/examples/python/reconstruction_system/scripts/gdrive_download.sh
deleted file mode 100755
index 8463655bd23..00000000000
--- a/examples/python/reconstruction_system/scripts/gdrive_download.sh
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/usr/bin/env bash
-set -e
-
-# gdrive_download
-#
-# script to download Google Drive files from command line
-# not guaranteed to work indefinitely
-# taken from Stack Overflow answer:
-# http://stackoverflow.com/a/38937732/7002068
-
-gURL=$1
-# match more than 26 word characters
-ggID=$(echo "$gURL" | egrep -o '(\w|-){26,}')
-
-ggURL='https://drive.google.com/uc?export=download'
-
-curl -sc /tmp/gcokie "${ggURL}&id=${ggID}" >/dev/null
-getcode="$(awk '/_warning_/ {print $NF}' /tmp/gcokie)"
-
-cmd='curl --insecure -C - -LOJb /tmp/gcokie "${ggURL}&confirm=${getcode}&id=${ggID}"'
-echo -e "Downloading from "$gURL"...\n"
-eval $cmd
diff --git a/examples/python/reconstruction_system/scripts/requirements.txt b/examples/python/reconstruction_system/scripts/requirements.txt
deleted file mode 100644
index e4f93bc60d1..00000000000
--- a/examples/python/reconstruction_system/scripts/requirements.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-opencv-python
-joblib
diff --git a/examples/python/reconstruction_system/scripts/synchronize_frames.py b/examples/python/reconstruction_system/scripts/synchronize_frames.py
deleted file mode 100644
index d5d34d921fa..00000000000
--- a/examples/python/reconstruction_system/scripts/synchronize_frames.py
+++ /dev/null
@@ -1,115 +0,0 @@
-# ----------------------------------------------------------------------------
-# -                        Open3D: www.open3d.org                            -
-# ----------------------------------------------------------------------------
-# The MIT License (MIT)
-#
-# Copyright (c) 2018-2021 www.open3d.org
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-# IN THE SOFTWARE.
-# ----------------------------------------------------------------------------
-
-# examples/python/reconstruction_system/scripts/synchronize_frames.py
-
-import math
-import os
-import sys
-import shutil
-import argparse
-
-pyexample_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
-sys.path.append(pyexample_path)
-
-from open3d_example import *
-# original code is written by Andrew. W. Chen
-# input: openni style unsynchronized color and depth images
-# output: synchronized color and depth images
-
-
-def run_synchronization(args):
-    folder_path = args.dataset
-    color_files, depth_files = get_rgbd_file_lists(folder_path)
-    if args.debug_mode:
-        print(depth_files)
-        print(color_files)
-
-    # filename format is:
-    # frame-timestamp.filetype
-    timestamps = {
-        'depth': [None] * len(depth_files),
-        'color': [None] * len(color_files)
-    }
-    for i, name in enumerate(depth_files):
-        depth_timestamp = int(
-            os.path.basename(depth_files[i]).replace('-', '.').split('.')[1])
-        timestamps['depth'][i] = depth_timestamp
-    for i, name in enumerate(color_files):
-        color_timestamp = int(
-            os.path.basename(color_files[i]).replace('-', '.').split('.')[1])
-        timestamps['color'][i] = color_timestamp
-
-    # associations' index is the color frame, and the value at
-    # that index is the best depth frame for the color frame
-    associations = []
-    depth_idx = 0
-    for i in range(len(color_files)):
-        best_dist = float('inf')
-        while depth_idx <= len(depth_files) - 1 and i <= len(color_files) - 1:
-            dist = math.fabs(timestamps['depth'][depth_idx] - \
-                    timestamps['color'][i])
-            if dist > best_dist:
-                break
-            best_dist = dist
-            depth_idx += 1
-            if depth_idx > timestamps['depth'][-1]:
-                print("Ended at color frame %d, depth frame %d" %
-                      (i, depth_idx))
-        associations.append(depth_idx - 1)
-        if args.debug_mode:
-            print("%d %d %d %d" %
-                  (i, depth_idx - 1, timestamps['depth'][depth_idx - 1],
-                   timestamps['color'][i]))
-
-    os.rename(os.path.join(folder_path, "depth"),
-              os.path.join(folder_path, "temp"))
-    if not os.path.exists(os.path.join(folder_path, "depth")):
-        os.makedirs(os.path.join(folder_path, "depth"))
-    for i, assn in enumerate(associations):
-        temp_name = os.path.join(folder_path, "temp",
-                                 os.path.basename(depth_files[assn]))
-        new_name = os.path.join(folder_path, "depth/%06d.png" % (i + 1))
-        if args.debug_mode:
-            print(temp_name)
-            print(new_name)
-        if not exists(temp_name):
-            assert (i + 1 == len(color_files))
-            os.remove(color_files[-1])
-        else:
-            os.rename(temp_name, new_name)
-    shutil.rmtree(os.path.join(folder_path, "temp"))
-
-
-if __name__ == '__main__':
-    parser = argparse.ArgumentParser(
-        description="Synchronize color and depth images")
-    parser.add_argument("dataset", help="path to the dataset")
-    parser.add_argument("--debug_mode",
-                        help="turn on debug mode",
-                        action="store_true")
-    args = parser.parse_args()
-    run_synchronization(args)
diff --git a/examples/python/t_reconstruction_system/common.py b/examples/python/t_reconstruction_system/common.py
index bbc303c22f6..e190543f078 100644
--- a/examples/python/t_reconstruction_system/common.py
+++ b/examples/python/t_reconstruction_system/common.py
@@ -26,22 +26,89 @@
 
 # examples/python/reconstruction_system/common.py
 
+import open3d as o3d
+
 import os
+import sys
+import json
 import numpy as np
-import open3d as o3d
 import glob
+from os.path import isfile, join, splitext, dirname, basename
+from warnings import warn
+
+
+def extract_rgbd_frames(rgbd_video_file):
+    """
+    Extract color and aligned depth frames and intrinsic calibration from an
+    RGBD video file (currently only RealSense bag files supported). Folder
+    structure is:
+        <directory of rgbd_video_file/<rgbd_video_file name without extension>/
+            {depth/00000.jpg,color/00000.png,intrinsic.json}
+    """
+    frames_folder = join(dirname(rgbd_video_file),
+                         basename(splitext(rgbd_video_file)[0]))
+    path_intrinsic = join(frames_folder, "intrinsic.json")
+    if isfile(path_intrinsic):
+        warn(f"Skipping frame extraction for {rgbd_video_file} since files are"
+             " present.")
+    else:
+        rgbd_video = o3d.t.io.RGBDVideoReader.create(rgbd_video_file)
+        rgbd_video.save_frames(frames_folder)
+    with open(path_intrinsic) as intr_file:
+        intr = json.load(intr_file)
+    depth_scale = intr["depth_scale"]
+    return frames_folder, path_intrinsic, depth_scale
+
+
+def lounge_dataloader(config):
+    # Get the dataset.
+    lounge_rgbd = o3d.data.LoungeRGBDImages()
+    # Override default config parameters with dataset specific parameters.
+    config.path_dataset = lounge_rgbd.extract_dir
+    config.path_trajectory = lounge_rgbd.trajectory_log_path
+    config.depth_folder = "depth"
+    config.color_folder = "color"
+    return config
+
+
+def bedroom_dataloader(config):
+    # Get the dataset.
+    bedroom_rgbd = o3d.data.BedroomRGBDImages()
+    # Override default config parameters with dataset specific parameters.
+    config.path_dataset = bedroom_rgbd.extract_dir
+    config.path_trajectory = bedroom_rgbd.trajectory_log_path
+    config.depth_folder = "depth"
+    config.color_folder = "image"
+    return config
+
+
+def jack_jack_dataloader(config):
+    # Get the dataset.
+    jackjack_rgbd = o3d.data.JackJackL515Bag()
+    # Override default config parameters with dataset specific parameters.
+    print("Extracting frames from RGBD video file")
+    config.path_dataset = jackjack_rgbd.path
+    config.depth_folder = "depth"
+    config.color_folder = "color"
+    return config
+
+
+def get_default_dataset(config):
+    print('Config file was not provided, falling back to default dataset.')
+    if config.default_dataset == 'lounge':
+        config = lounge_dataloader(config)
+    elif config.default_dataset == 'bedroom':
+        config = bedroom_dataloader(config)
+    elif config.default_dataset == 'jack_jack':
+        config = jack_jack_dataloader(config)
+    else:
+        print(
+            "The requested dataset is not available. Available dataset options include lounge and jack_jack."
+        )
+        sys.exit(1)
 
-
-def get_default_testdata():
-    example_path = os.path.abspath(
-        os.path.join(__file__, os.path.pardir, os.path.pardir, os.path.pardir))
-
-    redwood_rgbd = o3d.data.SampleRedwoodRGBDImages()
-    path_dataset = redwood_rgbd.extract_dir
-    print('Dataset not found, falling back to test examples {}'.format(
-        path_dataset))
-
-    return path_dataset
+    print('Loaded data from {}'.format(config.path_dataset))
+    return config
 
 
 def load_depth_file_names(config):
diff --git a/examples/python/t_reconstruction_system/dense_slam.py b/examples/python/t_reconstruction_system/dense_slam.py
index 8a15a2d161c..63211390c79 100644
--- a/examples/python/t_reconstruction_system/dense_slam.py
+++ b/examples/python/t_reconstruction_system/dense_slam.py
@@ -35,7 +35,7 @@
 import time
 
 from config import ConfigParser
-from common import load_rgbd_file_names, save_poses, load_intrinsic, extract_trianglemesh, get_default_testdata
+from common import get_default_dataset, load_rgbd_file_names, save_poses, load_intrinsic, extract_trianglemesh, get_default_testdata, extract_rgbd_frames
 
 
 def slam(depth_file_names, color_file_names, intrinsic, config):
@@ -93,13 +93,26 @@ def slam(depth_file_names, color_file_names, intrinsic, config):
         help='YAML config file path. Please refer to default_config.yml as a '
         'reference. It overrides the default config file, but will be '
         'overridden by other command line inputs.')
+    parser.add('--default_dataset',
+               help='Default dataset is used when config file is not provided. '
+               'Default dataset may be selected from the following options: '
+               '[lounge, bedroom, jack_jack]',
+               default='lounge')
     parser.add('--path_npz',
                help='path to the npz file that stores voxel block grid.',
                default='output.npz')
     config = parser.get_config()
 
     if config.path_dataset == '':
-        config.path_dataset = get_default_testdata()
+        config = get_default_dataset(config)
+
+    # Extract RGB-D frames and intrinsic from bag file.
+    if config.path_dataset.endswith(".bag"):
+        assert os.path.isfile(
+            config.path_dataset), (f"File {config.path_dataset} not found.")
+        print("Extracting frames from RGBD video file")
+        config.path_dataset, config.path_intrinsic, config.depth_scale = extract_rgbd_frames(
+            config.path_dataset)
 
     depth_file_names, color_file_names = load_rgbd_file_names(config)
     intrinsic = load_intrinsic(config)
diff --git a/examples/python/t_reconstruction_system/dense_slam_gui.py b/examples/python/t_reconstruction_system/dense_slam_gui.py
index 8ec8a3c38e8..ad197bd2308 100644
--- a/examples/python/t_reconstruction_system/dense_slam_gui.py
+++ b/examples/python/t_reconstruction_system/dense_slam_gui.py
@@ -29,18 +29,18 @@
 # P.S. This example is used in documentation, so, please ensure the changes are
 # synchronized.
 
+import open3d as o3d
+import open3d.core as o3c
 import open3d.visualization.gui as gui
 import open3d.visualization.rendering as rendering
 
-import open3d as o3d
-import open3d.core as o3c
 from config import ConfigParser
 
 import os, sys
 import numpy as np
 import threading
 import time
-from common import load_rgbd_file_names, save_poses, load_intrinsic, extract_trianglemesh, get_default_testdata
+from common import load_rgbd_file_names, save_poses, load_intrinsic, extract_trianglemesh, get_default_dataset, extract_rgbd_frames
 
 
 def set_enabled(widget, enable):
@@ -462,13 +462,26 @@ def update_main(self):
         help='YAML config file path. Please refer to default_config.yml as a '
         'reference. It overrides the default config file, but will be '
         'overridden by other command line inputs.')
+    parser.add('--default_dataset',
+               help='Default dataset is used when config file is not provided. '
+               'Default dataset may be selected from the following options: '
+               '[lounge, bedroom, jack_jack]',
+               default='lounge')
     parser.add('--path_npz',
                help='path to the npz file that stores voxel block grid.',
                default='output.npz')
     config = parser.get_config()
 
     if config.path_dataset == '':
-        config.path_dataset = get_default_testdata()
+        config = get_default_dataset(config)
+
+    # Extract RGB-D frames and intrinsic from bag file.
+    if config.path_dataset.endswith(".bag"):
+        assert os.path.isfile(
+            config.path_dataset), (f"File {config.path_dataset} not found.")
+        print("Extracting frames from RGBD video file")
+        config.path_dataset, config.path_intrinsic, config.depth_scale = extract_rgbd_frames(
+            config.path_dataset)
 
     app = gui.Application.instance
     app.initialize()
diff --git a/examples/python/t_reconstruction_system/integrate.py b/examples/python/t_reconstruction_system/integrate.py
index c3047aee47b..f4f95cb168f 100644
--- a/examples/python/t_reconstruction_system/integrate.py
+++ b/examples/python/t_reconstruction_system/integrate.py
@@ -119,9 +119,7 @@ def integrate(depth_file_names, color_file_names, depth_intrinsic,
     config = parser.get_config()
 
     if config.path_dataset == '':
-        config.path_dataset = get_default_testdata()
-        config.path_trajectory = os.path.join(config.path_dataset,
-                                              'trajectory.log')
+        config = get_default_testdata(config)
 
     if config.integrate_color:
         depth_file_names, color_file_names = load_rgbd_file_names(config)
diff --git a/examples/python/t_reconstruction_system/integrate_custom.py b/examples/python/t_reconstruction_system/integrate_custom.py
index ae154c96cf3..1eecbfd4bc9 100644
--- a/examples/python/t_reconstruction_system/integrate_custom.py
+++ b/examples/python/t_reconstruction_system/integrate_custom.py
@@ -37,7 +37,7 @@
 import matplotlib.pyplot as plt
 
 from config import ConfigParser
-from common import load_rgbd_file_names, load_depth_file_names, save_poses, load_intrinsic, load_extrinsics, get_default_testdata
+from common import get_default_dataset, load_rgbd_file_names, load_depth_file_names, save_poses, load_intrinsic, load_extrinsics, extract_rgbd_frames
 
 from tqdm import tqdm
 
@@ -170,6 +170,11 @@ def integrate(depth_file_names, color_file_names, intrinsic, extrinsics,
         help='YAML config file path. Please refer to default_config.yml as a '
         'reference. It overrides the default config file, but will be '
         'overridden by other command line inputs.')
+    parser.add('--default_dataset',
+               help='Default dataset is used when config file is not provided. '
+               'Default dataset may be selected from the following options: '
+               '[lounge, jack_jack]',
+               default='lounge')
     parser.add('--integrate_color', action='store_true')
     parser.add('--path_trajectory',
                help='path to the trajectory .log or .json file.')
@@ -179,9 +184,15 @@ def integrate(depth_file_names, color_file_names, intrinsic, extrinsics,
     config = parser.get_config()
 
     if config.path_dataset == '':
-        config.path_dataset = get_default_testdata()
-        config.path_trajectory = os.path.join(config.path_dataset,
-                                              'trajectory.log')
+        config = get_default_dataset(config)
+
+    # Extract RGB-D frames and intrinsic from bag file.
+    if config.path_dataset.endswith(".bag"):
+        assert os.path.isfile(
+            config.path_dataset), (f"File {config.path_dataset} not found.")
+        print("Extracting frames from RGBD video file")
+        config.path_dataset, config.path_intrinsic, config.depth_scale = extract_rgbd_frames(
+            config.path_dataset)
 
     if config.integrate_color:
         depth_file_names, color_file_names = load_rgbd_file_names(config)
diff --git a/examples/python/t_reconstruction_system/ray_casting.py b/examples/python/t_reconstruction_system/ray_casting.py
index cd4f5ec5da2..50e4c690a57 100644
--- a/examples/python/t_reconstruction_system/ray_casting.py
+++ b/examples/python/t_reconstruction_system/ray_casting.py
@@ -38,7 +38,7 @@
 
 from tqdm import tqdm
 from config import ConfigParser
-from common import load_depth_file_names, load_intrinsic, load_extrinsics, get_default_testdata
+from common import load_depth_file_names, load_intrinsic, load_extrinsics, get_default_dataset, extract_rgbd_frames
 import matplotlib.pyplot as plt
 import numpy as np
 
@@ -50,7 +50,11 @@
         help='YAML config file path. Please refer to default_config.yml as a '
         'reference. It overrides the default config file, but will be '
         'overridden by other command line inputs.')
-
+    parser.add('--default_dataset',
+               help='Default dataset is used when config file is not provided. '
+               'Default dataset may be selected from the following options: '
+               '[lounge, jack_jack]',
+               default='lounge')
     parser.add('--path_trajectory',
                help='path to the trajectory .log or .json file.')
     parser.add('--path_npz',
@@ -59,9 +63,15 @@
     config = parser.get_config()
 
     if config.path_dataset == '':
-        config.path_dataset = get_default_testdata()
-        config.path_trajectory = os.path.join(config.path_dataset,
-                                              'trajectory.log')
+        config = get_default_dataset(config)
+
+    # Extract RGB-D frames and intrinsic from bag file.
+    if config.path_dataset.endswith(".bag"):
+        assert os.path.isfile(
+            config.path_dataset), (f"File {config.path_dataset} not found.")
+        print("Extracting frames from RGBD video file")
+        config.path_dataset, config.path_intrinsic, config.depth_scale = extract_rgbd_frames(
+            config.path_dataset)
 
     vbg = o3d.t.geometry.VoxelBlockGrid.load(config.path_npz)
     depth_file_names = load_depth_file_names(config)