Compare commits

...
Author SHA1 Message Date
matlabbe 366a4a0174 merged master->jazzy 2025-06-08 15:52:25 -07:00
matlabbe dbfc4b1dad bump ros package version 2025-06-08 15:50:36 -07:00
matlabbe 1f44d23a08 CI: moving back opengv to deps image 2025-06-08 14:43:39 -07:00
matlabbe 332dde6d74 Fixed icp_odometry freezing 2025-06-07 16:47:40 -07:00
matlabbe 80d463ed20 docker CI: removed armv7 focal build 2025-06-07 10:49:30 -07:00
matlabbe e19b0c3dc4 docker: use -j2 instead of -j4 for jammy-deps (CI freezing) 2025-06-04 11:43:07 -07:00
matlabbe 6d73ba46e2 docker: fixed noble-deps noble-kilted-deps 2025-06-03 20:45:56 -07:00
matlabbe a6b71f4716 docker: remove some COPY to avoid invalidating cache 2025-06-03 20:37:08 -07:00
matlabbe 47e49207ad CI: fixed docker focal-deps missing ros key 2025-06-01 19:11:30 -07:00
matlabbe 2a5af18bf2 CI: more updates 2025-06-01 18:48:59 -07:00
matlabbe 41684644a1 CI: re-enabled docker-deps 2025-06-01 18:38:41 -07:00
matlabbe 7b69bf6696 CI: added kilted, re-enabled deps, removed all nproc variables 2025-06-01 18:36:36 -07:00
matlabbe 6d4e8a4173 New feature: Depth confidence (#1520)
* New feature: Depth confidence

* iOS app updated to save depth confidence, added util2d::depthBleedingFiltering function

* Updated tools to show/extract depth confidence

* Android: moved smoothing in post-processing, fixed confidence registration, added depth bleeding error option.

* Fixed warning

* removed debug log

* Added new feature types, fixed rendering when exporting texture >4096 (#1469), added depth bleeding filter option to iOS

* fixed some warnings, android: added bleeding error option

* CI: try updating ros2 key

* added sudo

* antoher test

* bump ios app version
2025-06-01 14:14:29 -07:00
matlabbe 90d195237f CI: added rolling for cmake-ros workflow 2025-05-26 16:22:25 -07:00
matlabbe 9394c0a170 Export Bundler: Fixed custom matching parameters not used when ba iteration >=1 2025-05-26 13:27:55 -07:00
matlabbe 6781930100 fixed typo 2025-05-26 09:54:53 -07:00
matlabbe 9e862cec68 iOS: updated xcode project 2025-05-26 09:01:30 -07:00
matlabbe eb2a8f132c iOS: updated g2o patch to find correctly cholmod 2025-05-26 08:53:04 -07:00
matlabbe 7a317b9f39 iOS added suitesparse dependency for g2o 2025-05-25 21:01:41 -07:00
matlabbe f5f51bc792 Fixed iOS build for XCode 16.3 (#1482 #1491) 2025-05-25 20:35:57 -07:00
Torjus Ivelandandmatlabbe 683a1dc554 Handle edge case when SuperPoint detects only 1 keypoint (#1509)
* Handle edge case when SuperPoint detects only 1 keypoint

* missing normalize

---------

Co-authored-by: matlabbe <matlabbe@gmail.com>
2025-05-24 15:38:44 -07:00
matlabbe 478e909742 Fix 6DoF graph angular check (#1511)
* Fix 6DoF graph angular check

* Updated getAngle to use better version
2025-05-24 13:25:26 -07:00
matlabbe a02621ef30 Export Bundler: added 0 iteration support (no optimization) 2025-05-18 13:57:26 -07:00
matlabbe 43d2e1bfde rtabmap-export: add --poses_landmark option 2025-05-18 12:40:41 -07:00
matlabbe 802b8f9870 Add/Refine/SBA: create Registration only once to avoid internal initialization for every link refined, added or rematched (e.g., SuperPoint or SuperGlue). 2025-05-17 16:34:31 -07:00
matlabbe f03139d4ff Update rtabmap_superpoint.py 2025-05-17 14:20:39 -07:00
matlabbe 96f8466fa7 Update rtabmap_superpoint.py 2025-05-17 14:16:13 -07:00
matlabbe 5b368fb2f1 Fixed DataRecorder UI asserting if data without images is received (in case of monocular or lidar-only recording). rtabmap-dataRecorder: added auto-close when end of stream is reached. rtabmap-reprocess: added ability to process images without odometry and to record localization poses with -p option in localizatiion mode. 2025-05-11 18:37:35 -07:00
matlabbe a3d4028faa Camera projection: Added max depth error option to colorize more points 2025-05-10 18:20:29 -07:00
Petr Hodinaandmatlabbe 6b5b1c9617 Fix ctor (#1496)
* CI: only build noetic in noetic-devel branch

* fix ctor and dtor warning for UThreadC

* revert CI changes

---------

Co-authored-by: matlabbe <matlabbe@gmail.com>
2025-05-03 11:24:55 -07:00
matlabbe 087a2cecd8 New parameter: RGBD/LocalizationSecondTryWithoutProximityLinks (#1499)
* Added parameter RGBD/LocalizationSecondTryWithoutProximityLinks

* Statistics: added new stat to know when proximity links are removed after a successful second loc try

* changed kLoopProximity_links_cleared for a count instead of bool

* Updating odomCachePoses with optimization for better visualization
2025-05-02 10:35:31 -07:00
matlabbe d2a430ce57 Export: updated usage of --cam_projection_decimation 2025-05-01 20:44:29 -07:00
matlabbe 26f036173d export: fixed texture_depth_error=-1 2025-04-29 21:50:11 -07:00
matlabbe 16e21697f8 reprocess: fixed -cam_tf option when -cam option is not used at the same time 2025-04-28 15:23:12 -07:00
matlabbe d4e55c3a1d Merge branch 'master' of github.com:introlab/rtabmap into jazzy-devel 2025-02-12 19:47:19 -08:00
matlabbe 0445ae7c33 mergd master, disabled grid_map_core for jazzy 2024-11-30 19:51:41 -08:00
matlabbe ce1e91b9f1 Just build jazzy in jazzy-devel branch 2024-11-30 18:28:31 -08:00
matlabbe a19163fc75 CI: use contains 2024-11-30 18:11:51 -08:00
matlabbe eba90c1869 Merge branch 'master' of github.com:introlab/rtabmap into jazzy-devel 2024-11-30 18:07:10 -08:00
matlabbe 4af0e7dbea grid_core_map now available on jazzy 2024-11-30 17:38:43 -08:00
matlabbe 344fe4e4cf Merge branch 'master' of github.com:introlab/rtabmap into jazzy-devel 2024-11-30 17:31:59 -08:00
matlabbe 5e79fc559b merged master->jazzy 2024-07-22 20:59:09 -07:00
matlabbe 04fdc0d9e2 Merge branch 'jazzy-devel' of github.com:introlab/rtabmap into jazzy-devel 2024-06-30 19:50:45 -07:00
matlabbe f2df35be01 Disabling gtsam ros dep for now (internal version error) for ROS2 Jazzy 2024-06-02 14:06:16 -07:00
matlabbe da9ff08198 Removed grid_map_core missing dep on jazzy 2024-05-27 10:49:18 -07:00
88 changed files with 3792 additions and 2001 deletions
+13 -4
View File
@@ -3,7 +3,7 @@ name: CMake-ROS
on: on:
push: push:
branches: branches:
- master - jazzy-devel
pull_request: pull_request:
branches: branches:
- '**' - '**'
@@ -23,14 +23,23 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
ros_distribution: [ humble, jazzy ] ros_distribution: [jazzy]
include: include:
- ros_distribution: 'humble'
os: ubuntu-22.04
- ros_distribution: 'jazzy' - ros_distribution: 'jazzy'
os: ubuntu-24.04 os: ubuntu-24.04
steps: steps:
- name: Setup ROS2
# https://docs.ros.org/en/humble/Installation/Ubuntu-Install-Debs.html
run: |
sudo apt install software-properties-common
sudo add-apt-repository universe
sudo apt update && sudo apt install curl -y
export ROS_APT_SOURCE_VERSION=$(curl -s https://api.github.com/repos/ros-infrastructure/ros-apt-source/releases/latest | grep -F "tag_name" | awk -F\" '{print $4}')
curl -L -o /tmp/ros2-apt-source.deb "https://github.com/ros-infrastructure/ros-apt-source/releases/download/${ROS_APT_SOURCE_VERSION}/ros2-apt-source_${ROS_APT_SOURCE_VERSION}.$(. /etc/os-release && echo $VERSION_CODENAME)_all.deb"
sudo apt install /tmp/ros2-apt-source.deb
sudo apt update
- uses: ros-tooling/setup-ros@v0.7 - uses: ros-tooling/setup-ros@v0.7
with: with:
required-ros-distributions: ${{ matrix.ros_distribution }} required-ros-distributions: ${{ matrix.ros_distribution }}
+20 -20
View File
@@ -15,14 +15,14 @@ jobs:
# $ sudo apt-get upgrade qemu-user-static # $ sudo apt-get upgrade qemu-user-static
# $ docker run --rm --privileged multiarch/qemu-user-static --reset -p yes -c yes # $ docker run --rm --privileged multiarch/qemu-user-static --reset -p yes -c yes
# More info: https://github.com/introlab/rtabmap/issues/1454 # More info: https://github.com/introlab/rtabmap/issues/1454
if: false # if: false
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
docker_tag: [focal-deps, jammy-deps, jammy-iron-deps, noble-deps] docker_tag: [focal-deps, jammy-deps, noble-deps, noble-kilted-deps]
include: include:
- docker_tag: focal-deps - docker_tag: focal-deps
docker_tags: | docker_tags: |
@@ -30,7 +30,6 @@ jobs:
docker_platforms: | docker_platforms: |
linux/amd64 linux/amd64
linux/arm64 linux/arm64
linux/arm/v7
docker_path: 'focal/deps' docker_path: 'focal/deps'
- docker_tag: jammy-deps - docker_tag: jammy-deps
docker_tags: | docker_tags: |
@@ -39,12 +38,6 @@ jobs:
linux/amd64 linux/amd64
linux/arm64 linux/arm64
docker_path: 'jammy/deps' docker_path: 'jammy/deps'
- docker_tag: jammy-iron-deps
docker_tags: |
introlab3it/rtabmap:jammy-iron-deps
docker_platforms: |
linux/amd64
docker_path: 'jammy-iron/deps'
- docker_tag: noble-deps - docker_tag: noble-deps
docker_tags: | docker_tags: |
introlab3it/rtabmap:noble-deps introlab3it/rtabmap:noble-deps
@@ -52,6 +45,13 @@ jobs:
linux/amd64 linux/amd64
linux/arm64 linux/arm64
docker_path: 'noble/deps' docker_path: 'noble/deps'
- docker_tag: noble-kilted-deps
docker_tags: |
introlab3it/rtabmap:noble-kilted-deps
docker_platforms: |
linux/amd64
linux/arm64
docker_path: 'noble-kilted/deps'
steps: steps:
- -
@@ -84,13 +84,13 @@ jobs:
cache-to: type=inline cache-to: type=inline
docker: docker:
#needs: docker_deps needs: docker_deps
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
docker_tag: [bionic, focal, jammy, jammy-iron, noble, android23, android24, android26, android30] docker_tag: [bionic, focal, jammy, noble, noble-kilted, android23, android24, android26, android30]
include: include:
- docker_tag: bionic - docker_tag: bionic
docker_tags: | docker_tags: |
@@ -112,7 +112,6 @@ jobs:
docker_platforms: | docker_platforms: |
linux/amd64 linux/amd64
linux/arm64 linux/arm64
linux/arm/v7
docker_path: 'focal' docker_path: 'focal'
- docker_tag: jammy - docker_tag: jammy
docker_tags: | docker_tags: |
@@ -124,14 +123,6 @@ jobs:
linux/amd64 linux/amd64
linux/arm64 linux/arm64
docker_path: 'jammy' docker_path: 'jammy'
- docker_tag: jammy-iron
docker_tags: |
introlab3it/rtabmap:jammy-iron
docker_args: |
NOT_USED=0
docker_platforms: |
linux/amd64
docker_path: 'jammy-iron'
- docker_tag: noble - docker_tag: noble
docker_tags: | docker_tags: |
introlab3it/rtabmap:noble introlab3it/rtabmap:noble
@@ -142,6 +133,15 @@ jobs:
linux/amd64 linux/amd64
linux/arm64 linux/arm64
docker_path: 'noble' docker_path: 'noble'
- docker_tag: noble-kilted
docker_tags: |
introlab3it/rtabmap:noble-kilted
docker_args: |
NOT_USED=0
docker_platforms: |
linux/amd64
linux/arm64
docker_path: 'noble-kilted'
- docker_tag: android23 - docker_tag: android23
docker_tags: | docker_tags: |
introlab3it/rtabmap:android23 introlab3it/rtabmap:android23
+2 -2
View File
@@ -19,8 +19,8 @@ SET(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake_modules")
# VERSION # VERSION
####################### #######################
SET(RTABMAP_MAJOR_VERSION 0) SET(RTABMAP_MAJOR_VERSION 0)
SET(RTABMAP_MINOR_VERSION 21) SET(RTABMAP_MINOR_VERSION 22)
SET(RTABMAP_PATCH_VERSION 13) SET(RTABMAP_PATCH_VERSION 0)
SET(RTABMAP_VERSION SET(RTABMAP_VERSION
${RTABMAP_MAJOR_VERSION}.${RTABMAP_MINOR_VERSION}.${RTABMAP_PATCH_VERSION}) ${RTABMAP_MAJOR_VERSION}.${RTABMAP_MINOR_VERSION}.${RTABMAP_PATCH_VERSION})
+2 -2
View File
@@ -37,8 +37,8 @@ namespace rtabmap {
////////////////////////////// //////////////////////////////
// CameraARCore // CameraARCore
////////////////////////////// //////////////////////////////
CameraARCore::CameraARCore(void* env, void* context, void* activity, bool depthFromMotion, bool smoothing, float upstreamRelocalizationAccThr): CameraARCore::CameraARCore(void* env, void* context, void* activity, bool depthFromMotion, float upstreamRelocalizationAccThr):
CameraMobile(smoothing, upstreamRelocalizationAccThr), CameraMobile(upstreamRelocalizationAccThr),
env_(env), env_(env),
context_(context), context_(context),
activity_(activity), activity_(activity),
+1 -1
View File
@@ -50,7 +50,7 @@ namespace rtabmap {
class CameraARCore : public CameraMobile { class CameraARCore : public CameraMobile {
public: public:
CameraARCore(void* env, void* context, void* activity, bool depthFromMotion = false, bool smoothing = false, float upstreamRelocalizationAccThr = 0.0f); CameraARCore(void* env, void* context, void* activity, bool depthFromMotion = false, float upstreamRelocalizationAccThr = 0.0f);
virtual ~CameraARCore(); virtual ~CameraARCore();
virtual void setScreenRotationAndSize(ScreenRotation colorCameraToDisplayRotation, int width, int height); virtual void setScreenRotationAndSize(ScreenRotation colorCameraToDisplayRotation, int width, int height);
+2 -2
View File
@@ -40,8 +40,8 @@ namespace rtabmap {
////////////////////////////// //////////////////////////////
// CameraAREngine // CameraAREngine
////////////////////////////// //////////////////////////////
CameraAREngine::CameraAREngine(void* env, void* context, void* activity, bool smoothing, float upstreamRelocalizationAccThr): CameraAREngine::CameraAREngine(void* env, void* context, void* activity, float upstreamRelocalizationAccThr):
CameraMobile(smoothing, upstreamRelocalizationAccThr), CameraMobile(upstreamRelocalizationAccThr),
env_(env), env_(env),
context_(context), context_(context),
activity_(activity), activity_(activity),
+1 -1
View File
@@ -46,7 +46,7 @@ namespace rtabmap {
class CameraAREngine : public CameraMobile { class CameraAREngine : public CameraMobile {
public: public:
CameraAREngine(void* env, void* context, void* activity, bool smoothing = false, float upstreamRelocalizationAccThr = 0.0f); CameraAREngine(void* env, void* context, void* activity, float upstreamRelocalizationAccThr = 0.0f);
virtual ~CameraAREngine(); virtual ~CameraAREngine();
virtual void setScreenRotationAndSize(ScreenRotation colorCameraToDisplayRotation, int width, int height); virtual void setScreenRotationAndSize(ScreenRotation colorCameraToDisplayRotation, int width, int height);
+130 -123
View File
@@ -41,9 +41,6 @@ namespace rtabmap {
////////////////////////////// //////////////////////////////
// CameraMobile // CameraMobile
////////////////////////////// //////////////////////////////
const float CameraMobile::bilateralFilteringSigmaS = 2.0f;
const float CameraMobile::bilateralFilteringSigmaR = 0.075f;
const rtabmap::Transform CameraMobile::opticalRotation = Transform( const rtabmap::Transform CameraMobile::opticalRotation = Transform(
0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
-1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
@@ -53,13 +50,12 @@ const rtabmap::Transform CameraMobile::opticalRotationInv = Transform(
0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f,
1.0f, 0.0f, 0.0f, 0.0f); 1.0f, 0.0f, 0.0f, 0.0f);
CameraMobile::CameraMobile(bool smoothing, float upstreamRelocalizationAccThr) : CameraMobile::CameraMobile(float upstreamRelocalizationAccThr) :
Camera(10), Camera(10),
deviceTColorCamera_(Transform::getIdentity()), deviceTColorCamera_(Transform::getIdentity()),
textureId_(0), textureId_(0),
uvs_initialized_(false), uvs_initialized_(false),
stampEpochOffset_(0.0), stampEpochOffset_(0.0),
smoothing_(smoothing),
colorCameraToDisplayRotation_(ROTATION_0), colorCameraToDisplayRotation_(ROTATION_0),
originUpdate_(true), originUpdate_(true),
upstreamRelocalizationAccThr_(upstreamRelocalizationAccThr), upstreamRelocalizationAccThr_(upstreamRelocalizationAccThr),
@@ -394,124 +390,135 @@ SensorData CameraMobile::updateDataOnRender(Transform & pose)
void CameraMobile::postUpdate() void CameraMobile::postUpdate()
{ {
if(data_.isValid()) if(data_.isValid())
{ {
// adjust origin // adjust origin
if(!originOffset_.isNull()) if(!originOffset_.isNull())
{ {
dataPose_ = originOffset_ * dataPose_; dataPose_ = originOffset_ * dataPose_;
viewMatrix_ = glm::inverse(rtabmap::glmFromTransform(rtabmap::opengl_world_T_rtabmap_world * originOffset_ *rtabmap::rtabmap_world_T_opengl_world)*glm::inverse(viewMatrix_)); viewMatrix_ = glm::inverse(rtabmap::glmFromTransform(rtabmap::opengl_world_T_rtabmap_world * originOffset_ *rtabmap::rtabmap_world_T_opengl_world)*glm::inverse(viewMatrix_));
occlusionModel_.setLocalTransform(originOffset_ * occlusionModel_.localTransform()); occlusionModel_.setLocalTransform(originOffset_ * occlusionModel_.localTransform());
} }
if(lastKnownGPS_.stamp() > 0.0 && data_.stamp()-lastKnownGPS_.stamp()<1.0) if(lastKnownGPS_.stamp() > 0.0 && data_.stamp()-lastKnownGPS_.stamp()<1.0)
{ {
data_.setGPS(lastKnownGPS_); data_.setGPS(lastKnownGPS_);
} }
else if(lastKnownGPS_.stamp()>0.0) else if(lastKnownGPS_.stamp()>0.0)
{ {
LOGD("GPS too old (current time=%f, gps time = %f)", data_.stamp(), lastKnownGPS_.stamp()); LOGD("GPS too old (current time=%f, gps time = %f)", data_.stamp(), lastKnownGPS_.stamp());
} }
if(lastEnvSensors_.size()) if(lastEnvSensors_.size())
{ {
data_.setEnvSensors(lastEnvSensors_); data_.setEnvSensors(lastEnvSensors_);
lastEnvSensors_.clear(); lastEnvSensors_.clear();
} }
if(smoothing_ && !data_.depthRaw().empty())
{ // Rotate image depending on the camera orientation
//UTimer t; if(colorCameraToDisplayRotation_ == ROTATION_90)
data_.setDepthOrRightRaw(rtabmap::util2d::fastBilateralFiltering(data_.depthRaw(), bilateralFilteringSigmaS, bilateralFilteringSigmaR)); {
//LOGD("Bilateral filtering, time=%fs", t.ticks()); UDEBUG("ROTATION_90");
} cv::Mat rgb, depth, confidence;
cv::Mat rgbt;
// Rotate image depending on the camera orientation cv::flip(data_.imageRaw(),rgb,1);
if(colorCameraToDisplayRotation_ == ROTATION_90) cv::transpose(rgb,rgbt);
{ rgb = rgbt;
UDEBUG("ROTATION_90"); cv::Mat deptht;
cv::Mat rgb, depth; cv::flip(data_.depthRaw(),depth,1);
cv::Mat rgbt(data_.imageRaw().cols, data_.imageRaw().rows, data_.imageRaw().type()); cv::transpose(depth,deptht);
cv::flip(data_.imageRaw(),rgb,1); depth = deptht;
cv::transpose(rgb,rgbt); if(!data_.depthConfidenceRaw().empty()) {
rgb = rgbt; cv::Mat conft;
cv::Mat deptht(data_.depthRaw().cols, data_.depthRaw().rows, data_.depthRaw().type()); cv::flip(data_.depthConfidenceRaw(),confidence,1);
cv::flip(data_.depthRaw(),depth,1); cv::transpose(confidence,conft);
cv::transpose(depth,deptht); confidence = conft;
depth = deptht; }
CameraModel model = data_.cameraModels()[0]; CameraModel model = data_.cameraModels()[0];
cv::Size sizet(model.imageHeight(), model.imageWidth()); cv::Size sizet(model.imageHeight(), model.imageWidth());
model = CameraModel( model = CameraModel(
model.fy(), model.fy(),
model.fx(), model.fx(),
model.cy(), model.cy(),
model.cx()>0?model.imageWidth()-model.cx():0, model.cx()>0?model.imageWidth()-model.cx():0,
model.localTransform()*rtabmap::Transform(0,-1,0,0, 1,0,0,0, 0,0,1,0)); model.localTransform()*rtabmap::Transform(0,-1,0,0, 1,0,0,0, 0,0,1,0));
model.setImageSize(sizet); model.setImageSize(sizet);
data_.setRGBDImage(rgb, depth, model); data_.setRGBDImage(rgb, depth, confidence, model);
std::vector<cv::KeyPoint> keypoints = data_.keypoints(); std::vector<cv::KeyPoint> keypoints = data_.keypoints();
for(size_t i=0; i<keypoints.size(); ++i) for(size_t i=0; i<keypoints.size(); ++i)
{ {
keypoints[i].pt.x = data_.keypoints()[i].pt.y; keypoints[i].pt.x = data_.keypoints()[i].pt.y;
keypoints[i].pt.y = rgb.rows - data_.keypoints()[i].pt.x; keypoints[i].pt.y = rgb.rows - data_.keypoints()[i].pt.x;
} }
data_.setFeatures(keypoints, data_.keypoints3D(), cv::Mat()); data_.setFeatures(keypoints, data_.keypoints3D(), cv::Mat());
} }
else if(colorCameraToDisplayRotation_ == ROTATION_180) else if(colorCameraToDisplayRotation_ == ROTATION_180)
{ {
UDEBUG("ROTATION_180"); UDEBUG("ROTATION_180");
cv::Mat rgb, depth; cv::Mat rgb, depth, confidence;
cv::flip(data_.imageRaw(),rgb,1); cv::flip(data_.imageRaw(),rgb,1);
cv::flip(rgb,rgb,0); cv::flip(rgb,rgb,0);
cv::flip(data_.depthOrRightRaw(),depth,1); cv::flip(data_.depthOrRightRaw(),depth,1);
cv::flip(depth,depth,0); cv::flip(depth,depth,0);
CameraModel model = data_.cameraModels()[0]; if(!data_.depthConfidenceRaw().empty()) {
cv::Size sizet(model.imageWidth(), model.imageHeight()); cv::flip(data_.depthConfidenceRaw(),confidence,1);
model = CameraModel( cv::flip(confidence,confidence,0);
model.fx(), }
model.fy(), CameraModel model = data_.cameraModels()[0];
model.cx()>0?model.imageWidth()-model.cx():0, cv::Size sizet(model.imageWidth(), model.imageHeight());
model.cy()>0?model.imageHeight()-model.cy():0, model = CameraModel(
model.localTransform()*rtabmap::Transform(0,0,0,0,0,1,0)); model.fx(),
model.setImageSize(sizet); model.fy(),
data_.setRGBDImage(rgb, depth, model); model.cx()>0?model.imageWidth()-model.cx():0,
model.cy()>0?model.imageHeight()-model.cy():0,
std::vector<cv::KeyPoint> keypoints = data_.keypoints(); model.localTransform()*rtabmap::Transform(0,0,0,0,0,1,0));
for(size_t i=0; i<keypoints.size(); ++i) model.setImageSize(sizet);
{ data_.setRGBDImage(rgb, depth, confidence, model);
keypoints[i].pt.x = rgb.cols - data_.keypoints()[i].pt.x;
keypoints[i].pt.y = rgb.rows - data_.keypoints()[i].pt.y; std::vector<cv::KeyPoint> keypoints = data_.keypoints();
} for(size_t i=0; i<keypoints.size(); ++i)
data_.setFeatures(keypoints, data_.keypoints3D(), cv::Mat()); {
} keypoints[i].pt.x = rgb.cols - data_.keypoints()[i].pt.x;
else if(colorCameraToDisplayRotation_ == ROTATION_270) keypoints[i].pt.y = rgb.rows - data_.keypoints()[i].pt.y;
{ }
UDEBUG("ROTATION_270"); data_.setFeatures(keypoints, data_.keypoints3D(), cv::Mat());
cv::Mat rgb(data_.imageRaw().cols, data_.imageRaw().rows, data_.imageRaw().type()); }
cv::transpose(data_.imageRaw(),rgb); else if(colorCameraToDisplayRotation_ == ROTATION_270)
cv::flip(rgb,rgb,1); {
cv::Mat depth(data_.depthOrRightRaw().cols, data_.depthOrRightRaw().rows, data_.depthOrRightRaw().type()); UDEBUG("ROTATION_270");
cv::transpose(data_.depthOrRightRaw(),depth); cv::Mat rgb, depth, confidence;
cv::flip(depth,depth,1); cv::transpose(data_.imageRaw(),rgb);
CameraModel model = data_.cameraModels()[0]; cv::flip(rgb,rgb,1);
cv::Size sizet(model.imageHeight(), model.imageWidth()); cv::transpose(data_.depthOrRightRaw(),depth);
model = CameraModel( cv::flip(depth,depth,1);
model.fy(), if(!data_.depthConfidenceRaw().empty()) {
model.fx(), cv::transpose(data_.depthConfidenceRaw(),confidence);
model.cy()>0?model.imageHeight()-model.cy():0, cv::flip(confidence,confidence,1);
model.cx(), }
model.localTransform()*rtabmap::Transform(0,1,0,0, -1,0,0,0, 0,0,1,0)); CameraModel model = data_.cameraModels()[0];
model.setImageSize(sizet); cv::Size sizet(model.imageHeight(), model.imageWidth());
data_.setRGBDImage(rgb, depth, model); model = CameraModel(
model.fy(),
std::vector<cv::KeyPoint> keypoints = data_.keypoints(); model.fx(),
for(size_t i=0; i<keypoints.size(); ++i) model.cy()>0?model.imageHeight()-model.cy():0,
{ model.cx(),
keypoints[i].pt.x = rgb.cols - data_.keypoints()[i].pt.y; model.localTransform()*rtabmap::Transform(0,1,0,0, -1,0,0,0, 0,0,1,0));
keypoints[i].pt.y = data_.keypoints()[i].pt.x; model.setImageSize(sizet);
} data_.setRGBDImage(rgb, depth, confidence, model);
data_.setFeatures(keypoints, data_.keypoints3D(), cv::Mat());
} std::vector<cv::KeyPoint> keypoints = data_.keypoints();
for(size_t i=0; i<keypoints.size(); ++i)
{
keypoints[i].pt.x = rgb.cols - data_.keypoints()[i].pt.y;
keypoints[i].pt.y = data_.keypoints()[i].pt.x;
}
data_.setFeatures(keypoints, data_.keypoints3D(), cv::Mat());
}
else
{
UDEBUG("ROTATION_0");
}
} }
} }
+1 -6
View File
@@ -70,9 +70,6 @@ private:
class CameraMobile : public Camera, public UEventsSender { class CameraMobile : public Camera, public UEventsSender {
public: public:
static const float bilateralFilteringSigmaS;
static const float bilateralFilteringSigmaR;
static const rtabmap::Transform opticalRotation; static const rtabmap::Transform opticalRotation;
static const rtabmap::Transform opticalRotationInv; static const rtabmap::Transform opticalRotationInv;
@@ -87,7 +84,7 @@ public:
int kptsSize = 3); int kptsSize = 3);
public: public:
CameraMobile(bool smoothing = false, float upstreamRelocalizationAccThr = 0.0f); CameraMobile(float upstreamRelocalizationAccThr = 0.0f);
virtual ~CameraMobile(); virtual ~CameraMobile();
// abstract functions // abstract functions
@@ -110,7 +107,6 @@ public:
const CameraModel & getCameraModel() const {return model_;} const CameraModel & getCameraModel() const {return model_;}
const Transform & getDeviceTColorCamera() const {return deviceTColorCamera_;} const Transform & getDeviceTColorCamera() const {return deviceTColorCamera_;}
void setSmoothing(bool enabled) {smoothing_ = enabled;}
virtual void setScreenRotationAndSize(ScreenRotation colorCameraToDisplayRotation, int width, int height) {colorCameraToDisplayRotation_ = colorCameraToDisplayRotation;} virtual void setScreenRotationAndSize(ScreenRotation colorCameraToDisplayRotation, int width, int height) {colorCameraToDisplayRotation_ = colorCameraToDisplayRotation;}
void setGPS(const GPS & gps); void setGPS(const GPS & gps);
void addEnvSensor(int type, float value); void addEnvSensor(int type, float value);
@@ -144,7 +140,6 @@ protected:
private: private:
bool firstFrame_; bool firstFrame_;
double stampEpochOffset_; double stampEpochOffset_;
bool smoothing_;
ScreenRotation colorCameraToDisplayRotation_; ScreenRotation colorCameraToDisplayRotation_;
GPS lastKnownGPS_; GPS lastKnownGPS_;
EnvSensors lastEnvSensors_; EnvSensors lastEnvSensors_;
+1 -2
View File
@@ -114,8 +114,7 @@ void onTangoEventAvailableRouter(void* context, const TangoEvent* event)
////////////////////////////// //////////////////////////////
// CameraTango // CameraTango
////////////////////////////// //////////////////////////////
CameraTango::CameraTango(bool colorCamera, int decimation, bool publishRawScan, bool smoothing) : CameraTango::CameraTango(bool colorCamera, int decimation, bool publishRawScan) :
CameraMobile(smoothing),
tango_config_(0), tango_config_(0),
colorCamera_(colorCamera), colorCamera_(colorCamera),
decimation_(decimation), decimation_(decimation),
+1 -1
View File
@@ -45,7 +45,7 @@ namespace rtabmap {
class CameraTango : public CameraMobile { class CameraTango : public CameraMobile {
public: public:
CameraTango(bool colorCamera, int decimation, bool publishRawScan, bool smoothing); CameraTango(bool colorCamera, int decimation, bool publishRawScan);
virtual ~CameraTango(); virtual ~CameraTango();
virtual bool init(const std::string & calibrationFolder = ".", const std::string & cameraName = ""); virtual bool init(const std::string & calibrationFolder = ".", const std::string & cameraName = "");
+169 -55
View File
@@ -84,6 +84,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
const int g_optMeshId = -100; const int g_optMeshId = -100;
const float g_bilateralFilteringSigmaS = 2.0f;
const float g_bilateralFilteringSigmaR = 0.075f;
#ifdef __ANDROID__ #ifdef __ANDROID__
static JavaVM *jvm; static JavaVM *jvm;
static jobject RTABMapActivity = 0; static jobject RTABMapActivity = 0;
@@ -230,6 +233,7 @@ RTABMapApp::RTABMapApp() :
trajectoryMode_(false), trajectoryMode_(false),
rawScanSaved_(false), rawScanSaved_(false),
smoothing_(true), smoothing_(true),
depthBleedingError_(0.0f),
depthFromMotion_(false), depthFromMotion_(false),
cameraColor_(true), cameraColor_(true),
fullResolution_(false), fullResolution_(false),
@@ -245,7 +249,11 @@ RTABMapApp::RTABMapApp() :
maxGainRadius_(0.02f), maxGainRadius_(0.02f),
renderingTextureDecimation_(4), renderingTextureDecimation_(4),
backgroundColor_(0.2f), backgroundColor_(0.2f),
depthConfidence_(2), #ifndef RTABMAP_ARCORE
depthConfidence_(100), // iOS
#else
depthConfidence_(0),
#endif
upstreamRelocalizationMaxAcc_(0.0f), upstreamRelocalizationMaxAcc_(0.0f),
exportPointCloudFormat_("ply"), exportPointCloudFormat_("ply"),
dataRecorderMode_(false), dataRecorderMode_(false),
@@ -266,20 +274,20 @@ RTABMapApp::RTABMapApp() :
lastPoseEventTime_(0.0), lastPoseEventTime_(0.0),
visualizingMesh_(false), visualizingMesh_(false),
exportedMeshUpdated_(false), exportedMeshUpdated_(false),
optTextureMesh_(new pcl::TextureMesh),
optRefId_(0),
optRefPose_(0),
measuresUpdated_(false), measuresUpdated_(false),
targetPoint_(new pcl::PointCloud<pcl::PointXYZRGB>), metricSystem_(true),
quadSample_(new pcl::PointCloud<pcl::PointXYZ>),
quadSamplePolygons_(2),
metricSystem_(true),
measuringTextSize_(0.05f), measuringTextSize_(0.05f),
snapAxisThr_(0.95), snapAxisThr_(0.95),
measuringMode_(0), measuringMode_(0),
addMeasureClicked_(false), addMeasureClicked_(false),
teleportClicked_(false), teleportClicked_(false),
removeMeasureClicked_(false), removeMeasureClicked_(false),
optTextureMesh_(new pcl::TextureMesh), targetPoint_(new pcl::PointCloud<pcl::PointXYZRGB>),
optRefId_(0), quadSample_(new pcl::PointCloud<pcl::PointXYZ>),
optRefPose_(0), quadSamplePolygons_(2),
mapToOdom_(rtabmap::Transform::getIdentity()) mapToOdom_(rtabmap::Transform::getIdentity())
{ {
@@ -461,7 +469,13 @@ int RTABMapApp::openDatabase(const std::string & databasePath, bool databaseInMe
LOGI("Open: Found optimized mesh! Visualizing it."); LOGI("Open: Found optimized mesh! Visualizing it.");
optTextureMesh_ = rtabmap::util3d::assembleTextureMesh(cloudMat, polygons, texCoords, textures, true); optTextureMesh_ = rtabmap::util3d::assembleTextureMesh(cloudMat, polygons, texCoords, textures, true);
optMesh_ = rtabmap::Mesh(); optMesh_ = rtabmap::Mesh();
optTexture_ = textures; if(textures.rows > 4096) // Limitation iOS, just for rendering on device
{
cv::resize(textures, optTexture_, cv::Size(4096, 4096), 0.0f, 0.0f, cv::INTER_AREA);
}
else {
optTexture_ = textures;
}
if(!optTexture_.empty()) if(!optTexture_.empty())
{ {
LOGI("Open: Texture mesh: %dx%d.", optTexture_.cols, optTexture_.rows); LOGI("Open: Texture mesh: %dx%d.", optTexture_.cols, optTexture_.rows);
@@ -569,8 +583,8 @@ int RTABMapApp::openDatabase(const std::string & databasePath, bool databaseInMe
rtabmap::SensorData data = signatures.at(id).sensorData(); rtabmap::SensorData data = signatures.at(id).sensorData();
rawPoses_.insert(std::make_pair(id, signatures.at(id).getPose())); rawPoses_.insert(std::make_pair(id, signatures.at(id).getPose()));
cv::Mat tmpA, depth; cv::Mat tmpA, tmpB, tmpC;
data.uncompressData(&tmpA, &depth); data.uncompressData(&tmpA, &tmpB, 0, 0, 0, 0, 0, depthConfidence_>0?&tmpC:0);
if(!(!data.imageRaw().empty() && !data.depthRaw().empty()) && !data.laserScanCompressed().isEmpty()) if(!(!data.imageRaw().empty() && !data.depthRaw().empty()) && !data.laserScanCompressed().isEmpty())
{ {
@@ -586,8 +600,30 @@ int RTABMapApp::openDatabase(const std::string & databasePath, bool databaseInMe
if(!data.imageRaw().empty() && !data.depthRaw().empty() && (!useExternalLidar_ || data.laserScanRaw().isEmpty())) if(!data.imageRaw().empty() && !data.depthRaw().empty() && (!useExternalLidar_ || data.laserScanRaw().isEmpty()))
{ {
int meshDecimation = updateMeshDecimation(data.depthRaw().cols, data.depthRaw().rows); int meshDecimation = updateMeshDecimation(data.depthRaw().cols, data.depthRaw().rows);
cloud = rtabmap::util3d::cloudRGBFromSensorData(data, meshDecimation, maxCloudDepth_, minCloudDepth_, indices.get()); if(smoothing_ || depthBleedingError_>0.0f)
{
cv::Mat depth = data.depthRaw();
if(depthBleedingError_ > 0.0f)
{
rtabmap::util2d::depthBleedingFiltering(depth, depthBleedingError_);
}
if(smoothing_)
{
depth = rtabmap::util2d::fastBilateralFiltering(depth, g_bilateralFilteringSigmaS, g_bilateralFilteringSigmaR);
}
data.setRGBDImage(data.imageRaw(), depth, data.depthConfidenceRaw(), data.cameraModels());
}
cloud = rtabmap::util3d::cloudRGBFromSensorData(
data,
meshDecimation,
maxCloudDepth_,
minCloudDepth_,
indices.get(),
rtabmap::ParametersMap(),
std::vector<float>(),
depthConfidence_);
} }
else else
{ {
@@ -875,11 +911,11 @@ int RTABMapApp::updateMeshDecimation(int width, int height)
{ {
meshDecimation = 5; meshDecimation = 5;
} }
else if(width % 3 == 0 && width % 3 == 0) else if(width % 3 == 0 && height % 3 == 0)
{ {
meshDecimation = 3; meshDecimation = 3;
} }
else if(width % 2 == 0 && width % 2 == 0) else if(width % 2 == 0 && height % 2 == 0)
{ {
meshDecimation = 2; meshDecimation = 2;
} }
@@ -946,7 +982,7 @@ bool RTABMapApp::startCamera()
if(cameraDriver_ == 0) // Tango if(cameraDriver_ == 0) // Tango
{ {
#ifdef RTABMAP_TANGO #ifdef RTABMAP_TANGO
camera_ = new rtabmap::CameraTango(cameraColor_, !cameraColor_ || fullResolution_?1:2, rawScanSaved_, smoothing_); camera_ = new rtabmap::CameraTango(cameraColor_, !cameraColor_ || fullResolution_?1:2, rawScanSaved_);
if (TangoService_setBinder(env, iBinder) != TANGO_SUCCESS) { if (TangoService_setBinder(env, iBinder) != TANGO_SUCCESS) {
UERROR("TangoHandler::ConnectTango, TangoService_setBinder error"); UERROR("TangoHandler::ConnectTango, TangoService_setBinder error");
@@ -961,7 +997,7 @@ bool RTABMapApp::startCamera()
else if(cameraDriver_ == 1) else if(cameraDriver_ == 1)
{ {
#ifdef RTABMAP_ARCORE #ifdef RTABMAP_ARCORE
camera_ = new rtabmap::CameraARCore(env, context, activity, depthFromMotion_, smoothing_, upstreamRelocalizationMaxAcc_); camera_ = new rtabmap::CameraARCore(env, context, activity, depthFromMotion_, upstreamRelocalizationMaxAcc_);
#else #else
UERROR("RTAB-Map is not built with ARCore support!"); UERROR("RTAB-Map is not built with ARCore support!");
#endif #endif
@@ -969,14 +1005,14 @@ bool RTABMapApp::startCamera()
else if(cameraDriver_ == 2) else if(cameraDriver_ == 2)
{ {
#ifdef RTABMAP_ARENGINE #ifdef RTABMAP_ARENGINE
camera_ = new rtabmap::CameraAREngine(env, context, activity, smoothing_, upstreamRelocalizationMaxAcc_); camera_ = new rtabmap::CameraAREngine(env, context, activity, upstreamRelocalizationMaxAcc_);
#else #else
UERROR("RTAB-Map is not built with AREngine support!"); UERROR("RTAB-Map is not built with AREngine support!");
#endif #endif
} }
else if(cameraDriver_ == 3) else if(cameraDriver_ == 3)
{ {
camera_ = new rtabmap::CameraMobile(smoothing_, upstreamRelocalizationMaxAcc_); camera_ = new rtabmap::CameraMobile(upstreamRelocalizationMaxAcc_);
} }
if(camera_ == 0) if(camera_ == 0)
@@ -1003,7 +1039,11 @@ bool RTABMapApp::startCamera()
cameraJustInitialized_ = true; cameraJustInitialized_ = true;
if(useExternalLidar_) if(useExternalLidar_)
{ {
#if BOOST_VERSION >= 108700
rtabmap::LidarVLP16 * lidar = new rtabmap::LidarVLP16(boost::asio::ip::make_address("192.168.1.201"), 2368, true);
#else
rtabmap::LidarVLP16 * lidar = new rtabmap::LidarVLP16(boost::asio::ip::address_v4::from_string("192.168.1.201"), 2368, true); rtabmap::LidarVLP16 * lidar = new rtabmap::LidarVLP16(boost::asio::ip::address_v4::from_string("192.168.1.201"), 2368, true);
#endif
lidar->init(); lidar->init();
camera_->setImageRate(0); // if lidar, to get close camera synchronization camera_->setImageRate(0); // if lidar, to get close camera synchronization
sensorCaptureThread_ = new rtabmap::SensorCaptureThread(lidar, camera_, camera_, rtabmap::Transform::getIdentity()); sensorCaptureThread_ = new rtabmap::SensorCaptureThread(lidar, camera_, camera_, rtabmap::Transform::getIdentity());
@@ -1354,8 +1394,8 @@ int RTABMapApp::Render()
#ifdef DEBUG_RENDERING_PERFORMANCE #ifdef DEBUG_RENDERING_PERFORMANCE
LOGD("Camera updateOnRender %fs", time.ticks()); LOGD("Camera updateOnRender %fs", time.ticks());
#endif #endif
// We detect if we are in measuring mode if rtabmap is not running // We check if we are in measuring mode: not visualizing mesh or rtabmap is not started (localization mode)
if(main_scene_.background_renderer_ == 0 && camera_->getTextureId() != 0 && !(rtabmapThread_ == 0 || !rtabmapThread_->isRunning())) if(main_scene_.background_renderer_ == 0 && camera_->getTextureId() != 0 && (!visualizingMesh_ || !(rtabmapThread_ == 0 || !rtabmapThread_->isRunning())))
{ {
main_scene_.background_renderer_ = new BackgroundRenderer(); main_scene_.background_renderer_ = new BackgroundRenderer();
main_scene_.background_renderer_->InitializeGlContent(((rtabmap::CameraMobile*)camera_)->getTextureId(), cameraDriver_ <= 2); main_scene_.background_renderer_->InitializeGlContent(((rtabmap::CameraMobile*)camera_)->getTextureId(), cameraDriver_ <= 2);
@@ -1536,7 +1576,6 @@ int RTABMapApp::Render()
int textId = 0; int textId = 0;
int quadId = 0; int quadId = 0;
int circleId = 0; int circleId = 0;
float sphereRadius = 0.02f;
float quadSize=0.05f; float quadSize=0.05f;
float quadAlpha = 0.3f; float quadAlpha = 0.3f;
@@ -2010,8 +2049,8 @@ int RTABMapApp::Render()
{ {
rtabmap::SensorData data = bufferedSensorData.at(id); rtabmap::SensorData data = bufferedSensorData.at(id);
cv::Mat tmpA, depth; cv::Mat tmpA, tmpB, tmpC;
data.uncompressData(&tmpA, &depth); data.uncompressData(&tmpA, &tmpB, 0, 0, 0, 0, 0, depthConfidence_>0?&tmpC:0);
if(!(!data.imageRaw().empty() && !data.depthRaw().empty()) && !data.laserScanCompressed().isEmpty()) if(!(!data.imageRaw().empty() && !data.depthRaw().empty()) && !data.laserScanCompressed().isEmpty())
{ {
rtabmap::LaserScan scan; rtabmap::LaserScan scan;
@@ -2029,7 +2068,20 @@ int RTABMapApp::Render()
if(!data.imageRaw().empty() && !data.depthRaw().empty() && (!useExternalLidar_ || data.laserScanRaw().isEmpty())) if(!data.imageRaw().empty() && !data.depthRaw().empty() && (!useExternalLidar_ || data.laserScanRaw().isEmpty()))
{ {
int meshDecimation = updateMeshDecimation(data.depthRaw().cols, data.depthRaw().rows); int meshDecimation = updateMeshDecimation(data.depthRaw().cols, data.depthRaw().rows);
cloud = rtabmap::util3d::cloudRGBFromSensorData(data, meshDecimation, maxCloudDepth_, minCloudDepth_, indices.get()); if(smoothing_ || depthBleedingError_>0.0f)
{
cv::Mat depth = data.depthRaw();
if(depthBleedingError_ > 0.0f)
{
rtabmap::util2d::depthBleedingFiltering(depth, depthBleedingError_);
}
if(smoothing_)
{
depth = rtabmap::util2d::fastBilateralFiltering(depth, g_bilateralFilteringSigmaS, g_bilateralFilteringSigmaR);
}
data.setRGBDImage(data.imageRaw(), depth, data.depthConfidenceRaw(), data.cameraModels());
}
cloud = rtabmap::util3d::cloudRGBFromSensorData(data, meshDecimation, maxCloudDepth_, minCloudDepth_, indices.get(), rtabmap::ParametersMap(), std::vector<float>(), depthConfidence_);
} }
else else
{ {
@@ -2245,7 +2297,7 @@ int RTABMapApp::Render()
if(!sensorEvent.data().imageRaw().empty() && !sensorEvent.data().depthRaw().empty() && (!useExternalLidar_ || sensorEvent.data().laserScanRaw().isEmpty())) if(!sensorEvent.data().imageRaw().empty() && !sensorEvent.data().depthRaw().empty() && (!useExternalLidar_ || sensorEvent.data().laserScanRaw().isEmpty()))
{ {
int meshDecimation = updateMeshDecimation(sensorEvent.data().depthRaw().cols, sensorEvent.data().depthRaw().rows); int meshDecimation = updateMeshDecimation(sensorEvent.data().depthRaw().cols, sensorEvent.data().depthRaw().rows);
cloud = rtabmap::util3d::cloudRGBFromSensorData(sensorEvent.data(), meshDecimation, maxCloudDepth_, minCloudDepth_, indices.get()); cloud = rtabmap::util3d::cloudRGBFromSensorData(sensorEvent.data(), meshDecimation, maxCloudDepth_, minCloudDepth_, indices.get(), rtabmap::ParametersMap(), std::vector<float>(), depthConfidence_);
} }
else else
{ {
@@ -3015,6 +3067,11 @@ void RTABMapApp::setSmoothing(bool enabled)
} }
} }
void RTABMapApp::setDepthBleedingError(float value)
{
depthBleedingError_ = value;
}
void RTABMapApp::setDepthFromMotion(bool enabled) void RTABMapApp::setDepthFromMotion(bool enabled)
{ {
if(depthFromMotion_ != enabled) if(depthFromMotion_ != enabled)
@@ -3107,10 +3164,10 @@ void RTABMapApp::setBackgroundColor(float gray)
void RTABMapApp::setDepthConfidence(int value) void RTABMapApp::setDepthConfidence(int value)
{ {
depthConfidence_ = value; depthConfidence_ = value*50; // [0,2] -> [0,100]
if(depthConfidence_>2) if(depthConfidence_>100)
{ {
depthConfidence_ = 2; depthConfidence_ = 100;
} }
} }
@@ -3410,6 +3467,19 @@ bool RTABMapApp::exportMesh(
if(!data.imageRaw().empty() && !data.depthRaw().empty() && data.cameraModels().size() == 1) if(!data.imageRaw().empty() && !data.depthRaw().empty() && data.cameraModels().size() == 1)
{ {
int meshDecimation = updateMeshDecimation(data.depthRaw().cols, data.depthRaw().rows); int meshDecimation = updateMeshDecimation(data.depthRaw().cols, data.depthRaw().rows);
if(smoothing_ || depthBleedingError_>0.0f)
{
cv::Mat depth = data.depthRaw();
if(depthBleedingError_ > 0.0f)
{
rtabmap::util2d::depthBleedingFiltering(depth, depthBleedingError_);
}
if(smoothing_)
{
depth = rtabmap::util2d::fastBilateralFiltering(depth, g_bilateralFilteringSigmaS, g_bilateralFilteringSigmaR);
}
data.setRGBDImage(data.imageRaw(), depth, data.depthConfidenceRaw(), data.cameraModels());
}
cloud = rtabmap::util3d::cloudRGBFromSensorData(data, meshDecimation, maxCloudDepth_, minCloudDepth_, indices.get()); cloud = rtabmap::util3d::cloudRGBFromSensorData(data, meshDecimation, maxCloudDepth_, minCloudDepth_, indices.get());
model = data.cameraModels()[0]; model = data.cameraModels()[0];
depth = data.depthRaw(); depth = data.depthRaw();
@@ -3677,7 +3747,20 @@ bool RTABMapApp::exportMesh(
if(!data.imageRaw().empty() && !data.depthRaw().empty() && data.cameraModels().size() == 1) if(!data.imageRaw().empty() && !data.depthRaw().empty() && data.cameraModels().size() == 1)
{ {
int meshDecimation = updateMeshDecimation(data.depthRaw().cols, data.depthRaw().rows); int meshDecimation = updateMeshDecimation(data.depthRaw().cols, data.depthRaw().rows);
cloud = rtabmap::util3d::cloudRGBFromSensorData(data, meshDecimation, maxCloudDepth_, minCloudDepth_); if(smoothing_ || depthBleedingError_>0.0f)
{
cv::Mat depth = data.depthRaw();
if(depthBleedingError_ > 0.0f)
{
rtabmap::util2d::depthBleedingFiltering(depth, depthBleedingError_);
}
if(smoothing_)
{
depth = rtabmap::util2d::fastBilateralFiltering(depth, g_bilateralFilteringSigmaS, g_bilateralFilteringSigmaR);
}
data.setRGBDImage(data.imageRaw(), depth, data.depthConfidenceRaw(), data.cameraModels());
}
cloud = rtabmap::util3d::cloudRGBFromSensorData(data, meshDecimation, maxCloudDepth_, minCloudDepth_, 0, rtabmap::ParametersMap(), std::vector<float>(), depthConfidence_);
polygons = rtabmap::util3d::organizedFastMesh(cloud, meshAngleToleranceDeg_*M_PI/180.0, false, meshTrianglePix_); polygons = rtabmap::util3d::organizedFastMesh(cloud, meshAngleToleranceDeg_*M_PI/180.0, false, meshTrianglePix_);
} }
} }
@@ -3935,7 +4018,20 @@ bool RTABMapApp::exportMesh(
if(!data.imageRaw().empty() && !data.depthRaw().empty()) if(!data.imageRaw().empty() && !data.depthRaw().empty())
{ {
// full resolution // full resolution
cloud = rtabmap::util3d::cloudRGBFromSensorData(data, 1, maxCloudDepth_, minCloudDepth_, indices.get()); if(smoothing_ || depthBleedingError_>0.0f)
{
cv::Mat depth = data.depthRaw();
if(depthBleedingError_ > 0.0f)
{
rtabmap::util2d::depthBleedingFiltering(depth, depthBleedingError_);
}
if(smoothing_)
{
depth = rtabmap::util2d::fastBilateralFiltering(depth, g_bilateralFilteringSigmaS, g_bilateralFilteringSigmaR);
}
data.setRGBDImage(data.imageRaw(), depth, data.depthConfidenceRaw(), data.cameraModels());
}
cloud = rtabmap::util3d::cloudRGBFromSensorData(data, 1, maxCloudDepth_, minCloudDepth_, indices.get(), rtabmap::ParametersMap(), std::vector<float>(), depthConfidence_);
} }
else if(!data.laserScanRaw().empty()) else if(!data.laserScanRaw().empty())
{ {
@@ -3965,7 +4061,20 @@ bool RTABMapApp::exportMesh(
if(!data.imageRaw().empty() && !data.depthRaw().empty()) if(!data.imageRaw().empty() && !data.depthRaw().empty())
{ {
int meshDecimation = updateMeshDecimation(data.depthRaw().cols, data.depthRaw().rows); int meshDecimation = updateMeshDecimation(data.depthRaw().cols, data.depthRaw().rows);
cloud = rtabmap::util3d::cloudRGBFromSensorData(data, meshDecimation, maxCloudDepth_, minCloudDepth_, indices.get()); if(smoothing_ || depthBleedingError_>0.0f)
{
cv::Mat depth = data.depthRaw();
if(depthBleedingError_ > 0.0f)
{
rtabmap::util2d::depthBleedingFiltering(depth, depthBleedingError_);
}
if(smoothing_)
{
depth = rtabmap::util2d::fastBilateralFiltering(depth, g_bilateralFilteringSigmaS, g_bilateralFilteringSigmaR);
}
data.setRGBDImage(data.imageRaw(), depth, data.depthConfidenceRaw(), data.cameraModels());
}
cloud = rtabmap::util3d::cloudRGBFromSensorData(data, meshDecimation, maxCloudDepth_, minCloudDepth_, indices.get(), rtabmap::ParametersMap(), std::vector<float>(), depthConfidence_);
} }
else if(!data.laserScanRaw().empty()) else if(!data.laserScanRaw().empty())
{ {
@@ -4117,7 +4226,13 @@ bool RTABMapApp::postExportation(bool visualize)
LOGI("postExportation: Found optimized mesh! Visualizing it."); LOGI("postExportation: Found optimized mesh! Visualizing it.");
optTextureMesh_ = rtabmap::util3d::assembleTextureMesh(cloudMat, polygons, texCoords, textures, true); optTextureMesh_ = rtabmap::util3d::assembleTextureMesh(cloudMat, polygons, texCoords, textures, true);
optMesh_ = rtabmap::Mesh(); optMesh_ = rtabmap::Mesh();
optTexture_ = textures; if(textures.rows > 4096) // Limitation iOS, just for rendering on device
{
cv::resize(textures, optTexture_, cv::Size(4096, 4096), 0.0f, 0.0f, cv::INTER_AREA);
}
else {
optTexture_ = textures;
}
boost::mutex::scoped_lock lock(renderingMutex_); boost::mutex::scoped_lock lock(renderingMutex_);
visualizingMesh_ = true; visualizingMesh_ = true;
@@ -4524,6 +4639,7 @@ void RTABMapApp::postOdometryEvent(
cv::Mat outputDepth; cv::Mat outputDepth;
cv::Mat outputDepthConfidence;
if(depth && depthHeight>0 && depthWidth>0) if(depth && depthHeight>0 && depthWidth>0)
{ {
#ifndef DISABLE_LOG #ifndef DISABLE_LOG
@@ -4533,32 +4649,21 @@ void RTABMapApp::postOdometryEvent(
{ {
// IOS // IOS
outputDepth = cv::Mat(depthHeight, depthWidth, CV_32FC1, (void*)depth).clone(); outputDepth = cv::Mat(depthHeight, depthWidth, CV_32FC1, (void*)depth).clone();
if(conf && confWidth == depthWidth && confHeight == depthHeight && confFormat == 1278226488 && depthConfidence_>0) if(conf && confWidth == depthWidth && confHeight == depthHeight && confFormat == 1278226488)
{ {
const unsigned char * confPtr = (const unsigned char *)conf; // https://developer.apple.com/documentation/arkit/arconfidencelevel
float * depthPtr = outputDepth.ptr<float>(); // 0 = low
int i=0; // 1 = medium
for (int y = 0; y < outputDepth.rows; ++y) // 2 = high
{ // Re-scale confidence from [0,2] to [0,100]
for (int x = 0; x < outputDepth.cols; ++x) cv::Mat(depthHeight, depthWidth, CV_8UC1, (void*)conf).convertTo(outputDepthConfidence, CV_8UC1, 50, 0);
{
// https://developer.apple.com/documentation/arkit/arconfidencelevel
// 0 = low
// 1 = medium
// 2 = high
if(confPtr[y*outputDepth.cols + x] < depthConfidence_)
{
depthPtr[y*outputDepth.cols + x] = 0.0f;
++i;
}
}
}
} }
} }
else if(depthLen == 2*depthWidth*depthHeight) else if(depthLen == 2*depthWidth*depthHeight)
{ {
// ANDROID // ANDROID
outputDepth = cv::Mat(depthHeight, depthWidth, CV_16UC1); outputDepth = cv::Mat(depthHeight, depthWidth, CV_16UC1);
outputDepthConfidence = cv::Mat(depthHeight, depthWidth, CV_8UC1);
uint16_t *dataShort = (uint16_t *)depth; uint16_t *dataShort = (uint16_t *)depth;
for (int y = 0; y < outputDepth.rows; ++y) for (int y = 0; y < outputDepth.rows; ++y)
{ {
@@ -4567,6 +4672,13 @@ void RTABMapApp::postOdometryEvent(
uint16_t depthSample = dataShort[y*outputDepth.cols + x]; uint16_t depthSample = dataShort[y*outputDepth.cols + x];
uint16_t depthRange = (depthSample & 0x1FFF); // first 3 bits are confidence uint16_t depthRange = (depthSample & 0x1FFF); // first 3 bits are confidence
outputDepth.at<uint16_t>(y,x) = depthRange; outputDepth.at<uint16_t>(y,x) = depthRange;
// https://developer.android.com/reference/android/graphics/ImageFormat#DEPTH16
// The confidence value is an estimate of correctness for this sample. It
// is encoded in the 3 most significant bits of the sample, with a value of
// 0 representing 100% confidence, a value of 1 representing 0% confidence, a
// value of 2 representing 1/7, a value of 3 representing 2/7, and so on.
uint8_t depthConfidence = uint8_t((depthSample >> 13) & 0x7);
outputDepthConfidence.at<uint8_t>(y,x) = depthConfidence == 0 ? 100 : (depthConfidence - 1)*100 / 7;
} }
} }
} }
@@ -4626,7 +4738,9 @@ void RTABMapApp::postOdometryEvent(
depth_fx, 0, depth_cx, depth_fx, 0, depth_cx,
0, depth_fy, depth_cy, 0, depth_fy, depth_cy,
0, 0, 1); 0, 0, 1);
outputDepth = rtabmap::util2d::registerDepth(outputDepth, depthK, outputDepth.size(), colorK, rgbToDepth); cv::Mat regConfidence;
outputDepth = rtabmap::util2d::registerDepth(outputDepth, outputDepthConfidence, depthK, outputDepth.size(), colorK, rgbToDepth, regConfidence);
outputDepthConfidence = regConfidence;
#ifndef DISABLE_LOG #ifndef DISABLE_LOG
UDEBUG("Depth registration time: %fs", time.elapsed()); UDEBUG("Depth registration time: %fs", time.elapsed());
#endif #endif
@@ -4666,8 +4780,8 @@ void RTABMapApp::postOdometryEvent(
depthModel.setLocalTransform(pose*model.localTransform()); depthModel.setLocalTransform(pose*model.localTransform());
camera_->setOcclusionImage(outputDepth, depthModel); camera_->setOcclusionImage(outputDepth, depthModel);
} }
rtabmap::SensorData data(scan, outputRGB, outputDepth, model, 0, stamp); rtabmap::SensorData data(scan, outputRGB, outputDepth, outputDepthConfidence, model, 0, stamp);
data.setFeatures(kpts, kpts3, cv::Mat()); data.setFeatures(kpts, kpts3, cv::Mat());
glm::mat4 projectionMatrix(0); glm::mat4 projectionMatrix(0);
projectionMatrix[0][0] = p00; projectionMatrix[0][0] = p00;
+3 -1
View File
@@ -139,6 +139,7 @@ class RTABMapApp : public UEventsHandler {
void setCameraColor(bool enabled); void setCameraColor(bool enabled);
void setFullResolution(bool enabled); void setFullResolution(bool enabled);
void setSmoothing(bool enabled); void setSmoothing(bool enabled);
void setDepthBleedingError(float value);
void setDepthFromMotion(bool enabled); void setDepthFromMotion(bool enabled);
void setAppendMode(bool enabled); void setAppendMode(bool enabled);
void setUpstreamRelocalizationAccThr(float value); void setUpstreamRelocalizationAccThr(float value);
@@ -235,6 +236,7 @@ class RTABMapApp : public UEventsHandler {
bool trajectoryMode_; bool trajectoryMode_;
bool rawScanSaved_; bool rawScanSaved_;
bool smoothing_; bool smoothing_;
float depthBleedingError_;
bool depthFromMotion_; bool depthFromMotion_;
bool cameraColor_; bool cameraColor_;
bool fullResolution_; bool fullResolution_;
@@ -250,7 +252,7 @@ class RTABMapApp : public UEventsHandler {
float maxGainRadius_; float maxGainRadius_;
int renderingTextureDecimation_; int renderingTextureDecimation_;
float backgroundColor_; float backgroundColor_;
int depthConfidence_; unsigned char depthConfidence_;
float upstreamRelocalizationMaxAcc_; float upstreamRelocalizationMaxAcc_;
std::string exportPointCloudFormat_; std::string exportPointCloudFormat_;
+13
View File
@@ -512,6 +512,19 @@ Java_com_introlab_rtabmap_RTABMapLib_setSmoothing(
} }
} }
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_com_introlab_rtabmap_RTABMapLib_setDepthBleedingError(
JNIEnv*, jclass, jlong native_application, float value)
{
if(native_application)
{
return native(native_application)->setDepthBleedingError(value);
}
else
{
UERROR("native_application is null!");
}
}
JNIEXPORT void JNICALL
Java_com_introlab_rtabmap_RTABMapLib_setDepthFromMotion( Java_com_introlab_rtabmap_RTABMapLib_setDepthFromMotion(
JNIEnv*, jclass, jlong native_application, bool enabled) JNIEnv*, jclass, jlong native_application, bool enabled)
{ {
@@ -114,6 +114,13 @@
android:title="@string/pref_title_smoothing" android:title="@string/pref_title_smoothing"
android:summary="@string/pref_summary_smoothing" android:summary="@string/pref_summary_smoothing"
android:defaultValue="@string/pref_default_smoothing"/> android:defaultValue="@string/pref_default_smoothing"/>
<ListPreference
android:key="@string/pref_key_depth_bleeding_error"
android:title="@string/pref_title_depth_bleeding_error"
android:summary="@string/pref_summary_depth_bleeding_error"
android:entries="@array/pref_depth_bleeding_error_keys"
android:entryValues="@array/pref_depth_bleeding_error_values"
android:defaultValue="@string/pref_default_depth_bleeding_error"/>
<com.introlab.rtabmap.CustomSwitchPreference <com.introlab.rtabmap.CustomSwitchPreference
android:key="@string/pref_key_fisheye" android:key="@string/pref_key_fisheye"
android:title="@string/pref_title_fisheye" android:title="@string/pref_title_fisheye"
+24
View File
@@ -76,6 +76,8 @@
<string name="pref_default_resolution">false</string> <string name="pref_default_resolution">false</string>
<string name="pref_key_smoothing">pref_key_smoothing</string> <string name="pref_key_smoothing">pref_key_smoothing</string>
<string name="pref_default_smoothing">false</string> <string name="pref_default_smoothing">false</string>
<string name="pref_key_depth_bleeding_error">pref_key_depth_bleeding_error</string>
<string name="pref_default_depth_bleeding_error">0.0</string>
<string name="pref_key_fisheye">pref_key_fisheye</string> <string name="pref_key_fisheye">pref_key_fisheye</string>
<string name="pref_default_fisheye">false</string> <string name="pref_default_fisheye">false</string>
@@ -337,6 +339,8 @@
<string name="pref_summary_resolution">Save HD images of the color camera if you want very detailed textures. More memory will be required.</string> <string name="pref_summary_resolution">Save HD images of the color camera if you want very detailed textures. More memory will be required.</string>
<string name="pref_title_smoothing">Smoothing</string> <string name="pref_title_smoothing">Smoothing</string>
<string name="pref_summary_smoothing">Smooth the point clouds.</string> <string name="pref_summary_smoothing">Smooth the point clouds.</string>
<string name="pref_title_depth_bleeding_error">Depth Bleeding Filtering Error</string>
<string name="pref_summary_depth_bleeding_error">Filter noisy depth points on the edges.</string>
<string name="pref_title_fisheye">Fish Eye Camera</string> <string name="pref_title_fisheye">Fish Eye Camera</string>
<string name="pref_summary_fisheye">Use fish eye camera instead of the color camera. May not work on some devices.</string> <string name="pref_summary_fisheye">Use fish eye camera instead of the color camera. May not work on some devices.</string>
<string name="pref_title_update_rate">Update Rate</string> <string name="pref_title_update_rate">Update Rate</string>
@@ -436,6 +440,26 @@
<item>"29.41995"</item> <item>"29.41995"</item>
<item>"19.6133"</item> <item>"19.6133"</item>
</string-array> </string-array>
<string-array name="pref_depth_bleeding_error_keys">
<item>"Disabled"</item>
<item>"2.5 cm"</item>
<item>"5 cm"</item>
<item>"10 cm"</item>
<item>"15 cm"</item>
<item>"20 cm"</item>
<item>"25 cm"</item>
<item>"30 cm"</item>
</string-array>
<string-array name="pref_depth_bleeding_error_values">
<item>"0"</item>
<item>"0.025"</item>
<item>"0.05"</item>
<item>"0.10"</item>
<item>"0.15"</item>
<item>"0.20"</item>
<item>"0.25"</item>
<item>"0.30"</item>
</string-array>
<string-array name="pref_max_speed_keys"> <string-array name="pref_max_speed_keys">
<item>"No Limit"</item> <item>"No Limit"</item>
<item>"High"</item> <item>"High"</item>
@@ -1140,6 +1140,7 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
RTABMapLib.setRawScanSaved(nativeApplication, sharedPref.getBoolean(getString(R.string.pref_key_raw_scan_saved), Boolean.parseBoolean(getString(R.string.pref_default_raw_scan_saved)))); RTABMapLib.setRawScanSaved(nativeApplication, sharedPref.getBoolean(getString(R.string.pref_key_raw_scan_saved), Boolean.parseBoolean(getString(R.string.pref_default_raw_scan_saved))));
RTABMapLib.setFullResolution(nativeApplication, sharedPref.getBoolean(getString(R.string.pref_key_resolution), Boolean.parseBoolean(getString(R.string.pref_default_resolution)))); RTABMapLib.setFullResolution(nativeApplication, sharedPref.getBoolean(getString(R.string.pref_key_resolution), Boolean.parseBoolean(getString(R.string.pref_default_resolution))));
RTABMapLib.setSmoothing(nativeApplication, sharedPref.getBoolean(getString(R.string.pref_key_smoothing), Boolean.parseBoolean(getString(R.string.pref_default_smoothing)))); RTABMapLib.setSmoothing(nativeApplication, sharedPref.getBoolean(getString(R.string.pref_key_smoothing), Boolean.parseBoolean(getString(R.string.pref_default_smoothing))));
RTABMapLib.setDepthBleedingError(nativeApplication, Float.parseFloat(sharedPref.getString(getString(R.string.pref_key_depth_bleeding_error), getString(R.string.pref_default_depth_bleeding_error))));
RTABMapLib.setDepthFromMotion(nativeApplication, sharedPref.getBoolean(getString(R.string.pref_key_depth_from_motion), Boolean.parseBoolean(getString(R.string.pref_default_depth_from_motion)))); RTABMapLib.setDepthFromMotion(nativeApplication, sharedPref.getBoolean(getString(R.string.pref_key_depth_from_motion), Boolean.parseBoolean(getString(R.string.pref_default_depth_from_motion))));
RTABMapLib.setCameraColor(nativeApplication, !sharedPref.getBoolean(getString(R.string.pref_key_fisheye), Boolean.parseBoolean(getString(R.string.pref_default_fisheye)))); RTABMapLib.setCameraColor(nativeApplication, !sharedPref.getBoolean(getString(R.string.pref_key_fisheye), Boolean.parseBoolean(getString(R.string.pref_default_fisheye))));
RTABMapLib.setAppendMode(nativeApplication, sharedPref.getBoolean(getString(R.string.pref_key_append), Boolean.parseBoolean(getString(R.string.pref_default_append)))); RTABMapLib.setAppendMode(nativeApplication, sharedPref.getBoolean(getString(R.string.pref_key_append), Boolean.parseBoolean(getString(R.string.pref_default_append))));
@@ -73,6 +73,7 @@ public class RTABMapLib
public static native void setRawScanSaved(long nativeApplication, boolean enabled); public static native void setRawScanSaved(long nativeApplication, boolean enabled);
public static native void setFullResolution(long nativeApplication, boolean enabled); public static native void setFullResolution(long nativeApplication, boolean enabled);
public static native void setSmoothing(long nativeApplication, boolean enabled); public static native void setSmoothing(long nativeApplication, boolean enabled);
public static native void setDepthBleedingError(long nativeApplication, float value);
public static native void setDepthFromMotion(long nativeApplication, boolean enabled); public static native void setDepthFromMotion(long nativeApplication, boolean enabled);
public static native void setCameraColor(long nativeApplication, boolean enabled); public static native void setCameraColor(long nativeApplication, boolean enabled);
public static native void setAppendMode(long nativeApplication, boolean enabled); public static native void setAppendMode(long nativeApplication, boolean enabled);
@@ -222,7 +222,8 @@ public class SettingsActivity extends PreferenceActivity implements OnSharedPref
((Preference)findPreference(getString(R.string.pref_key_background_color))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_background_color))).getEntry() + ") "+getString(R.string.pref_summary_background_color)); ((Preference)findPreference(getString(R.string.pref_key_background_color))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_background_color))).getEntry() + ") "+getString(R.string.pref_summary_background_color));
((Preference)findPreference(getString(R.string.pref_key_rendering_texture_decimation))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_rendering_texture_decimation))).getEntry() + ") "+getString(R.string.pref_summary_rendering_texture_decimation)); ((Preference)findPreference(getString(R.string.pref_key_rendering_texture_decimation))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_rendering_texture_decimation))).getEntry() + ") "+getString(R.string.pref_summary_rendering_texture_decimation));
((Preference)findPreference(getString(R.string.pref_key_arcore_relocalization_acc_thr))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_arcore_relocalization_acc_thr))).getEntry() + ") "+getString(R.string.pref_summary_arcore_relocalization_acc_thr)); ((Preference)findPreference(getString(R.string.pref_key_depth_bleeding_error))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_depth_bleeding_error))).getEntry() + ") "+getString(R.string.pref_summary_depth_bleeding_error));
((Preference)findPreference(getString(R.string.pref_key_arcore_relocalization_acc_thr))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_arcore_relocalization_acc_thr))).getEntry() + ") "+getString(R.string.pref_summary_arcore_relocalization_acc_thr));
((Preference)findPreference(getString(R.string.pref_key_update_rate))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_update_rate))).getEntry() + ") "+getString(R.string.pref_summary_update_rate)); ((Preference)findPreference(getString(R.string.pref_key_update_rate))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_update_rate))).getEntry() + ") "+getString(R.string.pref_summary_update_rate));
((Preference)findPreference(getString(R.string.pref_key_max_speed))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_max_speed))).getEntry() + ") "+getString(R.string.pref_summary_max_speed)); ((Preference)findPreference(getString(R.string.pref_key_max_speed))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_max_speed))).getEntry() + ") "+getString(R.string.pref_summary_max_speed));
((Preference)findPreference(getString(R.string.pref_key_time_thr))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_time_thr))).getEntry() + ") "+getString(R.string.pref_summary_time_thr)); ((Preference)findPreference(getString(R.string.pref_key_time_thr))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_time_thr))).getEntry() + ") "+getString(R.string.pref_summary_time_thr));
@@ -285,7 +286,8 @@ public class SettingsActivity extends PreferenceActivity implements OnSharedPref
if(key.compareTo(getString(R.string.pref_key_background_color))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_background_color)); if(key.compareTo(getString(R.string.pref_key_background_color))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_background_color));
if(key.compareTo(getString(R.string.pref_key_rendering_texture_decimation))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_rendering_texture_decimation)); if(key.compareTo(getString(R.string.pref_key_rendering_texture_decimation))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_rendering_texture_decimation));
if(key.compareTo(getString(R.string.pref_key_arcore_relocalization_acc_thr))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_arcore_relocalization_acc_thr)); if(key.compareTo(getString(R.string.pref_key_depth_bleeding_error))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_depth_bleeding_error));
if(key.compareTo(getString(R.string.pref_key_arcore_relocalization_acc_thr))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_arcore_relocalization_acc_thr));
if(key.compareTo(getString(R.string.pref_key_update_rate))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_update_rate)); if(key.compareTo(getString(R.string.pref_key_update_rate))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_update_rate));
if(key.compareTo(getString(R.string.pref_key_max_speed))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_max_speed)); if(key.compareTo(getString(R.string.pref_key_max_speed))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_max_speed));
if(key.compareTo(getString(R.string.pref_key_time_thr))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_time_thr)); if(key.compareTo(getString(R.string.pref_key_time_thr))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_time_thr));
+245 -213
View File
@@ -8,49 +8,90 @@
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
4E0D83832621F52C00C879AC /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 4E0D83822621F52C00C879AC /* Settings.bundle */; }; 4E0D83832621F52C00C879AC /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 4E0D83822621F52C00C879AC /* Settings.bundle */; };
4E10D89C2DE409870015926D /* librtabmap_core.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0EB0259D5BE500575D88 /* librtabmap_core.a */; };
4E10D89D2DE409870015926D /* librtabmap_utilite.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0EAF259D5BE500575D88 /* librtabmap_utilite.a */; };
4E10D89E2DE409A60015926D /* libopencv_xfeatures2d.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0ED9259D5BFC00575D88 /* libopencv_xfeatures2d.a */; };
4E10D89F2DE409B20015926D /* libopencv_video.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0EB4259D5BFB00575D88 /* libopencv_video.a */; };
4E10D8A02DE409BB0015926D /* libopencv_tracking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0ECC259D5BFC00575D88 /* libopencv_tracking.a */; };
4E10D8A12DE409C00015926D /* libopencv_optflow.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0EC3259D5BFC00575D88 /* libopencv_optflow.a */; };
4E10D8A22DE409C70015926D /* libopencv_imgproc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0EBE259D5BFC00575D88 /* libopencv_imgproc.a */; };
4E10D8A32DE409CA0015926D /* libopencv_features2d.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0EB8259D5BFB00575D88 /* libopencv_features2d.a */; };
4E10D8A42DE409CE0015926D /* libopencv_core.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0ED1259D5BFC00575D88 /* libopencv_core.a */; };
4E10D8A52DE409D10015926D /* libopencv_calib3d.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0ED6259D5BFC00575D88 /* libopencv_calib3d.a */; };
4E10D8A62DE409D50015926D /* libopencv_aruco.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0EB5259D5BFB00575D88 /* libopencv_aruco.a */; };
4E10D8A72DE409F40015926D /* libopencv_flann.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0EBC259D5BFB00575D88 /* libopencv_flann.a */; };
4E10D8A82DE40A1B0015926D /* libopencv_ximgproc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0EDC259D5BFC00575D88 /* libopencv_ximgproc.a */; };
4E10D8A92DE40A3A0015926D /* libopencv_photo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0EB6259D5BFB00575D88 /* libopencv_photo.a */; };
4E10D8AA2DE40A6C0015926D /* libopencv_objdetect.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0EBB259D5BFB00575D88 /* libopencv_objdetect.a */; };
4E10D8AB2DE40A8C0015926D /* libopencv_stitching.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0EBD259D5BFB00575D88 /* libopencv_stitching.a */; };
4E10D8AC2DE40AA20015926D /* libopencv_imgcodecs.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0EC4259D5BFC00575D88 /* libopencv_imgcodecs.a */; };
4E10D8AD2DE40E990015926D /* libg2o_core.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F0D259D5C2200575D88 /* libg2o_core.a */; };
4E10D8AE2DE40E990015926D /* libg2o_solver_dense.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F07259D5C2100575D88 /* libg2o_solver_dense.a */; };
4E10D8AF2DE40E990015926D /* libg2o_solver_eigen.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F12259D5C2200575D88 /* libg2o_solver_eigen.a */; };
4E10D8B02DE40E990015926D /* libg2o_solver_pcg.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F0B259D5C2200575D88 /* libg2o_solver_pcg.a */; };
4E10D8B12DE40E990015926D /* libg2o_solver_slam2d_linear.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F09259D5C2100575D88 /* libg2o_solver_slam2d_linear.a */; };
4E10D8B22DE40E990015926D /* libg2o_solver_structure_only.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F11259D5C2200575D88 /* libg2o_solver_structure_only.a */; };
4E10D8B32DE40E990015926D /* libg2o_stuff.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F14259D5C2200575D88 /* libg2o_stuff.a */; };
4E10D8B42DE40E990015926D /* libg2o_types_data.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F0C259D5C2200575D88 /* libg2o_types_data.a */; };
4E10D8B52DE40E990015926D /* libg2o_types_icp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F0F259D5C2200575D88 /* libg2o_types_icp.a */; };
4E10D8B62DE40E990015926D /* libg2o_types_sba.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F15259D5C2200575D88 /* libg2o_types_sba.a */; };
4E10D8B72DE40E990015926D /* libg2o_types_sclam2d.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F1A259D5C2200575D88 /* libg2o_types_sclam2d.a */; };
4E10D8B82DE40E990015926D /* libg2o_types_sim3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F1B259D5C2200575D88 /* libg2o_types_sim3.a */; };
4E10D8B92DE40E990015926D /* libg2o_types_slam2d_addons.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F16259D5C2200575D88 /* libg2o_types_slam2d_addons.a */; };
4E10D8BA2DE40E990015926D /* libg2o_types_slam2d.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F0A259D5C2100575D88 /* libg2o_types_slam2d.a */; };
4E10D8BB2DE40E990015926D /* libg2o_types_slam3d_addons.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F17259D5C2200575D88 /* libg2o_types_slam3d_addons.a */; };
4E10D8BC2DE40E990015926D /* libg2o_types_slam3d.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F18259D5C2200575D88 /* libg2o_types_slam3d.a */; };
4E10D8BD2DE40EC70015926D /* libpcl_common.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0B4D259D4DF100575D88 /* libpcl_common.a */; };
4E10D8BE2DE40EC70015926D /* libpcl_features.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0B43259D4DF100575D88 /* libpcl_features.a */; };
4E10D8BF2DE40EC70015926D /* libpcl_filters.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0B44259D4DF100575D88 /* libpcl_filters.a */; };
4E10D8C02DE40EC70015926D /* libpcl_io_ply.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0B4E259D4DF100575D88 /* libpcl_io_ply.a */; };
4E10D8C12DE40EC70015926D /* libpcl_io.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0B4C259D4DF100575D88 /* libpcl_io.a */; };
4E10D8C22DE40EC70015926D /* libpcl_kdtree.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0B46259D4DF100575D88 /* libpcl_kdtree.a */; };
4E10D8C32DE40EC70015926D /* libpcl_keypoints.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0B49259D4DF100575D88 /* libpcl_keypoints.a */; };
4E10D8C42DE40EC70015926D /* libpcl_ml.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0B4F259D4DF100575D88 /* libpcl_ml.a */; };
4E10D8C52DE40EC70015926D /* libpcl_octree.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0B4B259D4DF100575D88 /* libpcl_octree.a */; };
4E10D8C62DE40EC70015926D /* libpcl_registration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0B42259D4DF100575D88 /* libpcl_registration.a */; };
4E10D8C72DE40EC70015926D /* libpcl_sample_consensus.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0B45259D4DF100575D88 /* libpcl_sample_consensus.a */; };
4E10D8C82DE40EC70015926D /* libpcl_search.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0B47259D4DF100575D88 /* libpcl_search.a */; };
4E10D8C92DE40EC70015926D /* libpcl_segmentation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0B50259D4DF100575D88 /* libpcl_segmentation.a */; };
4E10D8CA2DE40EC70015926D /* libpcl_stereo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0B41259D4DF100575D88 /* libpcl_stereo.a */; };
4E10D8CB2DE40EC70015926D /* libpcl_surface.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0B48259D4DF100575D88 /* libpcl_surface.a */; };
4E10D8CC2DE40EE30015926D /* libgtsam_unstable.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F0E259D5C2200575D88 /* libgtsam_unstable.a */; };
4E10D8CD2DE40EE30015926D /* libgtsam.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F1C259D5C2200575D88 /* libgtsam.a */; };
4E10D8CE2DE40EE30015926D /* libmetis-gtsam.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4E10D8622DE408EE0015926D /* libmetis-gtsam.a */; };
4E10D8CF2DE40EF90015926D /* libboost_serialization.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0B30259D4DE900575D88 /* libboost_serialization.a */; };
4E10D8D02DE40F060015926D /* libboost_timer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0B34259D4DE900575D88 /* libboost_timer.a */; };
4E10D8D12DE40F190015926D /* liblas_c.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4E10D8752DE408EF0015926D /* liblas_c.a */; };
4E10D8D22DE40F190015926D /* liblas.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFAA9422CAE4E960055DA51 /* liblas.a */; };
4E10D8D32DE40F190015926D /* liblaszip.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4ED73AD02D7FECF3007899C2 /* liblaszip.a */; };
4E10D8D42DE40F2A0015926D /* libboost_thread.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0B33259D4DE900575D88 /* libboost_thread.a */; };
4E10D8E12DE4101B0015926D /* liblibjpeg-turbo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4E10D8D52DE40FBE0015926D /* liblibjpeg-turbo.a */; };
4E10D8E22DE4101B0015926D /* liblibpng.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4E10D8D72DE40FCA0015926D /* liblibpng.a */; };
4E1E9CF72D618E69000CB881 /* quad_color.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4E1E9CF62D618079000CB881 /* quad_color.cpp */; }; 4E1E9CF72D618E69000CB881 /* quad_color.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4E1E9CF62D618079000CB881 /* quad_color.cpp */; };
4E1E9CF82D618E69000CB881 /* text_drawable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4E1E9CF52D618079000CB881 /* text_drawable.cpp */; }; 4E1E9CF82D618E69000CB881 /* text_drawable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4E1E9CF52D618079000CB881 /* text_drawable.cpp */; };
4E20B24E266AB94300316EE6 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4E20B24D266AB94300316EE6 /* Images.xcassets */; }; 4E20B24E266AB94300316EE6 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4E20B24D266AB94300316EE6 /* Images.xcassets */; };
4E20B250266AB95600316EE6 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4E20B24F266AB95600316EE6 /* Images.xcassets */; }; 4E20B250266AB95600316EE6 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4E20B24F266AB95600316EE6 /* Images.xcassets */; };
4E2C516725A63119005CEDBD /* DatabaseView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E2C516525A63119005CEDBD /* DatabaseView.swift */; }; 4E2C516725A63119005CEDBD /* DatabaseView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E2C516525A63119005CEDBD /* DatabaseView.swift */; };
4E2C516825A63119005CEDBD /* VerticalScrollerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E2C516625A63119005CEDBD /* VerticalScrollerView.swift */; }; 4E2C516825A63119005CEDBD /* VerticalScrollerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E2C516625A63119005CEDBD /* VerticalScrollerView.swift */; };
4E3525542DE4C6E500F39D8F /* libg2o_csparse_extension.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F13259D5C2200575D88 /* libg2o_csparse_extension.a */; };
4E3525552DE4C6E500F39D8F /* libg2o_solver_csparse.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F10259D5C2200575D88 /* libg2o_solver_csparse.a */; };
4E3525572DE4C6E500F39D8F /* libg2o_solver_cholmod.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4E3525562DE4C6E500F39D8F /* libg2o_solver_cholmod.a */; };
4E3525592DE4C6F600F39D8F /* libcholmod.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4E3525582DE4C6F600F39D8F /* libcholmod.a */; };
4E35255E2DE4C71000F39D8F /* libcxsparse.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4E35255A2DE4C71000F39D8F /* libcxsparse.a */; };
4E35255F2DE4C71000F39D8F /* libcolamd.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4E35255B2DE4C71000F39D8F /* libcolamd.a */; };
4E3525602DE4C71000F39D8F /* libcamd.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4E35255C2DE4C71000F39D8F /* libcamd.a */; };
4E3525612DE4C71000F39D8F /* libccolamd.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4E35255D2DE4C71000F39D8F /* libccolamd.a */; };
4E3525642DE4C71C00F39D8F /* libsuitesparseconfig.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4E3525622DE4C71C00F39D8F /* libsuitesparseconfig.a */; };
4E3525652DE4C71C00F39D8F /* libspqr.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4E3525632DE4C71C00F39D8F /* libspqr.a */; };
4E3525672DE4C72D00F39D8F /* libamd.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4E3525662DE4C72D00F39D8F /* libamd.a */; };
4E8B155426273A580037FC53 /* Zip in Frameworks */ = {isa = PBXBuildFile; productRef = 4E8B155326273A580037FC53 /* Zip */; }; 4E8B155426273A580037FC53 /* Zip in Frameworks */ = {isa = PBXBuildFile; productRef = 4E8B155326273A580037FC53 /* Zip */; };
4EB1A66625A0D90B0043C7BF /* RTABMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EB1A66525A0D90B0043C7BF /* RTABMap.swift */; }; 4EB1A66625A0D90B0043C7BF /* RTABMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EB1A66525A0D90B0043C7BF /* RTABMap.swift */; };
4ED73AD12D7FECF3007899C2 /* liblaszip.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4ED73AD02D7FECF3007899C2 /* liblaszip.a */; };
4EE016B3259BE441008CCE65 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EE016AF259BE441008CCE65 /* ViewController.swift */; }; 4EE016B3259BE441008CCE65 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EE016AF259BE441008CCE65 /* ViewController.swift */; };
4EE016B4259BE441008CCE65 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EE016B0259BE441008CCE65 /* SceneDelegate.swift */; }; 4EE016B4259BE441008CCE65 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EE016B0259BE441008CCE65 /* SceneDelegate.swift */; };
4EE016B9259BE449008CCE65 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EE016B8259BE449008CCE65 /* AppDelegate.swift */; }; 4EE016B9259BE449008CCE65 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EE016B8259BE449008CCE65 /* AppDelegate.swift */; };
4EE016C3259BE464008CCE65 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4EE016BF259BE464008CCE65 /* Main.storyboard */; }; 4EE016C3259BE464008CCE65 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4EE016BF259BE464008CCE65 /* Main.storyboard */; };
4EE016C4259BE464008CCE65 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4EE016C1259BE464008CCE65 /* LaunchScreen.storyboard */; }; 4EE016C4259BE464008CCE65 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4EE016C1259BE464008CCE65 /* LaunchScreen.storyboard */; };
4EE016C7259BE46F008CCE65 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4EE016C6259BE46F008CCE65 /* Assets.xcassets */; }; 4EE016C7259BE46F008CCE65 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4EE016C6259BE46F008CCE65 /* Assets.xcassets */; };
4EFAA9432CAE4E960055DA51 /* liblas.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFAA9422CAE4E960055DA51 /* liblas.a */; };
4EFD0B36259D4DE900575D88 /* libboost_filesystem.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0B2B259D4DE900575D88 /* libboost_filesystem.a */; };
4EFD0B37259D4DE900575D88 /* libboost_program_options.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0B2C259D4DE900575D88 /* libboost_program_options.a */; };
4EFD0B38259D4DE900575D88 /* libboost_regex.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0B2D259D4DE900575D88 /* libboost_regex.a */; };
4EFD0B39259D4DE900575D88 /* libboost_iostreams.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0B2E259D4DE900575D88 /* libboost_iostreams.a */; };
4EFD0B3A259D4DE900575D88 /* libboost_date_time.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0B2F259D4DE900575D88 /* libboost_date_time.a */; };
4EFD0B3B259D4DE900575D88 /* libboost_serialization.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0B30259D4DE900575D88 /* libboost_serialization.a */; };
4EFD0B3C259D4DE900575D88 /* libboost_system.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0B31259D4DE900575D88 /* libboost_system.a */; };
4EFD0B3D259D4DE900575D88 /* libboost_signals.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0B32259D4DE900575D88 /* libboost_signals.a */; };
4EFD0B3E259D4DE900575D88 /* libboost_thread.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0B33259D4DE900575D88 /* libboost_thread.a */; };
4EFD0B3F259D4DE900575D88 /* libboost_timer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0B34259D4DE900575D88 /* libboost_timer.a */; };
4EFD0B40259D4DE900575D88 /* libboost_chrono.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0B35259D4DE900575D88 /* libboost_chrono.a */; };
4EFD0B51259D4DF100575D88 /* libpcl_stereo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0B41259D4DF100575D88 /* libpcl_stereo.a */; };
4EFD0B52259D4DF100575D88 /* libpcl_registration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0B42259D4DF100575D88 /* libpcl_registration.a */; };
4EFD0B53259D4DF100575D88 /* libpcl_features.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0B43259D4DF100575D88 /* libpcl_features.a */; };
4EFD0B54259D4DF100575D88 /* libpcl_filters.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0B44259D4DF100575D88 /* libpcl_filters.a */; };
4EFD0B55259D4DF100575D88 /* libpcl_sample_consensus.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0B45259D4DF100575D88 /* libpcl_sample_consensus.a */; };
4EFD0B56259D4DF100575D88 /* libpcl_kdtree.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0B46259D4DF100575D88 /* libpcl_kdtree.a */; };
4EFD0B57259D4DF100575D88 /* libpcl_search.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0B47259D4DF100575D88 /* libpcl_search.a */; };
4EFD0B58259D4DF100575D88 /* libpcl_surface.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0B48259D4DF100575D88 /* libpcl_surface.a */; };
4EFD0B59259D4DF100575D88 /* libpcl_keypoints.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0B49259D4DF100575D88 /* libpcl_keypoints.a */; };
4EFD0B5A259D4DF100575D88 /* libpcl_recognition.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0B4A259D4DF100575D88 /* libpcl_recognition.a */; };
4EFD0B5B259D4DF100575D88 /* libpcl_octree.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0B4B259D4DF100575D88 /* libpcl_octree.a */; };
4EFD0B5C259D4DF100575D88 /* libpcl_io.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0B4C259D4DF100575D88 /* libpcl_io.a */; };
4EFD0B5D259D4DF100575D88 /* libpcl_common.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0B4D259D4DF100575D88 /* libpcl_common.a */; };
4EFD0B5E259D4DF100575D88 /* libpcl_io_ply.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0B4E259D4DF100575D88 /* libpcl_io_ply.a */; };
4EFD0B5F259D4DF100575D88 /* libpcl_ml.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0B4F259D4DF100575D88 /* libpcl_ml.a */; };
4EFD0B60259D4DF100575D88 /* libpcl_segmentation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0B50259D4DF100575D88 /* libpcl_segmentation.a */; };
4EFD0B97259D501E00575D88 /* line.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4EFD0B63259D501E00575D88 /* line.cpp */; }; 4EFD0B97259D501E00575D88 /* line.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4EFD0B63259D501E00575D88 /* line.cpp */; };
4EFD0B98259D501E00575D88 /* util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4EFD0B64259D501E00575D88 /* util.cpp */; }; 4EFD0B98259D501E00575D88 /* util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4EFD0B64259D501E00575D88 /* util.cpp */; };
4EFD0B99259D501E00575D88 /* obj_loader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4EFD0B65259D501E00575D88 /* obj_loader.cpp */; }; 4EFD0B99259D501E00575D88 /* obj_loader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4EFD0B65259D501E00575D88 /* obj_loader.cpp */; };
@@ -78,80 +119,8 @@
4EFD0BBC259D509300575D88 /* point_cloud_drawable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4EFD0BBA259D509300575D88 /* point_cloud_drawable.cpp */; }; 4EFD0BBC259D509300575D88 /* point_cloud_drawable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4EFD0BBA259D509300575D88 /* point_cloud_drawable.cpp */; };
4EFD0BC0259D50A800575D88 /* scene.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4EFD0BBE259D50A800575D88 /* scene.cpp */; }; 4EFD0BC0259D50A800575D88 /* scene.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4EFD0BBE259D50A800575D88 /* scene.cpp */; };
4EFD0EAB259D581800575D88 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0EAA259D581800575D88 /* OpenGLES.framework */; }; 4EFD0EAB259D581800575D88 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0EAA259D581800575D88 /* OpenGLES.framework */; };
4EFD0EB1259D5BE500575D88 /* librtabmap_utilite.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0EAF259D5BE500575D88 /* librtabmap_utilite.a */; };
4EFD0EB2259D5BE500575D88 /* librtabmap_core.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0EB0259D5BE500575D88 /* librtabmap_core.a */; };
4EFD0EDD259D5BFC00575D88 /* libopencv_video.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0EB4259D5BFB00575D88 /* libopencv_video.a */; };
4EFD0EDE259D5BFC00575D88 /* libopencv_aruco.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0EB5259D5BFB00575D88 /* libopencv_aruco.a */; };
4EFD0EDF259D5BFC00575D88 /* libopencv_photo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0EB6259D5BFB00575D88 /* libopencv_photo.a */; };
4EFD0EE0259D5BFC00575D88 /* libopencv_line_descriptor.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0EB7259D5BFB00575D88 /* libopencv_line_descriptor.a */; };
4EFD0EE1259D5BFC00575D88 /* libopencv_features2d.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0EB8259D5BFB00575D88 /* libopencv_features2d.a */; };
4EFD0EE2259D5BFC00575D88 /* libopencv_bgsegm.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0EB9259D5BFB00575D88 /* libopencv_bgsegm.a */; };
4EFD0EE3259D5BFC00575D88 /* libopencv_dnn_objdetect.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0EBA259D5BFB00575D88 /* libopencv_dnn_objdetect.a */; };
4EFD0EE4259D5BFC00575D88 /* libopencv_objdetect.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0EBB259D5BFB00575D88 /* libopencv_objdetect.a */; };
4EFD0EE5259D5BFC00575D88 /* libopencv_flann.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0EBC259D5BFB00575D88 /* libopencv_flann.a */; };
4EFD0EE6259D5BFC00575D88 /* libopencv_stitching.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0EBD259D5BFB00575D88 /* libopencv_stitching.a */; };
4EFD0EE7259D5BFC00575D88 /* libopencv_imgproc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0EBE259D5BFC00575D88 /* libopencv_imgproc.a */; };
4EFD0EE8259D5BFC00575D88 /* libopencv_ml.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0EBF259D5BFC00575D88 /* libopencv_ml.a */; };
4EFD0EE9259D5BFC00575D88 /* libopencv_rgbd.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0EC0259D5BFC00575D88 /* libopencv_rgbd.a */; };
4EFD0EEA259D5BFC00575D88 /* libopencv_xphoto.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0EC1259D5BFC00575D88 /* libopencv_xphoto.a */; };
4EFD0EEB259D5BFC00575D88 /* libopencv_phase_unwrapping.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0EC2259D5BFC00575D88 /* libopencv_phase_unwrapping.a */; };
4EFD0EEC259D5BFC00575D88 /* libopencv_optflow.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0EC3259D5BFC00575D88 /* libopencv_optflow.a */; };
4EFD0EED259D5BFC00575D88 /* libopencv_imgcodecs.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0EC4259D5BFC00575D88 /* libopencv_imgcodecs.a */; };
4EFD0EEE259D5BFC00575D88 /* libopencv_fuzzy.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0EC5259D5BFC00575D88 /* libopencv_fuzzy.a */; };
4EFD0EEF259D5BFC00575D88 /* libopencv_dpm.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0EC6259D5BFC00575D88 /* libopencv_dpm.a */; };
4EFD0EF0259D5BFC00575D88 /* libopencv_plot.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0EC7259D5BFC00575D88 /* libopencv_plot.a */; };
4EFD0EF1259D5BFC00575D88 /* libopencv_dnn.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0EC8259D5BFC00575D88 /* libopencv_dnn.a */; };
4EFD0EF2259D5BFC00575D88 /* libopencv_saliency.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0EC9259D5BFC00575D88 /* libopencv_saliency.a */; };
4EFD0EF3259D5BFC00575D88 /* libopencv_videoio.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0ECA259D5BFC00575D88 /* libopencv_videoio.a */; };
4EFD0EF4259D5BFC00575D88 /* libopencv_hfs.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0ECB259D5BFC00575D88 /* libopencv_hfs.a */; };
4EFD0EF5259D5BFC00575D88 /* libopencv_tracking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0ECC259D5BFC00575D88 /* libopencv_tracking.a */; };
4EFD0EF6259D5BFC00575D88 /* libopencv_text.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0ECD259D5BFC00575D88 /* libopencv_text.a */; };
4EFD0EF7259D5BFC00575D88 /* libopencv_face.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0ECE259D5BFC00575D88 /* libopencv_face.a */; };
4EFD0EF8259D5BFC00575D88 /* libopencv_bioinspired.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0ECF259D5BFC00575D88 /* libopencv_bioinspired.a */; };
4EFD0EF9259D5BFC00575D88 /* libopencv_highgui.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0ED0259D5BFC00575D88 /* libopencv_highgui.a */; };
4EFD0EFA259D5BFC00575D88 /* libopencv_core.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0ED1259D5BFC00575D88 /* libopencv_core.a */; };
4EFD0EFB259D5BFC00575D88 /* libopencv_shape.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0ED2259D5BFC00575D88 /* libopencv_shape.a */; };
4EFD0EFC259D5BFC00575D88 /* libopencv_datasets.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0ED3259D5BFC00575D88 /* libopencv_datasets.a */; };
4EFD0EFD259D5BFC00575D88 /* libopencv_img_hash.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0ED4259D5BFC00575D88 /* libopencv_img_hash.a */; };
4EFD0EFE259D5BFC00575D88 /* libopencv_surface_matching.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0ED5259D5BFC00575D88 /* libopencv_surface_matching.a */; };
4EFD0EFF259D5BFC00575D88 /* libopencv_calib3d.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0ED6259D5BFC00575D88 /* libopencv_calib3d.a */; };
4EFD0F00259D5BFC00575D88 /* libopencv_structured_light.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0ED7259D5BFC00575D88 /* libopencv_structured_light.a */; };
4EFD0F01259D5BFC00575D88 /* libopencv_reg.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0ED8259D5BFC00575D88 /* libopencv_reg.a */; };
4EFD0F02259D5BFC00575D88 /* libopencv_xfeatures2d.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0ED9259D5BFC00575D88 /* libopencv_xfeatures2d.a */; };
4EFD0F03259D5BFC00575D88 /* libopencv_videostab.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0EDA259D5BFC00575D88 /* libopencv_videostab.a */; };
4EFD0F04259D5BFC00575D88 /* libopencv_ccalib.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0EDB259D5BFC00575D88 /* libopencv_ccalib.a */; };
4EFD0F05259D5BFC00575D88 /* libopencv_ximgproc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0EDC259D5BFC00575D88 /* libopencv_ximgproc.a */; };
4EFD0F1D259D5C2200575D88 /* libg2o_solver_dense.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F07259D5C2100575D88 /* libg2o_solver_dense.a */; };
4EFD0F1E259D5C2200575D88 /* libg2o_ext_csparse.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F08259D5C2100575D88 /* libg2o_ext_csparse.a */; };
4EFD0F1F259D5C2200575D88 /* libg2o_solver_slam2d_linear.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F09259D5C2100575D88 /* libg2o_solver_slam2d_linear.a */; };
4EFD0F20259D5C2200575D88 /* libg2o_types_slam2d.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F0A259D5C2100575D88 /* libg2o_types_slam2d.a */; };
4EFD0F21259D5C2200575D88 /* libg2o_solver_pcg.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F0B259D5C2200575D88 /* libg2o_solver_pcg.a */; };
4EFD0F22259D5C2200575D88 /* libg2o_types_data.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F0C259D5C2200575D88 /* libg2o_types_data.a */; };
4EFD0F23259D5C2200575D88 /* libg2o_core.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F0D259D5C2200575D88 /* libg2o_core.a */; };
4EFD0F24259D5C2200575D88 /* libgtsam_unstable.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F0E259D5C2200575D88 /* libgtsam_unstable.a */; };
4EFD0F25259D5C2200575D88 /* libg2o_types_icp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F0F259D5C2200575D88 /* libg2o_types_icp.a */; };
4EFD0F26259D5C2200575D88 /* libg2o_solver_csparse.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F10259D5C2200575D88 /* libg2o_solver_csparse.a */; };
4EFD0F27259D5C2200575D88 /* libg2o_solver_structure_only.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F11259D5C2200575D88 /* libg2o_solver_structure_only.a */; };
4EFD0F28259D5C2200575D88 /* libg2o_solver_eigen.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F12259D5C2200575D88 /* libg2o_solver_eigen.a */; };
4EFD0F29259D5C2200575D88 /* libg2o_csparse_extension.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F13259D5C2200575D88 /* libg2o_csparse_extension.a */; };
4EFD0F2A259D5C2200575D88 /* libg2o_stuff.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F14259D5C2200575D88 /* libg2o_stuff.a */; };
4EFD0F2B259D5C2200575D88 /* libg2o_types_sba.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F15259D5C2200575D88 /* libg2o_types_sba.a */; };
4EFD0F2C259D5C2200575D88 /* libg2o_types_slam2d_addons.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F16259D5C2200575D88 /* libg2o_types_slam2d_addons.a */; };
4EFD0F2D259D5C2200575D88 /* libg2o_types_slam3d_addons.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F17259D5C2200575D88 /* libg2o_types_slam3d_addons.a */; };
4EFD0F2E259D5C2200575D88 /* libg2o_types_slam3d.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F18259D5C2200575D88 /* libg2o_types_slam3d.a */; };
4EFD0F2F259D5C2200575D88 /* libmetis.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F19259D5C2200575D88 /* libmetis.a */; };
4EFD0F30259D5C2200575D88 /* libg2o_types_sclam2d.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F1A259D5C2200575D88 /* libg2o_types_sclam2d.a */; };
4EFD0F31259D5C2200575D88 /* libg2o_types_sim3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F1B259D5C2200575D88 /* libg2o_types_sim3.a */; };
4EFD0F32259D5C2200575D88 /* libgtsam.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F1C259D5C2200575D88 /* libgtsam.a */; };
4EFD0F34259D5C2900575D88 /* libflann_cpp_s.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F33259D5C2900575D88 /* libflann_cpp_s.a */; };
4EFD0F36259D5C7300575D88 /* vtk.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F35259D5C7300575D88 /* vtk.framework */; }; 4EFD0F36259D5C7300575D88 /* vtk.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F35259D5C7300575D88 /* vtk.framework */; };
4EFD0F3A259D5D1500575D88 /* CameraMobile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4EFD0F38259D5D1500575D88 /* CameraMobile.cpp */; }; 4EFD0F3A259D5D1500575D88 /* CameraMobile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4EFD0F38259D5D1500575D88 /* CameraMobile.cpp */; };
4EFD0F3D259D5D5C00575D88 /* libsqlite3.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F3C259D5D5C00575D88 /* libsqlite3.tbd */; };
4EFD0F50259D67D900575D88 /* liblibwebp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F4B259D67D900575D88 /* liblibwebp.a */; };
4EFD0F51259D67D900575D88 /* liblibpng.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F4C259D67D900575D88 /* liblibpng.a */; };
4EFD0F52259D67D900575D88 /* liblibjpeg-turbo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F4D259D67D900575D88 /* liblibjpeg-turbo.a */; };
4EFD0F53259D67D900575D88 /* libzlib.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F4E259D67D900575D88 /* libzlib.a */; };
4EFD0F54259D67D900575D88 /* liblibprotobuf.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4EFD0F4F259D67D900575D88 /* liblibprotobuf.a */; };
4EFD0F62259E341C00575D88 /* RTABMapApp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4EFD0F61259E341C00575D88 /* RTABMapApp.cpp */; }; 4EFD0F62259E341C00575D88 /* RTABMapApp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4EFD0F61259E341C00575D88 /* RTABMapApp.cpp */; };
4EFD0F67259E38DE00575D88 /* NativeWrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4EFD0F66259E38DE00575D88 /* NativeWrapper.cpp */; }; 4EFD0F67259E38DE00575D88 /* NativeWrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4EFD0F66259E38DE00575D88 /* NativeWrapper.cpp */; };
4EFD0F70259F847300575D88 /* background_renderer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4EFD0F6E259F847300575D88 /* background_renderer.cc */; }; 4EFD0F70259F847300575D88 /* background_renderer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4EFD0F6E259F847300575D88 /* background_renderer.cc */; };
@@ -160,6 +129,42 @@
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
44D4681D2D538A4100B094BA /* RTABMapApp.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = RTABMapApp.entitlements; path = RTABMapApp/RTABMapApp.entitlements; sourceTree = "<group>"; }; 44D4681D2D538A4100B094BA /* RTABMapApp.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = RTABMapApp.entitlements; path = RTABMapApp/RTABMapApp.entitlements; sourceTree = "<group>"; };
4E0D83822621F52C00C879AC /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = "<group>"; }; 4E0D83822621F52C00C879AC /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = "<group>"; };
4E10D8602DE408EE0015926D /* libboost_stacktrace_noop.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libboost_stacktrace_noop.a; path = RTABMapApp/Libraries/lib/libboost_stacktrace_noop.a; sourceTree = "<group>"; };
4E10D8612DE408EE0015926D /* libboost_wserialization.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libboost_wserialization.a; path = RTABMapApp/Libraries/lib/libboost_wserialization.a; sourceTree = "<group>"; };
4E10D8622DE408EE0015926D /* libmetis-gtsam.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libmetis-gtsam.a"; path = "RTABMapApp/Libraries/lib/libmetis-gtsam.a"; sourceTree = "<group>"; };
4E10D8632DE408EE0015926D /* libopencv_wechat_qrcode.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libopencv_wechat_qrcode.a; path = RTABMapApp/Libraries/lib/libopencv_wechat_qrcode.a; sourceTree = "<group>"; };
4E10D8642DE408EE0015926D /* libboost_container.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libboost_container.a; path = RTABMapApp/Libraries/lib/libboost_container.a; sourceTree = "<group>"; };
4E10D8652DE408EE0015926D /* libboost_graph.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libboost_graph.a; path = RTABMapApp/Libraries/lib/libboost_graph.a; sourceTree = "<group>"; };
4E10D8662DE408EE0015926D /* libboost_json.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libboost_json.a; path = RTABMapApp/Libraries/lib/libboost_json.a; sourceTree = "<group>"; };
4E10D8672DE408EE0015926D /* libboost_stacktrace_basic.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libboost_stacktrace_basic.a; path = RTABMapApp/Libraries/lib/libboost_stacktrace_basic.a; sourceTree = "<group>"; };
4E10D8682DE408EE0015926D /* libboost_atomic.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libboost_atomic.a; path = RTABMapApp/Libraries/lib/libboost_atomic.a; sourceTree = "<group>"; };
4E10D8692DE408EE0015926D /* libopencv_intensity_transform.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libopencv_intensity_transform.a; path = RTABMapApp/Libraries/lib/libopencv_intensity_transform.a; sourceTree = "<group>"; };
4E10D86A2DE408EF0015926D /* libboost_locale.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libboost_locale.a; path = RTABMapApp/Libraries/lib/libboost_locale.a; sourceTree = "<group>"; };
4E10D86B2DE408EF0015926D /* liblz4.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liblz4.a; path = RTABMapApp/Libraries/lib/liblz4.a; sourceTree = "<group>"; };
4E10D86C2DE408EF0015926D /* libopencv_dnn_superres.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libopencv_dnn_superres.a; path = RTABMapApp/Libraries/lib/libopencv_dnn_superres.a; sourceTree = "<group>"; };
4E10D86D2DE408EF0015926D /* libopencv_rapid.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libopencv_rapid.a; path = RTABMapApp/Libraries/lib/libopencv_rapid.a; sourceTree = "<group>"; };
4E10D86E2DE408EF0015926D /* libopencv_quality.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libopencv_quality.a; path = RTABMapApp/Libraries/lib/libopencv_quality.a; sourceTree = "<group>"; };
4E10D86F2DE408EF0015926D /* libboost_url.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libboost_url.a; path = RTABMapApp/Libraries/lib/libboost_url.a; sourceTree = "<group>"; };
4E10D8702DE408EF0015926D /* libboost_unit_test_framework.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libboost_unit_test_framework.a; path = RTABMapApp/Libraries/lib/libboost_unit_test_framework.a; sourceTree = "<group>"; };
4E10D8712DE408EF0015926D /* libboost_random.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libboost_random.a; path = RTABMapApp/Libraries/lib/libboost_random.a; sourceTree = "<group>"; };
4E10D8722DE408EF0015926D /* libboost_wave.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libboost_wave.a; path = RTABMapApp/Libraries/lib/libboost_wave.a; sourceTree = "<group>"; };
4E10D8732DE408EF0015926D /* libboost_charconv.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libboost_charconv.a; path = RTABMapApp/Libraries/lib/libboost_charconv.a; sourceTree = "<group>"; };
4E10D8742DE408EF0015926D /* libboost_type_erasure.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libboost_type_erasure.a; path = RTABMapApp/Libraries/lib/libboost_type_erasure.a; sourceTree = "<group>"; };
4E10D8752DE408EF0015926D /* liblas_c.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liblas_c.a; path = RTABMapApp/Libraries/lib/liblas_c.a; sourceTree = "<group>"; };
4E10D8762DE408EF0015926D /* libboost_contract.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libboost_contract.a; path = RTABMapApp/Libraries/lib/libboost_contract.a; sourceTree = "<group>"; };
4E10D8772DE408EF0015926D /* libopencv_gapi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libopencv_gapi.a; path = RTABMapApp/Libraries/lib/libopencv_gapi.a; sourceTree = "<group>"; };
4E10D8782DE408EF0015926D /* libopencv_signal.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libopencv_signal.a; path = RTABMapApp/Libraries/lib/libopencv_signal.a; sourceTree = "<group>"; };
4E10D8792DE408EF0015926D /* libboost_prg_exec_monitor.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libboost_prg_exec_monitor.a; path = RTABMapApp/Libraries/lib/libboost_prg_exec_monitor.a; sourceTree = "<group>"; };
4E10D87A2DE408EF0015926D /* libboost_stacktrace_addr2line.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libboost_stacktrace_addr2line.a; path = RTABMapApp/Libraries/lib/libboost_stacktrace_addr2line.a; sourceTree = "<group>"; };
4E10D87B2DE408EF0015926D /* libboost_nowide.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libboost_nowide.a; path = RTABMapApp/Libraries/lib/libboost_nowide.a; sourceTree = "<group>"; };
4E10D87C2DE408EF0015926D /* libboost_test_exec_monitor.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libboost_test_exec_monitor.a; path = RTABMapApp/Libraries/lib/libboost_test_exec_monitor.a; sourceTree = "<group>"; };
4E10D87D2DE408EF0015926D /* libopencv_mcc.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libopencv_mcc.a; path = RTABMapApp/Libraries/lib/libopencv_mcc.a; sourceTree = "<group>"; };
4E10D8D52DE40FBE0015926D /* liblibjpeg-turbo.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "liblibjpeg-turbo.a"; path = "RTABMapApp/Libraries/lib/opencv4/3rdparty/liblibjpeg-turbo.a"; sourceTree = "<group>"; };
4E10D8D72DE40FCA0015926D /* liblibpng.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liblibpng.a; path = RTABMapApp/Libraries/lib/opencv4/3rdparty/liblibpng.a; sourceTree = "<group>"; };
4E10D8D92DE40FF60015926D /* libzlib.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libzlib.a; path = RTABMapApp/Libraries/lib/opencv4/3rdparty/libzlib.a; sourceTree = "<group>"; };
4E10D8DA2DE40FF60015926D /* libIlmImf.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libIlmImf.a; path = RTABMapApp/Libraries/lib/opencv4/3rdparty/libIlmImf.a; sourceTree = "<group>"; };
4E10D8DB2DE40FF60015926D /* libade.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libade.a; path = RTABMapApp/Libraries/lib/opencv4/3rdparty/libade.a; sourceTree = "<group>"; };
4E10D8DC2DE40FF60015926D /* liblibprotobuf.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liblibprotobuf.a; path = RTABMapApp/Libraries/lib/opencv4/3rdparty/liblibprotobuf.a; sourceTree = "<group>"; };
4E1E9CF22D617D08000CB881 /* Measure.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Measure.h; path = ../android/jni/Measure.h; sourceTree = "<group>"; }; 4E1E9CF22D617D08000CB881 /* Measure.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Measure.h; path = ../android/jni/Measure.h; sourceTree = "<group>"; };
4E1E9CF32D618079000CB881 /* quad_color.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = quad_color.h; path = ../android/jni/quad_color.h; sourceTree = "<group>"; }; 4E1E9CF32D618079000CB881 /* quad_color.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = quad_color.h; path = ../android/jni/quad_color.h; sourceTree = "<group>"; };
4E1E9CF42D618079000CB881 /* text_drawable.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = text_drawable.h; path = ../android/jni/text_drawable.h; sourceTree = "<group>"; }; 4E1E9CF42D618079000CB881 /* text_drawable.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = text_drawable.h; path = ../android/jni/text_drawable.h; sourceTree = "<group>"; };
@@ -170,6 +175,15 @@
4E20B24F266AB95600316EE6 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = RTABMapApp/Images.xcassets; sourceTree = "<group>"; }; 4E20B24F266AB95600316EE6 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = RTABMapApp/Images.xcassets; sourceTree = "<group>"; };
4E2C516525A63119005CEDBD /* DatabaseView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = DatabaseView.swift; path = RTABMapApp/DatabaseView.swift; sourceTree = "<group>"; }; 4E2C516525A63119005CEDBD /* DatabaseView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = DatabaseView.swift; path = RTABMapApp/DatabaseView.swift; sourceTree = "<group>"; };
4E2C516625A63119005CEDBD /* VerticalScrollerView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = VerticalScrollerView.swift; path = RTABMapApp/VerticalScrollerView.swift; sourceTree = "<group>"; }; 4E2C516625A63119005CEDBD /* VerticalScrollerView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = VerticalScrollerView.swift; path = RTABMapApp/VerticalScrollerView.swift; sourceTree = "<group>"; };
4E3525562DE4C6E500F39D8F /* libg2o_solver_cholmod.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libg2o_solver_cholmod.a; path = RTABMapApp/Libraries/lib/libg2o_solver_cholmod.a; sourceTree = "<group>"; };
4E3525582DE4C6F600F39D8F /* libcholmod.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libcholmod.a; path = RTABMapApp/Libraries/lib/libcholmod.a; sourceTree = "<group>"; };
4E35255A2DE4C71000F39D8F /* libcxsparse.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libcxsparse.a; path = RTABMapApp/Libraries/lib/libcxsparse.a; sourceTree = "<group>"; };
4E35255B2DE4C71000F39D8F /* libcolamd.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libcolamd.a; path = RTABMapApp/Libraries/lib/libcolamd.a; sourceTree = "<group>"; };
4E35255C2DE4C71000F39D8F /* libcamd.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libcamd.a; path = RTABMapApp/Libraries/lib/libcamd.a; sourceTree = "<group>"; };
4E35255D2DE4C71000F39D8F /* libccolamd.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libccolamd.a; path = RTABMapApp/Libraries/lib/libccolamd.a; sourceTree = "<group>"; };
4E3525622DE4C71C00F39D8F /* libsuitesparseconfig.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libsuitesparseconfig.a; path = RTABMapApp/Libraries/lib/libsuitesparseconfig.a; sourceTree = "<group>"; };
4E3525632DE4C71C00F39D8F /* libspqr.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libspqr.a; path = RTABMapApp/Libraries/lib/libspqr.a; sourceTree = "<group>"; };
4E3525662DE4C72D00F39D8F /* libamd.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libamd.a; path = RTABMapApp/Libraries/lib/libamd.a; sourceTree = "<group>"; };
4E401BE825CC92C100240A56 /* ProgressionStatus.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ProgressionStatus.h; path = ../android/jni/ProgressionStatus.h; sourceTree = "<group>"; }; 4E401BE825CC92C100240A56 /* ProgressionStatus.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ProgressionStatus.h; path = ../android/jni/ProgressionStatus.h; sourceTree = "<group>"; };
4EB1A66525A0D90B0043C7BF /* RTABMap.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = RTABMap.swift; path = RTABMapApp/RTABMap.swift; sourceTree = "<group>"; }; 4EB1A66525A0D90B0043C7BF /* RTABMap.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = RTABMap.swift; path = RTABMapApp/RTABMap.swift; sourceTree = "<group>"; };
4ED73AD02D7FECF3007899C2 /* liblaszip.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liblaszip.a; path = RTABMapApp/Libraries/lib/liblaszip.a; sourceTree = "<group>"; }; 4ED73AD02D7FECF3007899C2 /* liblaszip.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liblaszip.a; path = RTABMapApp/Libraries/lib/liblaszip.a; sourceTree = "<group>"; };
@@ -356,110 +370,79 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
4EFAA9432CAE4E960055DA51 /* liblas.a in Frameworks */,
4ED73AD12D7FECF3007899C2 /* liblaszip.a in Frameworks */,
4EFD0F50259D67D900575D88 /* liblibwebp.a in Frameworks */,
4EFD0F51259D67D900575D88 /* liblibpng.a in Frameworks */,
4EFD0F52259D67D900575D88 /* liblibjpeg-turbo.a in Frameworks */,
4EFD0F53259D67D900575D88 /* libzlib.a in Frameworks */,
4EFD0F54259D67D900575D88 /* liblibprotobuf.a in Frameworks */,
4EFD0F3D259D5D5C00575D88 /* libsqlite3.tbd in Frameworks */,
4EFD0F36259D5C7300575D88 /* vtk.framework in Frameworks */,
4EFD0F34259D5C2900575D88 /* libflann_cpp_s.a in Frameworks */,
4EFD0F1D259D5C2200575D88 /* libg2o_solver_dense.a in Frameworks */,
4EFD0F1E259D5C2200575D88 /* libg2o_ext_csparse.a in Frameworks */,
4EFD0F1F259D5C2200575D88 /* libg2o_solver_slam2d_linear.a in Frameworks */,
4EFD0F20259D5C2200575D88 /* libg2o_types_slam2d.a in Frameworks */,
4EFD0F21259D5C2200575D88 /* libg2o_solver_pcg.a in Frameworks */,
4EFD0F22259D5C2200575D88 /* libg2o_types_data.a in Frameworks */,
4EFD0F23259D5C2200575D88 /* libg2o_core.a in Frameworks */,
4EFD0F24259D5C2200575D88 /* libgtsam_unstable.a in Frameworks */,
4EFD0F25259D5C2200575D88 /* libg2o_types_icp.a in Frameworks */,
4EFD0F26259D5C2200575D88 /* libg2o_solver_csparse.a in Frameworks */,
4EFD0F27259D5C2200575D88 /* libg2o_solver_structure_only.a in Frameworks */,
4EFD0F28259D5C2200575D88 /* libg2o_solver_eigen.a in Frameworks */,
4EFD0F29259D5C2200575D88 /* libg2o_csparse_extension.a in Frameworks */,
4EFD0F2A259D5C2200575D88 /* libg2o_stuff.a in Frameworks */,
4EFD0F2B259D5C2200575D88 /* libg2o_types_sba.a in Frameworks */,
4EFD0F2C259D5C2200575D88 /* libg2o_types_slam2d_addons.a in Frameworks */,
4EFD0F2D259D5C2200575D88 /* libg2o_types_slam3d_addons.a in Frameworks */,
4EFD0F2E259D5C2200575D88 /* libg2o_types_slam3d.a in Frameworks */,
4EFD0F2F259D5C2200575D88 /* libmetis.a in Frameworks */,
4EFD0F30259D5C2200575D88 /* libg2o_types_sclam2d.a in Frameworks */,
4EFD0F31259D5C2200575D88 /* libg2o_types_sim3.a in Frameworks */,
4EFD0F32259D5C2200575D88 /* libgtsam.a in Frameworks */,
4E8B155426273A580037FC53 /* Zip in Frameworks */, 4E8B155426273A580037FC53 /* Zip in Frameworks */,
4EFD0EDD259D5BFC00575D88 /* libopencv_video.a in Frameworks */, 4EFD0F36259D5C7300575D88 /* vtk.framework in Frameworks */,
4EFD0EDE259D5BFC00575D88 /* libopencv_aruco.a in Frameworks */,
4EFD0EDF259D5BFC00575D88 /* libopencv_photo.a in Frameworks */,
4EFD0EE0259D5BFC00575D88 /* libopencv_line_descriptor.a in Frameworks */,
4EFD0EE1259D5BFC00575D88 /* libopencv_features2d.a in Frameworks */,
4EFD0EE2259D5BFC00575D88 /* libopencv_bgsegm.a in Frameworks */,
4EFD0EE3259D5BFC00575D88 /* libopencv_dnn_objdetect.a in Frameworks */,
4EFD0EE4259D5BFC00575D88 /* libopencv_objdetect.a in Frameworks */,
4EFD0EE5259D5BFC00575D88 /* libopencv_flann.a in Frameworks */,
4EFD0EE6259D5BFC00575D88 /* libopencv_stitching.a in Frameworks */,
4EFD0EE7259D5BFC00575D88 /* libopencv_imgproc.a in Frameworks */,
4EFD0EE8259D5BFC00575D88 /* libopencv_ml.a in Frameworks */,
4EFD0EE9259D5BFC00575D88 /* libopencv_rgbd.a in Frameworks */,
4EFD0EEA259D5BFC00575D88 /* libopencv_xphoto.a in Frameworks */,
4EFD0EEB259D5BFC00575D88 /* libopencv_phase_unwrapping.a in Frameworks */,
4EFD0EEC259D5BFC00575D88 /* libopencv_optflow.a in Frameworks */,
4EFD0EED259D5BFC00575D88 /* libopencv_imgcodecs.a in Frameworks */,
4EFD0EEE259D5BFC00575D88 /* libopencv_fuzzy.a in Frameworks */,
4EFD0EEF259D5BFC00575D88 /* libopencv_dpm.a in Frameworks */,
4EFD0EF0259D5BFC00575D88 /* libopencv_plot.a in Frameworks */,
4EFD0EF1259D5BFC00575D88 /* libopencv_dnn.a in Frameworks */,
4EFD0EF2259D5BFC00575D88 /* libopencv_saliency.a in Frameworks */,
4EFD0EF3259D5BFC00575D88 /* libopencv_videoio.a in Frameworks */,
4EFD0EF4259D5BFC00575D88 /* libopencv_hfs.a in Frameworks */,
4EFD0EF5259D5BFC00575D88 /* libopencv_tracking.a in Frameworks */,
4EFD0EF6259D5BFC00575D88 /* libopencv_text.a in Frameworks */,
4EFD0EF7259D5BFC00575D88 /* libopencv_face.a in Frameworks */,
4EFD0EF8259D5BFC00575D88 /* libopencv_bioinspired.a in Frameworks */,
4EFD0EF9259D5BFC00575D88 /* libopencv_highgui.a in Frameworks */,
4EFD0EFA259D5BFC00575D88 /* libopencv_core.a in Frameworks */,
4EFD0EFB259D5BFC00575D88 /* libopencv_shape.a in Frameworks */,
4EFD0EFC259D5BFC00575D88 /* libopencv_datasets.a in Frameworks */,
4EFD0EFD259D5BFC00575D88 /* libopencv_img_hash.a in Frameworks */,
4EFD0EFE259D5BFC00575D88 /* libopencv_surface_matching.a in Frameworks */,
4EFD0EFF259D5BFC00575D88 /* libopencv_calib3d.a in Frameworks */,
4EFD0F00259D5BFC00575D88 /* libopencv_structured_light.a in Frameworks */,
4EFD0F01259D5BFC00575D88 /* libopencv_reg.a in Frameworks */,
4EFD0F02259D5BFC00575D88 /* libopencv_xfeatures2d.a in Frameworks */,
4EFD0F03259D5BFC00575D88 /* libopencv_videostab.a in Frameworks */,
4EFD0F04259D5BFC00575D88 /* libopencv_ccalib.a in Frameworks */,
4EFD0F05259D5BFC00575D88 /* libopencv_ximgproc.a in Frameworks */,
4EFD0EB1259D5BE500575D88 /* librtabmap_utilite.a in Frameworks */,
4EFD0EB2259D5BE500575D88 /* librtabmap_core.a in Frameworks */,
4EFD0EAB259D581800575D88 /* OpenGLES.framework in Frameworks */, 4EFD0EAB259D581800575D88 /* OpenGLES.framework in Frameworks */,
4EFD0B36259D4DE900575D88 /* libboost_filesystem.a in Frameworks */, 4E10D89C2DE409870015926D /* librtabmap_core.a in Frameworks */,
4EFD0B37259D4DE900575D88 /* libboost_program_options.a in Frameworks */, 4E10D89D2DE409870015926D /* librtabmap_utilite.a in Frameworks */,
4EFD0B38259D4DE900575D88 /* libboost_regex.a in Frameworks */, 4E10D89E2DE409A60015926D /* libopencv_xfeatures2d.a in Frameworks */,
4EFD0B39259D4DE900575D88 /* libboost_iostreams.a in Frameworks */, 4E10D89F2DE409B20015926D /* libopencv_video.a in Frameworks */,
4EFD0B3A259D4DE900575D88 /* libboost_date_time.a in Frameworks */, 4E10D8A02DE409BB0015926D /* libopencv_tracking.a in Frameworks */,
4EFD0B3B259D4DE900575D88 /* libboost_serialization.a in Frameworks */, 4E10D8A12DE409C00015926D /* libopencv_optflow.a in Frameworks */,
4EFD0B3C259D4DE900575D88 /* libboost_system.a in Frameworks */, 4E10D8A22DE409C70015926D /* libopencv_imgproc.a in Frameworks */,
4EFD0B3D259D4DE900575D88 /* libboost_signals.a in Frameworks */, 4E10D8A32DE409CA0015926D /* libopencv_features2d.a in Frameworks */,
4EFD0B3E259D4DE900575D88 /* libboost_thread.a in Frameworks */, 4E10D8A42DE409CE0015926D /* libopencv_core.a in Frameworks */,
4EFD0B3F259D4DE900575D88 /* libboost_timer.a in Frameworks */, 4E10D8A52DE409D10015926D /* libopencv_calib3d.a in Frameworks */,
4EFD0B40259D4DE900575D88 /* libboost_chrono.a in Frameworks */, 4E10D8A62DE409D50015926D /* libopencv_aruco.a in Frameworks */,
4EFD0B51259D4DF100575D88 /* libpcl_stereo.a in Frameworks */, 4E10D8A72DE409F40015926D /* libopencv_flann.a in Frameworks */,
4EFD0B52259D4DF100575D88 /* libpcl_registration.a in Frameworks */, 4E10D8A82DE40A1B0015926D /* libopencv_ximgproc.a in Frameworks */,
4EFD0B53259D4DF100575D88 /* libpcl_features.a in Frameworks */, 4E10D8A92DE40A3A0015926D /* libopencv_photo.a in Frameworks */,
4EFD0B54259D4DF100575D88 /* libpcl_filters.a in Frameworks */, 4E10D8AA2DE40A6C0015926D /* libopencv_objdetect.a in Frameworks */,
4EFD0B55259D4DF100575D88 /* libpcl_sample_consensus.a in Frameworks */, 4E10D8AB2DE40A8C0015926D /* libopencv_stitching.a in Frameworks */,
4EFD0B56259D4DF100575D88 /* libpcl_kdtree.a in Frameworks */, 4E10D8AC2DE40AA20015926D /* libopencv_imgcodecs.a in Frameworks */,
4EFD0B57259D4DF100575D88 /* libpcl_search.a in Frameworks */, 4E3525672DE4C72D00F39D8F /* libamd.a in Frameworks */,
4EFD0B58259D4DF100575D88 /* libpcl_surface.a in Frameworks */, 4E3525642DE4C71C00F39D8F /* libsuitesparseconfig.a in Frameworks */,
4EFD0B59259D4DF100575D88 /* libpcl_keypoints.a in Frameworks */, 4E3525652DE4C71C00F39D8F /* libspqr.a in Frameworks */,
4EFD0B5A259D4DF100575D88 /* libpcl_recognition.a in Frameworks */, 4E35255E2DE4C71000F39D8F /* libcxsparse.a in Frameworks */,
4EFD0B5B259D4DF100575D88 /* libpcl_octree.a in Frameworks */, 4E35255F2DE4C71000F39D8F /* libcolamd.a in Frameworks */,
4EFD0B5C259D4DF100575D88 /* libpcl_io.a in Frameworks */, 4E3525602DE4C71000F39D8F /* libcamd.a in Frameworks */,
4EFD0B5D259D4DF100575D88 /* libpcl_common.a in Frameworks */, 4E3525612DE4C71000F39D8F /* libccolamd.a in Frameworks */,
4EFD0B5E259D4DF100575D88 /* libpcl_io_ply.a in Frameworks */, 4E3525592DE4C6F600F39D8F /* libcholmod.a in Frameworks */,
4EFD0B5F259D4DF100575D88 /* libpcl_ml.a in Frameworks */, 4E10D8AD2DE40E990015926D /* libg2o_core.a in Frameworks */,
4EFD0B60259D4DF100575D88 /* libpcl_segmentation.a in Frameworks */, 4E3525572DE4C6E500F39D8F /* libg2o_solver_cholmod.a in Frameworks */,
4E3525542DE4C6E500F39D8F /* libg2o_csparse_extension.a in Frameworks */,
4E3525552DE4C6E500F39D8F /* libg2o_solver_csparse.a in Frameworks */,
4E10D8AE2DE40E990015926D /* libg2o_solver_dense.a in Frameworks */,
4E10D8AF2DE40E990015926D /* libg2o_solver_eigen.a in Frameworks */,
4E10D8B02DE40E990015926D /* libg2o_solver_pcg.a in Frameworks */,
4E10D8B12DE40E990015926D /* libg2o_solver_slam2d_linear.a in Frameworks */,
4E10D8B22DE40E990015926D /* libg2o_solver_structure_only.a in Frameworks */,
4E10D8B32DE40E990015926D /* libg2o_stuff.a in Frameworks */,
4E10D8B42DE40E990015926D /* libg2o_types_data.a in Frameworks */,
4E10D8B52DE40E990015926D /* libg2o_types_icp.a in Frameworks */,
4E10D8B62DE40E990015926D /* libg2o_types_sba.a in Frameworks */,
4E10D8B72DE40E990015926D /* libg2o_types_sclam2d.a in Frameworks */,
4E10D8B82DE40E990015926D /* libg2o_types_sim3.a in Frameworks */,
4E10D8B92DE40E990015926D /* libg2o_types_slam2d_addons.a in Frameworks */,
4E10D8BA2DE40E990015926D /* libg2o_types_slam2d.a in Frameworks */,
4E10D8BB2DE40E990015926D /* libg2o_types_slam3d_addons.a in Frameworks */,
4E10D8BC2DE40E990015926D /* libg2o_types_slam3d.a in Frameworks */,
4E10D8BD2DE40EC70015926D /* libpcl_common.a in Frameworks */,
4E10D8BE2DE40EC70015926D /* libpcl_features.a in Frameworks */,
4E10D8BF2DE40EC70015926D /* libpcl_filters.a in Frameworks */,
4E10D8C02DE40EC70015926D /* libpcl_io_ply.a in Frameworks */,
4E10D8C12DE40EC70015926D /* libpcl_io.a in Frameworks */,
4E10D8C22DE40EC70015926D /* libpcl_kdtree.a in Frameworks */,
4E10D8C32DE40EC70015926D /* libpcl_keypoints.a in Frameworks */,
4E10D8C42DE40EC70015926D /* libpcl_ml.a in Frameworks */,
4E10D8C52DE40EC70015926D /* libpcl_octree.a in Frameworks */,
4E10D8C62DE40EC70015926D /* libpcl_registration.a in Frameworks */,
4E10D8C72DE40EC70015926D /* libpcl_sample_consensus.a in Frameworks */,
4E10D8C82DE40EC70015926D /* libpcl_search.a in Frameworks */,
4E10D8C92DE40EC70015926D /* libpcl_segmentation.a in Frameworks */,
4E10D8CA2DE40EC70015926D /* libpcl_stereo.a in Frameworks */,
4E10D8CB2DE40EC70015926D /* libpcl_surface.a in Frameworks */,
4E10D8CC2DE40EE30015926D /* libgtsam_unstable.a in Frameworks */,
4E10D8CD2DE40EE30015926D /* libgtsam.a in Frameworks */,
4E10D8CE2DE40EE30015926D /* libmetis-gtsam.a in Frameworks */,
4E10D8CF2DE40EF90015926D /* libboost_serialization.a in Frameworks */,
4E10D8D02DE40F060015926D /* libboost_timer.a in Frameworks */,
4E10D8D42DE40F2A0015926D /* libboost_thread.a in Frameworks */,
4E10D8D12DE40F190015926D /* liblas_c.a in Frameworks */,
4E10D8D22DE40F190015926D /* liblas.a in Frameworks */,
4E10D8D32DE40F190015926D /* liblaszip.a in Frameworks */,
4E10D8E12DE4101B0015926D /* liblibjpeg-turbo.a in Frameworks */,
4E10D8E22DE4101B0015926D /* liblibpng.a in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -509,6 +492,51 @@
4EFD0B2A259D4DE900575D88 /* Frameworks */ = { 4EFD0B2A259D4DE900575D88 /* Frameworks */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
4E3525662DE4C72D00F39D8F /* libamd.a */,
4E3525632DE4C71C00F39D8F /* libspqr.a */,
4E3525622DE4C71C00F39D8F /* libsuitesparseconfig.a */,
4E35255C2DE4C71000F39D8F /* libcamd.a */,
4E35255D2DE4C71000F39D8F /* libccolamd.a */,
4E35255B2DE4C71000F39D8F /* libcolamd.a */,
4E35255A2DE4C71000F39D8F /* libcxsparse.a */,
4E3525582DE4C6F600F39D8F /* libcholmod.a */,
4E3525562DE4C6E500F39D8F /* libg2o_solver_cholmod.a */,
4E10D8DB2DE40FF60015926D /* libade.a */,
4E10D8DA2DE40FF60015926D /* libIlmImf.a */,
4E10D8DC2DE40FF60015926D /* liblibprotobuf.a */,
4E10D8D92DE40FF60015926D /* libzlib.a */,
4E10D8D72DE40FCA0015926D /* liblibpng.a */,
4E10D8D52DE40FBE0015926D /* liblibjpeg-turbo.a */,
4E10D8682DE408EE0015926D /* libboost_atomic.a */,
4E10D8732DE408EF0015926D /* libboost_charconv.a */,
4E10D8642DE408EE0015926D /* libboost_container.a */,
4E10D8762DE408EF0015926D /* libboost_contract.a */,
4E10D8652DE408EE0015926D /* libboost_graph.a */,
4E10D8662DE408EE0015926D /* libboost_json.a */,
4E10D86A2DE408EF0015926D /* libboost_locale.a */,
4E10D87B2DE408EF0015926D /* libboost_nowide.a */,
4E10D8792DE408EF0015926D /* libboost_prg_exec_monitor.a */,
4E10D8712DE408EF0015926D /* libboost_random.a */,
4E10D87A2DE408EF0015926D /* libboost_stacktrace_addr2line.a */,
4E10D8672DE408EE0015926D /* libboost_stacktrace_basic.a */,
4E10D8602DE408EE0015926D /* libboost_stacktrace_noop.a */,
4E10D87C2DE408EF0015926D /* libboost_test_exec_monitor.a */,
4E10D8742DE408EF0015926D /* libboost_type_erasure.a */,
4E10D8702DE408EF0015926D /* libboost_unit_test_framework.a */,
4E10D86F2DE408EF0015926D /* libboost_url.a */,
4E10D8722DE408EF0015926D /* libboost_wave.a */,
4E10D8612DE408EE0015926D /* libboost_wserialization.a */,
4E10D8752DE408EF0015926D /* liblas_c.a */,
4E10D86B2DE408EF0015926D /* liblz4.a */,
4E10D8622DE408EE0015926D /* libmetis-gtsam.a */,
4E10D86C2DE408EF0015926D /* libopencv_dnn_superres.a */,
4E10D8772DE408EF0015926D /* libopencv_gapi.a */,
4E10D8692DE408EE0015926D /* libopencv_intensity_transform.a */,
4E10D87D2DE408EF0015926D /* libopencv_mcc.a */,
4E10D86E2DE408EF0015926D /* libopencv_quality.a */,
4E10D86D2DE408EF0015926D /* libopencv_rapid.a */,
4E10D8782DE408EF0015926D /* libopencv_signal.a */,
4E10D8632DE408EE0015926D /* libopencv_wechat_qrcode.a */,
4ED73AD02D7FECF3007899C2 /* liblaszip.a */, 4ED73AD02D7FECF3007899C2 /* liblaszip.a */,
4EFAA9422CAE4E960055DA51 /* liblas.a */, 4EFAA9422CAE4E960055DA51 /* liblas.a */,
4EFD0F4D259D67D900575D88 /* liblibjpeg-turbo.a */, 4EFD0F4D259D67D900575D88 /* liblibjpeg-turbo.a */,
@@ -889,7 +917,7 @@
ALWAYS_SEARCH_USER_PATHS = NO; ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
CLANG_CXX_LIBRARY = "libc++"; CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_ARC = YES;
@@ -920,7 +948,7 @@
DEBUG_INFORMATION_FORMAT = dwarf; DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES; ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11; GCC_C_LANGUAGE_STANDARD = gnu17;
GCC_DYNAMIC_NO_PIC = NO; GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES; GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0; GCC_OPTIMIZATION_LEVEL = 0;
@@ -950,7 +978,7 @@
ALWAYS_SEARCH_USER_PATHS = NO; ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
CLANG_CXX_LIBRARY = "libc++"; CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_ARC = YES;
@@ -981,7 +1009,7 @@
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO; ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11; GCC_C_LANGUAGE_STANDARD = gnu17;
GCC_NO_COMMON_BLOCKS = YES; GCC_NO_COMMON_BLOCKS = YES;
GCC_PREPROCESSOR_DEFINITIONS = ""; GCC_PREPROCESSOR_DEFINITIONS = "";
GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
@@ -1035,8 +1063,9 @@
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)/RTABMapApp/Libraries/lib", "$(PROJECT_DIR)/RTABMapApp/Libraries/lib",
"$(PROJECT_DIR)/RTABMapApp/Libraries/share/OpenCV/3rdparty/lib", "$(PROJECT_DIR)/RTABMapApp/Libraries/share/OpenCV/3rdparty/lib",
"$(PROJECT_DIR)/RTABMapApp/Libraries/lib/opencv4/3rdparty",
); );
MARKETING_VERSION = 0.21.11; MARKETING_VERSION = 0.22.0;
OTHER_CFLAGS = ""; OTHER_CFLAGS = "";
PRODUCT_BUNDLE_IDENTIFIER = com.introlab.rtabmap; PRODUCT_BUNDLE_IDENTIFIER = com.introlab.rtabmap;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
@@ -1048,11 +1077,12 @@
SYSTEM_HEADER_SEARCH_PATHS = ( SYSTEM_HEADER_SEARCH_PATHS = (
"\"$(SRCROOT)/RTABMapApp/Libraries/include\"", "\"$(SRCROOT)/RTABMapApp/Libraries/include\"",
"\"$(SRCROOT)/RTABMapApp/Libraries/include/eigen3\"", "\"$(SRCROOT)/RTABMapApp/Libraries/include/eigen3\"",
"\"$(SRCROOT)/RTABMapApp/Libraries/include/pcl-1.11\"", "\"$(SRCROOT)/RTABMapApp/Libraries/include/pcl-1.15\"",
"\"$(SRCROOT)/RTABMapApp/Libraries/include/rtabmap-0.21\"", "\"$(SRCROOT)/RTABMapApp/Libraries/include/rtabmap-0.22\"",
"\"$(SRCROOT)/../android/jni/tango-gl/include\"", "\"$(SRCROOT)/../android/jni/tango-gl/include\"",
"\"$(SRCROOT)/../android/jni/third-party/include\"", "\"$(SRCROOT)/../android/jni/third-party/include\"",
"\"$(SRCROOT)/RTABMapApp/Libraries/lib/vtk.framework/Headers\"", "\"$(SRCROOT)/RTABMapApp/Libraries/lib/vtk.framework/Headers\"",
"\"$(SRCROOT)/RTABMapApp/Libraries/include/opencv4\"",
); );
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_WORKSPACE = NO; VALIDATE_WORKSPACE = NO;
@@ -1093,8 +1123,9 @@
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)/RTABMapApp/Libraries/lib", "$(PROJECT_DIR)/RTABMapApp/Libraries/lib",
"$(PROJECT_DIR)/RTABMapApp/Libraries/share/OpenCV/3rdparty/lib", "$(PROJECT_DIR)/RTABMapApp/Libraries/share/OpenCV/3rdparty/lib",
"$(PROJECT_DIR)/RTABMapApp/Libraries/lib/opencv4/3rdparty",
); );
MARKETING_VERSION = 0.21.11; MARKETING_VERSION = 0.22.0;
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
OTHER_CFLAGS = ""; OTHER_CFLAGS = "";
PRODUCT_BUNDLE_IDENTIFIER = com.introlab.rtabmap; PRODUCT_BUNDLE_IDENTIFIER = com.introlab.rtabmap;
@@ -1107,11 +1138,12 @@
SYSTEM_HEADER_SEARCH_PATHS = ( SYSTEM_HEADER_SEARCH_PATHS = (
"\"$(SRCROOT)/RTABMapApp/Libraries/include\"", "\"$(SRCROOT)/RTABMapApp/Libraries/include\"",
"\"$(SRCROOT)/RTABMapApp/Libraries/include/eigen3\"", "\"$(SRCROOT)/RTABMapApp/Libraries/include/eigen3\"",
"\"$(SRCROOT)/RTABMapApp/Libraries/include/pcl-1.11\"", "\"$(SRCROOT)/RTABMapApp/Libraries/include/pcl-1.15\"",
"\"$(SRCROOT)/RTABMapApp/Libraries/include/rtabmap-0.21\"", "\"$(SRCROOT)/RTABMapApp/Libraries/include/rtabmap-0.22\"",
"\"$(SRCROOT)/../android/jni/tango-gl/include\"", "\"$(SRCROOT)/../android/jni/tango-gl/include\"",
"\"$(SRCROOT)/../android/jni/third-party/include\"", "\"$(SRCROOT)/../android/jni/third-party/include\"",
"\"$(SRCROOT)/RTABMapApp/Libraries/lib/vtk.framework/Headers\"", "\"$(SRCROOT)/RTABMapApp/Libraries/lib/vtk.framework/Headers\"",
"\"$(SRCROOT)/RTABMapApp/Libraries/include/opencv4\"",
); );
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_WORKSPACE = NO; VALIDATE_WORKSPACE = NO;
+7
View File
@@ -505,6 +505,13 @@ void setSmoothingNative(const void *object, bool enabled)
else else
UERROR("object is null!"); UERROR("object is null!");
} }
void setDepthBleedingErrorNative(const void *object, float value)
{
if(object)
native(object)->setDepthBleedingError(value);
else
UERROR("object is null!");
}
void setAppendModeNative(const void *object, bool enabled) void setAppendModeNative(const void *object, bool enabled)
{ {
if(object) if(object)
+1
View File
@@ -101,6 +101,7 @@ void setGraphVisibleNative(const void *object, bool visible);
void setGridVisibleNative(const void *object, bool visible); void setGridVisibleNative(const void *object, bool visible);
void setFullResolutionNative(const void *object, bool enabled); void setFullResolutionNative(const void *object, bool enabled);
void setSmoothingNative(const void *object, bool enabled); void setSmoothingNative(const void *object, bool enabled);
void setDepthBleedingErrorNative(const void *object, float value);
void setAppendModeNative(const void *object, bool enabled); void setAppendModeNative(const void *object, bool enabled);
void setUpstreamRelocalizationAccThrNative(const void *object, float value); void setUpstreamRelocalizationAccThrNative(const void *object, float value);
void setMaxCloudDepthNative(const void *object, float value); void setMaxCloudDepthNative(const void *object, float value);
+3
View File
@@ -453,6 +453,9 @@ class RTABMap {
func setSmoothing(enabled: Bool) { func setSmoothing(enabled: Bool) {
setSmoothingNative(native_rtabmap, enabled) setSmoothingNative(native_rtabmap, enabled)
} }
func setDepthBleedingError(value: Float) {
setDepthBleedingErrorNative(native_rtabmap, value)
}
func setAppendMode(enabled: Bool) { func setAppendMode(enabled: Bool) {
setAppendModeNative(native_rtabmap, enabled) setAppendModeNative(native_rtabmap, enabled)
} }
+9 -8
View File
@@ -162,7 +162,6 @@ class ViewController: GLKViewController, ARSessionDelegate, RTABMapObserver, UIP
func resetNoTouchTimer(_ showHud: Bool = false) { func resetNoTouchTimer(_ showHud: Bool = false) {
if(showHud) if(showHud)
{ {
print("Show HUD")
mMenuOpened = false mMenuOpened = false
mHudVisible = true mHudVisible = true
setNeedsStatusBarAppearanceUpdate() setNeedsStatusBarAppearanceUpdate()
@@ -184,7 +183,6 @@ class ViewController: GLKViewController, ARSessionDelegate, RTABMapObserver, UIP
} }
else if(mState != .STATE_WELCOME && mState != .STATE_CAMERA && presentedViewController as? UIAlertController == nil && !mMenuOpened) else if(mState != .STATE_WELCOME && mState != .STATE_CAMERA && presentedViewController as? UIAlertController == nil && !mMenuOpened)
{ {
print("Hide HUD")
self.mHudVisible = false self.mHudVisible = false
self.setNeedsStatusBarAppearanceUpdate() self.setNeedsStatusBarAppearanceUpdate()
self.updateState(state: self.mState) self.updateState(state: self.mState)
@@ -840,13 +838,11 @@ class ViewController: GLKViewController, ARSessionDelegate, RTABMapObserver, UIP
self.isPaused = true self.isPaused = true
view?.enableSetNeedsDisplay = true view?.enableSetNeedsDisplay = true
self.view.setNeedsDisplay() self.view.setNeedsDisplay()
print("enableSetNeedsDisplay")
} }
else else
{ {
view?.enableSetNeedsDisplay = false view?.enableSetNeedsDisplay = false
self.isPaused = false self.isPaused = false
print("disableSetNeedsDisplay")
} }
if !self.isPaused { if !self.isPaused {
@@ -934,7 +930,6 @@ class ViewController: GLKViewController, ARSessionDelegate, RTABMapObserver, UIP
]) ])
// Measuring menu // Measuring menu
print("measuringMode = \(measuringMode)")
let measuringMenu = UIMenu(title: "Measuring...", image: UIImage(systemName: "ruler"), children: [ let measuringMenu = UIMenu(title: "Measuring...", image: UIImage(systemName: "ruler"), children: [
UIAction(title: "Plane to Plane Mode", image: measuringMode == 0 ? UIImage(systemName: "checkmark.circle") : UIImage(systemName: "circle"), handler: { _ in UIAction(title: "Plane to Plane Mode", image: measuringMode == 0 ? UIImage(systemName: "checkmark.circle") : UIImage(systemName: "circle"), handler: { _ in
self.measuringMode = 0 self.measuringMode = 0
@@ -1516,6 +1511,7 @@ class ViewController: GLKViewController, ARSessionDelegate, RTABMapObserver, UIP
rtabmap!.setNodesFiltering(enabled: defaults.bool(forKey: "NodesFiltering")); rtabmap!.setNodesFiltering(enabled: defaults.bool(forKey: "NodesFiltering"));
rtabmap!.setFullResolution(enabled: defaults.bool(forKey: "HDMode")); rtabmap!.setFullResolution(enabled: defaults.bool(forKey: "HDMode"));
rtabmap!.setSmoothing(enabled: defaults.bool(forKey: "Smoothing")); rtabmap!.setSmoothing(enabled: defaults.bool(forKey: "Smoothing"));
rtabmap!.setDepthBleedingError(value: defaults.float(forKey: "DepthBleedingError"));
rtabmap!.setAppendMode(enabled: defaults.bool(forKey: "AppendMode")); rtabmap!.setAppendMode(enabled: defaults.bool(forKey: "AppendMode"));
rtabmap!.setUpstreamRelocalizationAccThr(value: defaults.float(forKey: "UpstreamRelocalizationFilteringAccThr")); rtabmap!.setUpstreamRelocalizationAccThr(value: defaults.float(forKey: "UpstreamRelocalizationFilteringAccThr"));
rtabmap!.setExportPointCloudFormat(format: defaults.string(forKey: "ExportPointCloudFormat")!); rtabmap!.setExportPointCloudFormat(format: defaults.string(forKey: "ExportPointCloudFormat")!);
@@ -1918,7 +1914,9 @@ class ViewController: GLKViewController, ARSessionDelegate, RTABMapObserver, UIP
}) })
})) }))
let previousState = mState
updateState(state: .STATE_PROCESSING); updateState(state: .STATE_PROCESSING);
present(alertView, animated: true, completion: { present(alertView, animated: true, completion: {
@@ -1989,8 +1987,11 @@ class ViewController: GLKViewController, ARSessionDelegate, RTABMapObserver, UIP
self.updateState(state: .STATE_VISUALIZING) self.updateState(state: .STATE_VISUALIZING)
self.rtabmap!.postExportation(visualize: true) self.rtabmap!.postExportation(visualize: true)
self.setGLCamera(type: 2) if previousState != .STATE_VISUALIZING
{
self.setGLCamera(type: 2)
}
if self.openedDatabasePath == nil if self.openedDatabasePath == nil
{ {
+89 -67
View File
@@ -2,7 +2,7 @@
set -euxo pipefail set -euxo pipefail
# Tested on Apple Silicon Mac, with cmake 3.19.2. # Tested on Apple Silicon Mac, with cmake 4.0.2, XCode 16.3.
mkdir -p Libraries mkdir -p Libraries
cd Libraries cd Libraries
@@ -28,41 +28,65 @@ sysroot=iphoneos
# Boost # Boost
if [ ! -e $prefix/include/boost ] if [ ! -e $prefix/include/boost ]
then then
if [ ! -e boost_1_59_0 ] if [ ! -e boost-1.88.0 ]
then then
echo "wget boost..." echo "wget boost..."
curl -L https://downloads.sourceforge.net/project/boost/boost/1.59.0/boost_1_59_0.tar.gz -o boost_1_59_0.tar.gz curl -L https://github.com/boostorg/boost/releases/download/boost-1.88.0/boost-1.88.0-cmake.tar.gz -o boost-1.88.0-cmake.tar.gz
tar -xzf boost_1_59_0.tar.gz tar -xzf boost-1.88.0-cmake.tar.gz
fi fi
cd boost_1_59_0 cd boost-1.88.0
curl -L https://gist.github.com/matlabbe/0bce8feeb73a499a76afbbcc5c687221/raw/489ff2869eccd6f8d03ffb9090ef839108762741/BoostConfig.cmake.in -o BoostConfig.cmake.in
curl -L https://gist.github.com/matlabbe/0bce8feeb73a499a76afbbcc5c687221/raw/b07fe7d4e5dfe5f1d110c733e5cf660d79a26378/CMakeLists.txt -o CMakeLists.txt
mkdir -p build mkdir -p build
cd build cd build
cmake -G Xcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_SYSROOT=$sysroot -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 -DCMAKE_INSTALL_PREFIX=$prefix .. cmake -G Xcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_SYSROOT=$sysroot -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 -DCMAKE_INSTALL_PREFIX=$prefix -DBOOST_INCOMPATIBLE_LIBRARIES="process;context;coroutine;fiber;fiber_numa;log_setup;log;cobalt" -DBOOST_IOSTREAMS_ENABLE_ZLIB=OFF -DBOOST_IOSTREAMS_ENABLE_BZIP2=OFF ..
cmake --build . --config Release cmake --build . --config Release
cmake --build . --config Release --target install cmake --build . --config Release --target install
cd $pwd cd $pwd
#rm -r boost_1_59_0.tar.gz boost_1_59_0 #rm -r boost-1.88.0-cmake.tar.gz boost-1.88.0
fi fi
# eigen # eigen
if [ ! -e $prefix/include/eigen3 ] if [ ! -e $prefix/include/eigen3 ]
then then
if [ ! -e eigen-3.3.9 ] if [ ! -e eigen-3.4.0 ]
then then
echo "wget eigen..." echo "wget eigen..."
curl -L https://gitlab.com/libeigen/eigen/-/archive/3.3.9/eigen-3.3.9.tar.gz -o 3.3.9.tar.gz curl -L https://gitlab.com/libeigen/eigen/-/archive/3.4.0/eigen-3.4.0.tar.gz -o 3.4.0.tar.gz
tar -xzf 3.3.9.tar.gz tar -xzf 3.4.0.tar.gz
fi fi
cd eigen-3.3.9 cd eigen-3.4.0
mkdir -p build mkdir -p build
cd build cd build
cmake -G Xcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_SYSROOT=$sysroot -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 -DCMAKE_INSTALL_PREFIX=$prefix .. cmake -G Xcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_SYSROOT=$sysroot -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 -DCMAKE_INSTALL_PREFIX=$prefix ..
cmake --build . --config Release cmake --build . --config Release
cmake --build . --config Release --target install cmake --build . --config Release --target install
cd $pwd cd $pwd
#rm -r 3.3.9.tar.gz eigen-3.3.9 #rm -r 3.4.0.tar.gz eigen-3.4.0
fi
# lz4 (required by flann)
if [ ! -e $prefix/include/lz4.h ]
then
if [ ! -e lz4 ]
then
echo "wget lz4..."
git clone https://github.com/lz4/lz4.git -b v1.10.0
fi
cd lz4
if [ ! -e LZ4Config.cmake.in ]
then
curl -L https://gist.githubusercontent.com/matlabbe/abd0242305c29495bbba26065269daf2/raw/ad0b1865c02e61449f58358fdc4ddbed3cb5fb87/LZ4Config.cmake.in -o LZ4Config.cmake.in
fi
if [ ! -e CMakeLists.txt ]
then
curl -L https://gist.githubusercontent.com/matlabbe/abd0242305c29495bbba26065269daf2/raw/ad0b1865c02e61449f58358fdc4ddbed3cb5fb87/CMakeLists.txt -o CMakeLists.txt
fi
mkdir -p build
cd build
cmake -G Xcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_SYSROOT=$sysroot -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 -DCMAKE_INSTALL_PREFIX=$prefix ..
cmake --build . --config Release -- CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED="NO" CODE_SIGN_ENTITLEMENTS="" CODE_SIGNING_ALLOWED="NO"
cmake --build . --config Release --target install -- CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED="NO" CODE_SIGN_ENTITLEMENTS="" CODE_SIGNING_ALLOWED="NO"
cd $pwd
#rm -r lz4
fi fi
# FLANN # FLANN
@@ -71,19 +95,17 @@ then
if [ ! -e flann ] if [ ! -e flann ]
then then
echo "wget flann..." echo "wget flann..."
git clone https://github.com/flann-lib/flann.git -b 1.8.4 git clone https://github.com/flann-lib/flann.git -b 1.9.2
fi fi
cd flann cd flann
if [ ! -e flann_ios.patch ] if [ ! -e flann_ios_lz4.patch ]
then then
curl -L https://gist.githubusercontent.com/matlabbe/c858ba36fb85d5e44d8667dfb3543e12/raw/8fc40aa9bc3267604869444020476a49f14ab424/flann_ios.patch -o flann_ios.patch curl -L https://gist.githubusercontent.com/matlabbe/c858ba36fb85d5e44d8667dfb3543e12/raw/2586a356dec2b11440ec3c1bb113e709e1266d97/flann_ios_lz4.patch -o flann_ios_lz4.patch
git apply flann_ios.patch git apply flann_ios_lz4.patch
fi fi
mkdir -p build mkdir -p build
cd build cd build
# comment "add_subdirectory( test )" in top CMakeLists.txt cmake -G Xcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_SYSROOT=$sysroot -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 -DCMAKE_INSTALL_PREFIX=$prefix -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_MATLAB_BINDINGS=OFF -DBUILD_C_BINDINGS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_TESTS=OFF -DBUILD_DOC=OFF -DUSE_OPENMP=OFF -DLZ4_DIR=$prefix/lib/lz4 ..
# comment "add_subdirectory( doc )" in top CMakeLists.txt
cmake -G Xcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_SYSROOT=$sysroot -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 -DCMAKE_INSTALL_PREFIX=$prefix -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_MATLAB_BINDINGS=OFF -DBUILD_C_BINDINGS=OFF ..
cmake --build . --config Release -- CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED="NO" CODE_SIGN_ENTITLEMENTS="" CODE_SIGNING_ALLOWED="NO" cmake --build . --config Release -- CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED="NO" CODE_SIGN_ENTITLEMENTS="" CODE_SIGNING_ALLOWED="NO"
cmake --build . --config Release --target install -- CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED="NO" CODE_SIGN_ENTITLEMENTS="" CODE_SIGNING_ALLOWED="NO" cmake --build . --config Release --target install -- CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED="NO" CODE_SIGN_ENTITLEMENTS="" CODE_SIGNING_ALLOWED="NO"
cd $pwd cd $pwd
@@ -95,17 +117,14 @@ if [ ! -e $prefix/include/gtsam ]
then then
if [ ! -e gtsam ] if [ ! -e gtsam ]
then then
git clone https://bitbucket.org/gtborg/gtsam.git git clone https://github.com/borglab/gtsam.git -b 4.2
cd gtsam
git checkout fbb9d3bdda8b88df51896bc401bfd170573e66f5
else
cd gtsam
fi fi
cd gtsam
# patch # patch
if [ ! -e gtsam_GKlib_ios_fix.patch ] if [ ! -e gtsam_4_2_ios.patch ]
then then
curl -L https://gist.github.com/matlabbe/76d658dddb841b3355ae3a6e32850cd8/raw/7033cba1c89097b0c830651d7277c04dc92cbdd9/gtsam_GKlib_ios_fix.patch -o gtsam_GKlib_ios_fix.patch curl -L https://gist.githubusercontent.com/matlabbe/76d658dddb841b3355ae3a6e32850cd8/raw/e7355348c2d536ec50f41effa775ed251ae4e045/gtsam_4_2_ios.patch -o gtsam_4_2_ios.patch
git apply gtsam_GKlib_ios_fix.patch git apply gtsam_4_2_ios.patch
fi fi
mkdir -p build mkdir -p build
cd build cd build
@@ -116,22 +135,36 @@ cd $pwd
#rm -rf gtsam #rm -rf gtsam
fi fi
# suitesparse (dependency of g2o)
if [ ! -e $prefix/include/suitesparse/SuiteSparse_config.h ]
then
if [ ! -e SuiteSparse ]
then
git clone https://github.com/DrTimothyAldenDavis/SuiteSparse.git -b v7.6.1
fi
cd SuiteSparse
mkdir -p build
cd build
cmake -G Xcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_SYSROOT=$sysroot -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 -DCMAKE_INSTALL_PREFIX=$prefix -DCMAKE_FIND_ROOT_PATH=$prefix -DSUITESPARSE_USE_OPENMP=OFF -DSUITESPARSE_ENABLE_PROJECTS="cholmod;cxsparse;spqr" ..
cmake --build . --config Release -- CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED="NO" CODE_SIGN_ENTITLEMENTS="" CODE_SIGNING_ALLOWED="NO"
cmake --build . --config Release --target install -- CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED="NO" CODE_SIGN_ENTITLEMENTS="" CODE_SIGNING_ALLOWED="NO"
cd $pwd
fi
# g2o # g2o
if [ ! -e $prefix/include/g2o ] if [ ! -e $prefix/include/g2o ]
then then
if [ ! -e g2o ] if [ ! -e g2o ]
then then
git clone https://github.com/RainerKuemmerle/g2o.git git clone https://github.com/RainerKuemmerle/g2o.git -b 20241228_git
cd g2o
git checkout a3f7706bdbb849b2808dc3e1b7aee189f63b498e
else
cd g2o
fi fi
cd g2o
# patch # patch
if [ ! -e g2o_ios_fix.patch ] if [ ! -e g2o_20241228_ios.patch ]
then then
curl -L https://gist.github.com/matlabbe/b9ccfeae8f0744b275cab23510872680/raw/a58e06accba3976420d4b61341685c123193810e/g2o_ios_fix.patch -o g2o_ios_fix.patch ls
git apply g2o_ios_fix.patch curl -L https://gist.githubusercontent.com/matlabbe/b9ccfeae8f0744b275cab23510872680/raw/6fe2ffe5ba8fba59171adbd2f38f9c3999c61f75/g2o_20241228_ios.patch -o g2o_20241228_ios.patch
git apply g2o_20241228_ios.patch
fi fi
mkdir -p build mkdir -p build
cd build cd build
@@ -149,11 +182,10 @@ if [ ! -e VTK ]
then then
git clone https://github.com/Kitware/VTK.git git clone https://github.com/Kitware/VTK.git
cd VTK cd VTK
git checkout tags/v8.2.0 git checkout tags/v9.5.0.rc1
else else
cd VTK cd VTK
fi fi
git cherry-pick bf3ae8072df2393c7270509bae41be0776826346
mkdir -p build mkdir -p build
cd build cd build
cmake -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_FRAMEWORK_INSTALL_PREFIX=$prefix/lib -DIOS_DEVICE_ARCHITECTURES="arm64" -DIOS_SIMULATOR_ARCHITECTURES="" -DBUILD_EXAMPLES=OFF -DBUILD_TESTING=OFF -DVTK_IOS_BUILD=ON -DModule_vtkFiltersModeling=ON .. cmake -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_FRAMEWORK_INSTALL_PREFIX=$prefix/lib -DIOS_DEVICE_ARCHITECTURES="arm64" -DIOS_SIMULATOR_ARCHITECTURES="" -DBUILD_EXAMPLES=OFF -DBUILD_TESTING=OFF -DVTK_IOS_BUILD=ON -DModule_vtkFiltersModeling=ON ..
@@ -163,26 +195,28 @@ cd $pwd
#rm -rf VTK #rm -rf VTK
fi fi
# PCL # PCL
if [ ! -e $prefix/include/pcl-1.11 ] if [ ! -e $prefix/include/pcl-1.15 ]
then then
if [ ! -e pcl ] if [ ! -e pcl ]
then then
git clone https://github.com/PointCloudLibrary/pcl.git git clone https://github.com/PointCloudLibrary/pcl.git
cd pcl cd pcl
git checkout tags/pcl-1.11.1 git checkout tags/pcl-1.15.0
else else
cd pcl cd pcl
fi fi
# patch # patch
if [ ! -e pcl_1_11_1_vtk_ios_support.patch ] if [ ! -e pcl_1_15_0_ios.patch ]
then then
curl -L https://gist.github.com/matlabbe/f3ba9366eb91e1b855dadd2ddce5746d/raw/6869cf26211ab15492599e557b0e729b23b2c119/pcl_1_11_1_vtk_ios_support.patch -o pcl_1_11_1_vtk_ios_support.patch curl -L https://gist.githubusercontent.com/matlabbe/f3ba9366eb91e1b855dadd2ddce5746d/raw/7231688d7fb9e86df72ca7c5f355d6b9727205d5/pcl_1_15_0_ios.patch -o pcl_1_15_0_ios.patch
git apply pcl_1_11_1_vtk_ios_support.patch git apply pcl_1_15_0_ios.patch
fi fi
mkdir -p build mkdir -p build
cd build cd build
cmake -G Xcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_SYSROOT=$sysroot -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 -DCMAKE_INSTALL_PREFIX=$prefix -DBUILD_apps=OFF -DBUILD_examples=OFF -DBUILD_tools=OFF -DBUILD_visualization=OFF -DBUILD_tracking=OFF -DBUILD_people=OFF -DBUILD_global_tests=OFF -DWITH_QT=OFF -DWITH_OPENGL=OFF -DWITH_VTK=ON -DPCL_SHARED_LIBS=OFF -DPCL_ENABLE_SSE=OFF -DCMAKE_FIND_ROOT_PATH=$prefix .. cmake -G Xcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_SYSROOT=$sysroot -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 -DCMAKE_INSTALL_PREFIX=$prefix -DBUILD_apps=OFF -DBUILD_examples=OFF -DBUILD_tools=OFF -DBUILD_visualization=OFF -DBUILD_tracking=OFF -DBUILD_people=OFF -DBUILD_recognition=OFF -DBUILD_global_tests=OFF -DWITH_QT=OFF -DWITH_OPENGL=OFF -DWITH_OPENMP=OFF -DWITH_VTK=ON -DPCL_FLANN_REQUIRED_TYPE=STATIC -DPCL_SHARED_LIBS=OFF -DPCL_ENABLE_SSE=OFF -DCMAKE_FIND_ROOT_PATH=$prefix ..
cmake --build . --config Release cmake --build . --config Release
cmake --build . --config Release --target install cmake --build . --config Release --target install
cd $pwd cd $pwd
@@ -190,32 +224,21 @@ cd $pwd
fi fi
# OpenCV # OpenCV
if [ ! -e $prefix/include/opencv2 ] if [ ! -e $prefix/include/opencv4 ]
then then
if [ ! -e opencv_contrib ] if [ ! -e opencv_contrib ]
then then
git clone https://github.com/opencv/opencv_contrib.git git clone https://github.com/opencv/opencv_contrib.git -b 4.11.0
cd opencv_contrib
git checkout tags/3.4.2
fi fi
cd $pwd cd $pwd
if [ ! -e opencv ] if [ ! -e opencv ]
then then
git clone https://github.com/opencv/opencv.git git clone https://github.com/opencv/opencv.git -b 4.11.0
cd opencv
git checkout tags/3.4.2
else
cd opencv
fi
if [ ! -e opencv_ios.patch ]
then
curl -L https://gist.githubusercontent.com/matlabbe/fdc3ab4854f3a68fbde7277f543b4e5b/raw/f340839c09165056d3845645df24b76507542fd2/opencv_ios.patch -o opencv_ios.patch
git apply opencv_ios.patch
fi fi
cd opencv
mkdir -p build mkdir -p build
cd build cd build
# add "add_definitions(-DPNG_ARM_NEON_OPT=0)" in 3rdparty/libpng/CMakeLists.txt cmake -G Xcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_SYSROOT=$sysroot -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 -DCMAKE_INSTALL_PREFIX=$prefix -DOPENCV_EXTRA_MODULES_PATH=$prefix/opencv_contrib/modules -DBUILD_TESTS=OFF -DBUILD_PERF_TESTS=OFF -DWITH_CUDA=OFF -DWITH_WEBP=OFF -DWITH_OPENEXR=OFF -DBUILD_opencv_apps=OFF -DBUILD_opencv_xobjdetect=OFF -DBUILD_opencv_stereo=OFF -DOPENCV_ENABLE_NONFREE=ON ..
cmake -G Xcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_SYSROOT=$sysroot -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 -DCMAKE_INSTALL_PREFIX=$prefix -DOPENCV_EXTRA_MODULES_PATH=$prefix/opencv_contrib/modules -DBUILD_TESTS=OFF -DBUILD_PERF_TESTS=OFF -DWITH_CUDA=OFF -DBUILD_opencv_apps=OFF -DBUILD_opencv_xobjdetect=OFF -DBUILD_opencv_stereo=OFF ..
cmake --build . --config Release cmake --build . --config Release
cmake --build . --config Release --target install cmake --build . --config Release --target install
cd $pwd cd $pwd
@@ -228,12 +251,10 @@ if [ ! -e $prefix/include/laszip ]
then then
if [ ! -e LASzip ] if [ ! -e LASzip ]
then then
git clone https://github.com/LASzip/LASzip.git git clone https://github.com/LASzip/LASzip.git -b 2.0.1
cd LASzip
git checkout 2.0.1
else
cd LASzip
fi fi
cd LASzip
sed -i '' 's/cmake_minimum_required(VERSION 2.6.0)/cmake_minimum_required(VERSION 3.5)/g' CMakeLists.txt
sed -i '' 's/add_subdirectory(tools)/#add_subdirectory(tools)/g' CMakeLists.txt sed -i '' 's/add_subdirectory(tools)/#add_subdirectory(tools)/g' CMakeLists.txt
mkdir -p build mkdir -p build
cd build cd build
@@ -251,6 +272,7 @@ then
git clone https://github.com/libLAS/libLAS.git git clone https://github.com/libLAS/libLAS.git
fi fi
cd libLAS cd libLAS
sed -i '' 's/cmake_minimum_required(VERSION 2.8.11)/cmake_minimum_required(VERSION 3.5)/g' CMakeLists.txt
sed -i '' 's/SHARED/STATIC/g' src/CMakeLists.txt sed -i '' 's/SHARED/STATIC/g' src/CMakeLists.txt
mkdir -p build mkdir -p build
cd build cd build
@@ -266,6 +288,6 @@ cmake -DANDROID_PREBUILD=ON ../../../../..
cmake --build . --config Release cmake --build . --config Release
mkdir -p ios mkdir -p ios
cd ios cd ios
cmake -G Xcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_SYSROOT=$sysroot -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 -DCMAKE_INSTALL_PREFIX=$prefix -DCMAKE_FIND_ROOT_PATH=$prefix -DWITH_QT=OFF -DBUILD_APP=OFF -DBUILD_TOOLS=OFF -DWITH_TORO=OFF -DWITH_VERTIGO=OFF -DWITH_MADGWICK=OFF -DWITH_ORB_OCTREE=OFF -DBUILD_EXAMPLES=OFF -DWITH_LIBLAS=ON ../../../../../.. cmake -G Xcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_SYSROOT=$sysroot -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 -DCMAKE_INSTALL_PREFIX=$prefix -DCMAKE_FIND_ROOT_PATH=$prefix -DWITH_QT=OFF -DBUILD_APP=OFF -DBUILD_TOOLS=OFF -DWITH_TORO=OFF -DWITH_VERTIGO=OFF -DWITH_MADGWICK=OFF -DWITH_ORB_OCTREE=ON -DBUILD_EXAMPLES=OFF -DWITH_LIBLAS=ON ../../../../../..
cmake --build . --config Release cmake --build . --config Release
cmake --build . --config Release --target install cmake --build . --config Release --target install
+52 -6
View File
@@ -58,7 +58,7 @@
<key>Type</key> <key>Type</key>
<string>PSGroupSpecifier</string> <string>PSGroupSpecifier</string>
<key>FooterText</key> <key>FooterText</key>
<string>Choosing between high and low depth confidence depends on the application. If precise geometry is critical, prioritize high depth confidence even if it means fewer points. If you need a dense point cloud for analysis, even in areas with weak LiDAR signal, a lower depth confidence might be suitable at the cost of highly interpolated points (that could give a wavy look of some surfaces). Important: the points with too low confidence are not saved in the db file, so we cannot recover or filter these points in post-processing.</string> <string>Choosing between high and low depth confidence depends on the application. If precise geometry is critical, prioritize high depth confidence even if it means fewer points. If you need a dense point cloud for analysis, even in areas with weak LiDAR signal, a lower depth confidence might be suitable at the cost of highly interpolated points (that could give a wavy look of some surfaces). Note: it is possible to change confidence level in post-processing.</string>
</dict> </dict>
<dict> <dict>
<key>DefaultValue</key> <key>DefaultValue</key>
@@ -86,7 +86,7 @@
<key>Type</key> <key>Type</key>
<string>PSGroupSpecifier</string> <string>PSGroupSpecifier</string>
<key>FooterText</key> <key>FooterText</key>
<string>Smooth the point clouds.</string> <string>Smooth the point clouds. Note that this can be changed in post-processing.</string>
</dict> </dict>
<dict> <dict>
<key>Type</key> <key>Type</key>
@@ -98,6 +98,44 @@
<key>DefaultValue</key> <key>DefaultValue</key>
<false/> <false/>
</dict> </dict>
<dict>
<key>Type</key>
<string>PSGroupSpecifier</string>
<key>FooterText</key>
<string>Filter interpolated depth pixels between foreground and background objects. Note that values can be changed in post-processing.</string>
</dict>
<dict>
<key>Type</key>
<string>PSMultiValueSpecifier</string>
<key>Title</key>
<string>Depth Bleeding Filter Error</string>
<key>Key</key>
<string>DepthBleedingError</string>
<key>DefaultValue</key>
<string>0</string>
<key>Titles</key>
<array>
<string>Disabled</string>
<string>2.5 cm</string>
<string>5 cm</string>
<string>10 cm</string>
<string>15 cm</string>
<string>20 cm</string>
<string>25 cm</string>
<string>30 cm</string>
</array>
<key>Values</key>
<array>
<string>0</string>
<string>0.025</string>
<string>0.05</string>
<string>0.10</string>
<string>0.15</string>
<string>0.20</string>
<string>0.25</string>
<string>0.30</string>
</array>
</dict>
<dict> <dict>
<key>Type</key> <key>Type</key>
<string>PSGroupSpecifier</string> <string>PSGroupSpecifier</string>
@@ -590,7 +628,7 @@
<key>Type</key> <key>Type</key>
<string>PSGroupSpecifier</string> <string>PSGroupSpecifier</string>
<key>FooterText</key> <key>FooterText</key>
<string>BRIEF features are fast to compute but are not rotation invariant like FREAK. Warning: Changing feature type will automatically reset the map!</string> <string>BRIEF, FREAK and ORB are binary features, which are fast to compute and use less memory. SURF and SIFT are high dimensional float descriptors (rotation/scale/shear-invariant), so they use more memory and CPU but they are significantly better to detect loop closures in large environments. Warning: Changing feature type will automatically reset the map!</string>
</dict> </dict>
<dict> <dict>
<key>Type</key> <key>Type</key>
@@ -603,13 +641,21 @@
<string>6</string> <string>6</string>
<key>Titles</key> <key>Titles</key>
<array> <array>
<string>BRIEF</string> <string>SURF</string>
<string>FREAK</string> <string>SIFT</string>
<string>GFTT-FREAK</string>
<string>GFTT-BRIEF</string>
<string>GFTT-ORB</string>
<string>ORB-OCTREE</string>
</array> </array>
<key>Values</key> <key>Values</key>
<array> <array>
<string>6</string> <string>0</string>
<string>1</string>
<string>5</string> <string>5</string>
<string>6</string>
<string>8</string>
<string>10</string>
</array> </array>
</dict> </dict>
<dict> <dict>
+1 -1
View File
@@ -494,7 +494,7 @@
</dict> </dict>
<dict> <dict>
<key>DefaultValue</key> <key>DefaultValue</key>
<string>0.21.11</string> <string>0.22.0</string>
<key>Key</key> <key>Key</key>
<string>Version</string> <string>Version</string>
<key>Title</key> <key>Title</key>
+6 -3
View File
@@ -149,14 +149,16 @@ public:
const std::map<int, Signature> & signatures, const std::map<int, Signature> & signatures,
std::map<int, cv::Point3f> & points3DMap, std::map<int, cv::Point3f> & points3DMap,
std::map<int, std::map<int, FeatureBA> > & wordReferences, // <ID words, IDs frames + keypoint/depth/descriptor> std::map<int, std::map<int, FeatureBA> > & wordReferences, // <ID words, IDs frames + keypoint/depth/descriptor>
bool rematchFeatures = false); bool rematchFeatures = false,
const ParametersMap & registrationParameters = ParametersMap());
std::map<int, Transform> optimizeBA( std::map<int, Transform> optimizeBA(
int rootId, int rootId,
const std::map<int, Transform> & poses, const std::map<int, Transform> & poses,
const std::multimap<int, Link> & links, const std::multimap<int, Link> & links,
const std::map<int, Signature> & signatures, const std::map<int, Signature> & signatures,
bool rematchFeatures = false); bool rematchFeatures = false,
const ParametersMap & registrationParameters = ParametersMap());
Transform optimizeBA( Transform optimizeBA(
const Link & link, const Link & link,
@@ -172,7 +174,8 @@ public:
std::map<int, cv::Point3f> & points3DMap, std::map<int, cv::Point3f> & points3DMap,
std::map<int, std::map<int, FeatureBA > > & wordReferences, // <ID words, IDs frames + keypoint/depth/descriptor> std::map<int, std::map<int, FeatureBA > > & wordReferences, // <ID words, IDs frames + keypoint/depth/descriptor>
bool rematchFeatures = false, bool rematchFeatures = false,
bool useLinkTransformAsGuess = false); bool useLinkTransformAsGuess = false,
ParametersMap registrationParameters = ParametersMap());
protected: protected:
Optimizer( Optimizer(
@@ -390,6 +390,7 @@ class RTABMAP_CORE_EXPORT Parameters
RTABMAP_PARAM(RGBD, MaxOdomCacheSize, int, 10, uFormat("Maximum odometry cache size. Used only in localization mode (when %s=false). This is used to get smoother localizations and to verify localization transforms (when %s!=0) to make sure we don't teleport to a location very similar to one we previously localized on. Set 0 to disable caching.", kMemIncrementalMemory().c_str(), kRGBDOptimizeMaxError().c_str())); RTABMAP_PARAM(RGBD, MaxOdomCacheSize, int, 10, uFormat("Maximum odometry cache size. Used only in localization mode (when %s=false). This is used to get smoother localizations and to verify localization transforms (when %s!=0) to make sure we don't teleport to a location very similar to one we previously localized on. Set 0 to disable caching.", kMemIncrementalMemory().c_str(), kRGBDOptimizeMaxError().c_str()));
RTABMAP_PARAM(RGBD, LocalizationSmoothing, bool, true, uFormat("Adjust localization constraints based on optimized odometry cache poses (when %s>0).", kRGBDMaxOdomCacheSize().c_str())); RTABMAP_PARAM(RGBD, LocalizationSmoothing, bool, true, uFormat("Adjust localization constraints based on optimized odometry cache poses (when %s>0).", kRGBDMaxOdomCacheSize().c_str()));
RTABMAP_PARAM(RGBD, LocalizationPriorError, double, 0.001, uFormat("The corresponding variance (error x error) set to priors of the map's poses during localization (when %s>0).", kRGBDMaxOdomCacheSize().c_str())); RTABMAP_PARAM(RGBD, LocalizationPriorError, double, 0.001, uFormat("The corresponding variance (error x error) set to priors of the map's poses during localization (when %s>0).", kRGBDMaxOdomCacheSize().c_str()));
RTABMAP_PARAM(RGBD, LocalizationSecondTryWithoutProximityLinks, bool, true, uFormat("When localization is rejected by graph optimization validation, try a second time without proximity links if landmark or loop closure links are also present in odometry cache (see %s). If it succeeds, the proximity links are removed. This assumes that global loop closure and landmark links are more accurate than proximity links.", kRGBDMaxOdomCacheSize().c_str()));
// Local/Proximity loop closure detection // Local/Proximity loop closure detection
RTABMAP_PARAM(RGBD, ProximityByTime, bool, false, "Detection over all locations in STM."); RTABMAP_PARAM(RGBD, ProximityByTime, bool, false, "Detection over all locations in STM.");
+1
View File
@@ -333,6 +333,7 @@ private:
int _maxOdomCacheSize; int _maxOdomCacheSize;
bool _localizationSmoothing; bool _localizationSmoothing;
double _localizationPriorInf; double _localizationPriorInf;
bool _localizationSecondTryWithoutProximityLinks;
bool _createGlobalScanMap; bool _createGlobalScanMap;
float _markerPriorsLinearVariance; float _markerPriorsLinearVariance;
float _markerPriorsAngularVariance; float _markerPriorsAngularVariance;
+54 -2
View File
@@ -78,6 +78,16 @@ public:
double stamp = 0.0, double stamp = 0.0,
const cv::Mat & userData = cv::Mat()); const cv::Mat & userData = cv::Mat());
// RGB-D constructor + depth confidence
SensorData(
const cv::Mat & rgb,
const cv::Mat & depth,
const cv::Mat & depth_confidence,
const CameraModel & cameraModel,
int id = 0,
double stamp = 0.0,
const cv::Mat & userData = cv::Mat());
// RGB-D constructor + laser scan // RGB-D constructor + laser scan
SensorData( SensorData(
const LaserScan & laserScan, const LaserScan & laserScan,
@@ -87,6 +97,17 @@ public:
int id = 0, int id = 0,
double stamp = 0.0, double stamp = 0.0,
const cv::Mat & userData = cv::Mat()); const cv::Mat & userData = cv::Mat());
// RGB-D constructor + confidence + laser scan
SensorData(
const LaserScan & laserScan,
const cv::Mat & rgb,
const cv::Mat & depth,
const cv::Mat & depthConfidence,
const CameraModel & cameraModel,
int id = 0,
double stamp = 0.0,
const cv::Mat & userData = cv::Mat());
// Multi-cameras RGB-D constructor // Multi-cameras RGB-D constructor
SensorData( SensorData(
@@ -96,6 +117,16 @@ public:
int id = 0, int id = 0,
double stamp = 0.0, double stamp = 0.0,
const cv::Mat & userData = cv::Mat()); const cv::Mat & userData = cv::Mat());
// Multi-cameras RGB-D constructor + depth confidence
SensorData(
const cv::Mat & rgb,
const cv::Mat & depth,
const cv::Mat & depthConfidence,
const std::vector<CameraModel> & cameraModels,
int id = 0,
double stamp = 0.0,
const cv::Mat & userData = cv::Mat());
// Multi-cameras RGB-D constructor + laser scan // Multi-cameras RGB-D constructor + laser scan
SensorData( SensorData(
@@ -107,6 +138,17 @@ public:
double stamp = 0.0, double stamp = 0.0,
const cv::Mat & userData = cv::Mat()); const cv::Mat & userData = cv::Mat());
// Multi-cameras RGB-D constructor + depth confidence + laser scan
SensorData(
const LaserScan & laserScan,
const cv::Mat & rgb,
const cv::Mat & depth,
const cv::Mat & depthConfidence,
const std::vector<CameraModel> & cameraModels,
int id = 0,
double stamp = 0.0,
const cv::Mat & userData = cv::Mat());
// Stereo constructor // Stereo constructor
SensorData( SensorData(
const cv::Mat & left, const cv::Mat & left,
@@ -160,6 +202,8 @@ public:
_imageCompressed.empty() && _imageCompressed.empty() &&
_depthOrRightRaw.empty() && _depthOrRightRaw.empty() &&
_depthOrRightCompressed.empty() && _depthOrRightCompressed.empty() &&
_depthConfidenceRaw.empty() &&
_depthConfidenceCompressed.empty() &&
_laserScanRaw.isEmpty() && _laserScanRaw.isEmpty() &&
_laserScanCompressed.isEmpty() && _laserScanCompressed.isEmpty() &&
_cameraModels.empty() && _cameraModels.empty() &&
@@ -178,10 +222,12 @@ public:
const cv::Mat & imageCompressed() const {return _imageCompressed;} const cv::Mat & imageCompressed() const {return _imageCompressed;}
const cv::Mat & depthOrRightCompressed() const {return _depthOrRightCompressed;} const cv::Mat & depthOrRightCompressed() const {return _depthOrRightCompressed;}
const cv::Mat & depthConfidenceCompressed() const {return _depthConfidenceCompressed;}
const LaserScan & laserScanCompressed() const {return _laserScanCompressed;} const LaserScan & laserScanCompressed() const {return _laserScanCompressed;}
const cv::Mat & imageRaw() const {return _imageRaw;} const cv::Mat & imageRaw() const {return _imageRaw;}
const cv::Mat & depthOrRightRaw() const {return _depthOrRightRaw;} const cv::Mat & depthOrRightRaw() const {return _depthOrRightRaw;}
const cv::Mat & depthConfidenceRaw() const {return _depthConfidenceRaw;}
const LaserScan & laserScanRaw() const {return _laserScanRaw;} const LaserScan & laserScanRaw() const {return _laserScanRaw;}
/** /**
@@ -190,7 +236,9 @@ public:
* @param clearPreviousData, clear previous raw and compressed images before setting the new ones. * @param clearPreviousData, clear previous raw and compressed images before setting the new ones.
*/ */
void setRGBDImage(const cv::Mat & rgb, const cv::Mat & depth, const CameraModel & model, bool clearPreviousData = true); void setRGBDImage(const cv::Mat & rgb, const cv::Mat & depth, const CameraModel & model, bool clearPreviousData = true);
void setRGBDImage(const cv::Mat & rgb, const cv::Mat & depth, const cv::Mat & depth_confidence, const CameraModel & model, bool clearPreviousData = true);
void setRGBDImage(const cv::Mat & rgb, const cv::Mat & depth, const std::vector<CameraModel> & models, bool clearPreviousData = true); void setRGBDImage(const cv::Mat & rgb, const cv::Mat & depth, const std::vector<CameraModel> & models, bool clearPreviousData = true);
void setRGBDImage(const cv::Mat & rgb, const cv::Mat & depth, const cv::Mat & depth_confidence, const std::vector<CameraModel> & models, bool clearPreviousData = true);
void setStereoImage(const cv::Mat & left, const cv::Mat & right, const StereoCameraModel & stereoCameraModel, bool clearPreviousData = true); void setStereoImage(const cv::Mat & left, const cv::Mat & right, const StereoCameraModel & stereoCameraModel, bool clearPreviousData = true);
void setStereoImage(const cv::Mat & left, const cv::Mat & right, const std::vector<StereoCameraModel> & stereoCameraModels, bool clearPreviousData = true); void setStereoImage(const cv::Mat & left, const cv::Mat & right, const std::vector<StereoCameraModel> & stereoCameraModels, bool clearPreviousData = true);
@@ -227,7 +275,8 @@ public:
cv::Mat * userDataRaw = 0, cv::Mat * userDataRaw = 0,
cv::Mat * groundCellsRaw = 0, cv::Mat * groundCellsRaw = 0,
cv::Mat * obstacleCellsRaw = 0, cv::Mat * obstacleCellsRaw = 0,
cv::Mat * emptyCellsRaw = 0); cv::Mat * emptyCellsRaw = 0,
cv::Mat * depthConfidenceRaw = 0);
void uncompressDataConst( void uncompressDataConst(
cv::Mat * imageRaw, cv::Mat * imageRaw,
cv::Mat * depthOrRightRaw, cv::Mat * depthOrRightRaw,
@@ -235,7 +284,8 @@ public:
cv::Mat * userDataRaw = 0, cv::Mat * userDataRaw = 0,
cv::Mat * groundCellsRaw = 0, cv::Mat * groundCellsRaw = 0,
cv::Mat * obstacleCellsRaw = 0, cv::Mat * obstacleCellsRaw = 0,
cv::Mat * emptyCellsRaw = 0) const; cv::Mat * emptyCellsRaw = 0,
cv::Mat * depthConfidenceRaw = 0) const;
const std::vector<CameraModel> & cameraModels() const {return _cameraModels;} const std::vector<CameraModel> & cameraModels() const {return _cameraModels;}
const std::vector<StereoCameraModel> & stereoCameraModels() const {return _stereoCameraModels;} const std::vector<StereoCameraModel> & stereoCameraModels() const {return _stereoCameraModels;}
@@ -327,10 +377,12 @@ private:
cv::Mat _imageCompressed; // compressed image cv::Mat _imageCompressed; // compressed image
cv::Mat _depthOrRightCompressed; // compressed image cv::Mat _depthOrRightCompressed; // compressed image
cv::Mat _depthConfidenceCompressed; // compressed data
LaserScan _laserScanCompressed; // compressed data LaserScan _laserScanCompressed; // compressed data
cv::Mat _imageRaw; // CV_8UC1 or CV_8UC3 cv::Mat _imageRaw; // CV_8UC1 or CV_8UC3
cv::Mat _depthOrRightRaw; // depth CV_16UC1 or CV_32FC1, right image CV_8UC1 or CV_8UC3 cv::Mat _depthOrRightRaw; // depth CV_16UC1 or CV_32FC1, right image CV_8UC1 or CV_8UC3
cv::Mat _depthConfidenceRaw; // CV_8UC1
LaserScan _laserScanRaw; LaserScan _laserScanRaw;
std::vector<CameraModel> _cameraModels; std::vector<CameraModel> _cameraModels;
@@ -81,6 +81,7 @@ class RTABMAP_CORE_EXPORT Statistics
RTABMAP_STATS(Loop, Landmark_detected_node_ref,); RTABMAP_STATS(Loop, Landmark_detected_node_ref,);
RTABMAP_STATS(Loop, Visual_inliers_mean_dist,m); RTABMAP_STATS(Loop, Visual_inliers_mean_dist,m);
RTABMAP_STATS(Loop, Visual_inliers_distribution,); RTABMAP_STATS(Loop, Visual_inliers_distribution,);
RTABMAP_STATS(Loop, Proximity_links_cleared,);
//Odom correction //Odom correction
RTABMAP_STATS(Loop, Odom_correction_norm, m); RTABMAP_STATS(Loop, Odom_correction_norm, m);
RTABMAP_STATS(Loop, Odom_correction_angle, deg); RTABMAP_STATS(Loop, Odom_correction_angle, deg);
+1 -1
View File
@@ -113,7 +113,7 @@ public:
void getTranslationAndEulerAngles(float & x, float & y, float & z, float & roll, float & pitch, float & yaw) const; void getTranslationAndEulerAngles(float & x, float & y, float & z, float & roll, float & pitch, float & yaw) const;
void getEulerAngles(float & roll, float & pitch, float & yaw) const; void getEulerAngles(float & roll, float & pitch, float & yaw) const;
void getTranslation(float & x, float & y, float & z) const; void getTranslation(float & x, float & y, float & z) const;
float getAngle(float x=1.0f, float y=0.0f, float z=0.0f) const; float getAngle(const Transform & t) const;
float getNorm() const; float getNorm() const;
float getNormSquared() const; float getNormSquared() const;
float getDistance(const Transform & t) const; float getDistance(const Transform & t) const;
+12
View File
@@ -126,6 +126,14 @@ cv::Mat RTABMAP_CORE_EXPORT registerDepth(
const cv::Size & colorSize, const cv::Size & colorSize,
const cv::Mat & colorK, const cv::Mat & colorK,
const rtabmap::Transform & transform); const rtabmap::Transform & transform);
cv::Mat RTABMAP_CORE_EXPORT registerDepth(
const cv::Mat & depth,
const cv::Mat & confidence,
const cv::Mat & depthK,
const cv::Size & colorSize,
const cv::Mat & colorK,
const rtabmap::Transform & transform,
cv::Mat & registeredConfidence);
cv::Mat RTABMAP_CORE_EXPORT fillDepthHoles( cv::Mat RTABMAP_CORE_EXPORT fillDepthHoles(
const cv::Mat & depth, const cv::Mat & depth,
@@ -144,6 +152,10 @@ cv::Mat RTABMAP_CORE_EXPORT fastBilateralFiltering(
float sigmaR = 0.05f, float sigmaR = 0.05f,
bool earlyDivision = false); bool earlyDivision = false);
void RTABMAP_CORE_EXPORT depthBleedingFiltering(
cv::Mat & depth,
float maxDepthError);
cv::Mat RTABMAP_CORE_EXPORT brightnessAndContrastAuto( cv::Mat RTABMAP_CORE_EXPORT brightnessAndContrastAuto(
const cv::Mat & src, const cv::Mat & src,
const cv::Mat & mask, const cv::Mat & mask,
+29 -4
View File
@@ -97,6 +97,15 @@ pcl::PointCloud<pcl::PointXYZ>::Ptr RTABMAP_CORE_EXPORT cloudFromDepth(
float maxDepth = 0.0f, float maxDepth = 0.0f,
float minDepth = 0.0f, float minDepth = 0.0f,
std::vector<int> * validIndices = 0); std::vector<int> * validIndices = 0);
pcl::PointCloud<pcl::PointXYZ>::Ptr RTABMAP_CORE_EXPORT cloudFromDepth(
const cv::Mat & imageDepth,
const cv::Mat & imageDepthConfidence,
const CameraModel & model,
int decimation = 1,
float maxDepth = 0.0f,
float minDepth = 0.0f,
unsigned char confidenceThr = 0,
std::vector<int> * validIndices = 0);
// Use cloudFromDepthRGB with CameraModel interface. // Use cloudFromDepthRGB with CameraModel interface.
RTABMAP_DEPRECATED pcl::PointCloud<pcl::PointXYZRGB>::Ptr RTABMAP_CORE_EXPORT cloudFromDepthRGB( RTABMAP_DEPRECATED pcl::PointCloud<pcl::PointXYZRGB>::Ptr RTABMAP_CORE_EXPORT cloudFromDepthRGB(
@@ -116,6 +125,16 @@ pcl::PointCloud<pcl::PointXYZRGB>::Ptr RTABMAP_CORE_EXPORT cloudFromDepthRGB(
float maxDepth = 0.0f, float maxDepth = 0.0f,
float minDepth = 0.0f, float minDepth = 0.0f,
std::vector<int> * validIndices = 0); std::vector<int> * validIndices = 0);
pcl::PointCloud<pcl::PointXYZRGB>::Ptr RTABMAP_CORE_EXPORT cloudFromDepthRGB(
const cv::Mat & imageRgb,
const cv::Mat & imageDepth,
const cv::Mat & imageDepthConfidence,
const CameraModel & model,
int decimation = 1,
float maxDepth = 0.0f,
float minDepth = 0.0f,
unsigned char confidenceThr = 0, // 0=low, 100=high
std::vector<int> * validIndices = 0);
pcl::PointCloud<pcl::PointXYZ>::Ptr RTABMAP_CORE_EXPORT cloudFromDisparity( pcl::PointCloud<pcl::PointXYZ>::Ptr RTABMAP_CORE_EXPORT cloudFromDisparity(
const cv::Mat & imageDisparity, const cv::Mat & imageDisparity,
@@ -164,7 +183,8 @@ std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> RTABMAP_CORE_EXPORT cloudsFromS
float minDepth = 0.0f, float minDepth = 0.0f,
std::vector<pcl::IndicesPtr> * validIndices = 0, std::vector<pcl::IndicesPtr> * validIndices = 0,
const ParametersMap & stereoParameters = ParametersMap(), const ParametersMap & stereoParameters = ParametersMap(),
const std::vector<float> & roiRatios = std::vector<float>()); // ignored for stereo const std::vector<float> & roiRatios = std::vector<float>(), // ignored for stereo
unsigned char confidenceThr = 0); // ignored for stereo
/** /**
* Create a XYZ cloud from the images contained in SensorData. If there is only one camera, * Create a XYZ cloud from the images contained in SensorData. If there is only one camera,
@@ -188,7 +208,8 @@ pcl::PointCloud<pcl::PointXYZ>::Ptr RTABMAP_CORE_EXPORT cloudFromSensorData(
float minDepth = 0.0f, float minDepth = 0.0f,
std::vector<int> * validIndices = 0, std::vector<int> * validIndices = 0,
const ParametersMap & stereoParameters = ParametersMap(), const ParametersMap & stereoParameters = ParametersMap(),
const std::vector<float> & roiRatios = std::vector<float>()); // ignored for stereo const std::vector<float> & roiRatios = std::vector<float>(), // ignored for stereo
unsigned char confidenceThr = 0); // ignored for stereo
/** /**
* Create an RGB cloud from the images contained in SensorData, one for each camera * Create an RGB cloud from the images contained in SensorData, one for each camera
@@ -210,7 +231,8 @@ std::vector<pcl::PointCloud<pcl::PointXYZRGB>::Ptr> RTABMAP_CORE_EXPORT cloudsRG
float minDepth = 0.0f, float minDepth = 0.0f,
std::vector<pcl::IndicesPtr > * validIndices = 0, std::vector<pcl::IndicesPtr > * validIndices = 0,
const ParametersMap & stereoParameters = ParametersMap(), const ParametersMap & stereoParameters = ParametersMap(),
const std::vector<float> & roiRatios = std::vector<float>()); // ignored for stereo const std::vector<float> & roiRatios = std::vector<float>(), // ignored for stereo
unsigned char confidenceThr = 0); // ignored for stereo
/** /**
* Create an RGB cloud from the images contained in SensorData. If there is only one camera, * Create an RGB cloud from the images contained in SensorData. If there is only one camera,
@@ -234,7 +256,8 @@ pcl::PointCloud<pcl::PointXYZRGB>::Ptr RTABMAP_CORE_EXPORT cloudRGBFromSensorDat
float minDepth = 0.0f, float minDepth = 0.0f,
std::vector<int> * validIndices = 0, std::vector<int> * validIndices = 0,
const ParametersMap & stereoParameters = ParametersMap(), const ParametersMap & stereoParameters = ParametersMap(),
const std::vector<float> & roiRatios = std::vector<float>()); // ignored for stereo const std::vector<float> & roiRatios = std::vector<float>(), // ignored for stereo
unsigned char confidenceThr = 0); // ignored for stereo
/** /**
* Simulate a laser scan rotating counterclockwise, using middle line of the depth image. * Simulate a laser scan rotating counterclockwise, using middle line of the depth image.
@@ -390,6 +413,7 @@ std::vector<std::pair< std::pair<int, int>, pcl::PointXY> > RTABMAP_CORE_EXPORT
const std::map<int, std::vector<CameraModel> > & cameraModels, const std::map<int, std::vector<CameraModel> > & cameraModels,
float maxDistance = 0.0f, float maxDistance = 0.0f,
float maxAngle = 0.0f, float maxAngle = 0.0f,
float maxDepthError = 0.0f,
const std::vector<float> & roiRatios = std::vector<float>(), const std::vector<float> & roiRatios = std::vector<float>(),
const cv::Mat & projMask = cv::Mat(), const cv::Mat & projMask = cv::Mat(),
bool distanceToCamPolicy = false, bool distanceToCamPolicy = false,
@@ -404,6 +428,7 @@ std::vector<std::pair< std::pair<int, int>, pcl::PointXY> > RTABMAP_CORE_EXPORT
const std::map<int, std::vector<CameraModel> > & cameraModels, const std::map<int, std::vector<CameraModel> > & cameraModels,
float maxDistance = 0.0f, float maxDistance = 0.0f,
float maxAngle = 0.0f, float maxAngle = 0.0f,
float maxDepthError = 0.0f,
const std::vector<float> & roiRatios = std::vector<float>(), const std::vector<float> & roiRatios = std::vector<float>(),
const cv::Mat & projMask = cv::Mat(), const cv::Mat & projMask = cv::Mat(),
bool distanceToCamPolicy = false, bool distanceToCamPolicy = false,
+1
View File
@@ -816,6 +816,7 @@ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/resources/DatabaseSchema.sql.in ${CMA
SET(RESOURCES SET(RESOURCES
${CMAKE_CURRENT_SOURCE_DIR}/resources/DatabaseSchema.sql ${CMAKE_CURRENT_SOURCE_DIR}/resources/DatabaseSchema.sql
${CMAKE_CURRENT_SOURCE_DIR}/resources/backward_compatibility/DatabaseSchema_0_20_0.sql
${CMAKE_CURRENT_SOURCE_DIR}/resources/backward_compatibility/DatabaseSchema_0_18_3.sql ${CMAKE_CURRENT_SOURCE_DIR}/resources/backward_compatibility/DatabaseSchema_0_18_3.sql
${CMAKE_CURRENT_SOURCE_DIR}/resources/backward_compatibility/DatabaseSchema_0_18_0.sql ${CMAKE_CURRENT_SOURCE_DIR}/resources/backward_compatibility/DatabaseSchema_0_18_0.sql
${CMAKE_CURRENT_SOURCE_DIR}/resources/backward_compatibility/DatabaseSchema_0_17_0.sql ${CMAKE_CURRENT_SOURCE_DIR}/resources/backward_compatibility/DatabaseSchema_0_17_0.sql
+44 -3
View File
@@ -34,6 +34,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "rtabmap/core/util3d.h" #include "rtabmap/core/util3d.h"
#include "rtabmap/core/Compression.h" #include "rtabmap/core/Compression.h"
#include "DatabaseSchema_sql.h" #include "DatabaseSchema_sql.h"
#include "DatabaseSchema_0_20_0_sql.h"
#include "DatabaseSchema_0_18_3_sql.h" #include "DatabaseSchema_0_18_3_sql.h"
#include "DatabaseSchema_0_18_0_sql.h" #include "DatabaseSchema_0_18_0_sql.h"
#include "DatabaseSchema_0_17_0_sql.h" #include "DatabaseSchema_0_17_0_sql.h"
@@ -402,6 +403,7 @@ bool DBDriverSqlite3::connectDatabaseQuery(const std::string & url, bool overwri
schemas.push_back(std::make_pair("0.17.0", DATABASESCHEMA_0_17_0_SQL)); schemas.push_back(std::make_pair("0.17.0", DATABASESCHEMA_0_17_0_SQL));
schemas.push_back(std::make_pair("0.18.0", DATABASESCHEMA_0_18_0_SQL)); schemas.push_back(std::make_pair("0.18.0", DATABASESCHEMA_0_18_0_SQL));
schemas.push_back(std::make_pair("0.18.3", DATABASESCHEMA_0_18_3_SQL)); schemas.push_back(std::make_pair("0.18.3", DATABASESCHEMA_0_18_3_SQL));
schemas.push_back(std::make_pair("0.20.0", DATABASESCHEMA_0_20_0_SQL));
schemas.push_back(std::make_pair(uNumber2Str(RTABMAP_VERSION_MAJOR)+"."+uNumber2Str(RTABMAP_VERSION_MINOR), DATABASESCHEMA_SQL)); schemas.push_back(std::make_pair(uNumber2Str(RTABMAP_VERSION_MAJOR)+"."+uNumber2Str(RTABMAP_VERSION_MINOR), DATABASESCHEMA_SQL));
for(size_t i=0; i<schemas.size(); ++i) for(size_t i=0; i<schemas.size(); ++i)
{ {
@@ -1317,7 +1319,15 @@ void DBDriverSqlite3::loadNodeDataQuery(std::list<Signature *> & signatures, boo
if(images) if(images)
{ {
fields << "image, depth, calibration"; if(uStrNumCmp(_version, "0.22.0") >= 0)
{
fields << "image, depth, depth_confidence, calibration";
}
else
{
fields << "image, depth, calibration";
}
if(scan || userData || occupancyGrid) if(scan || userData || occupancyGrid)
{ {
fields << ", "; fields << ", ";
@@ -1448,6 +1458,7 @@ void DBDriverSqlite3::loadNodeDataQuery(std::list<Signature *> & signatures, boo
cv::Mat imageCompressed; cv::Mat imageCompressed;
cv::Mat depthOrRightCompressed; cv::Mat depthOrRightCompressed;
cv::Mat depthConfidenceCompressed;
std::vector<CameraModel> models; std::vector<CameraModel> models;
std::vector<StereoCameraModel> stereoModels; std::vector<StereoCameraModel> stereoModels;
Transform localTransform = Transform::getIdentity(); Transform localTransform = Transform::getIdentity();
@@ -1472,6 +1483,17 @@ void DBDriverSqlite3::loadNodeDataQuery(std::list<Signature *> & signatures, boo
depthOrRightCompressed = cv::Mat(1, dataSize, CV_8UC1, (void *)data).clone(); depthOrRightCompressed = cv::Mat(1, dataSize, CV_8UC1, (void *)data).clone();
} }
if(uStrNumCmp(_version, "0.22.0") >= 0)
{
//Create the depth image
data = sqlite3_column_blob(ppStmt, index);
dataSize = sqlite3_column_bytes(ppStmt, index++);
if(dataSize>4 && data)
{
depthConfidenceCompressed = cv::Mat(1, dataSize, CV_8UC1, (void *)data).clone();
}
}
if(uStrNumCmp(_version, "0.10.0") < 0) if(uStrNumCmp(_version, "0.10.0") < 0)
{ {
data = sqlite3_column_blob(ppStmt, index); // local transform data = sqlite3_column_blob(ppStmt, index); // local transform
@@ -1823,7 +1845,7 @@ void DBDriverSqlite3::loadNodeDataQuery(std::list<Signature *> & signatures, boo
{ {
if(models.size()) if(models.size())
{ {
(*iter)->sensorData().setRGBDImage(imageCompressed, depthOrRightCompressed, models); (*iter)->sensorData().setRGBDImage(imageCompressed, depthOrRightCompressed, depthConfidenceCompressed, models);
} }
else else
{ {
@@ -4478,6 +4500,7 @@ void DBDriverSqlite3::saveQuery(const std::list<Signature *> & signatures)
{ {
if(!(*i)->sensorData().imageCompressed().empty() || if(!(*i)->sensorData().imageCompressed().empty() ||
!(*i)->sensorData().depthOrRightCompressed().empty() || !(*i)->sensorData().depthOrRightCompressed().empty() ||
!(*i)->sensorData().depthConfidenceCompressed().empty() ||
!(*i)->sensorData().laserScanCompressed().isEmpty() || !(*i)->sensorData().laserScanCompressed().isEmpty() ||
!(*i)->sensorData().userDataCompressed().empty() || !(*i)->sensorData().userDataCompressed().empty() ||
!(*i)->sensorData().cameraModels().empty() || !(*i)->sensorData().cameraModels().empty() ||
@@ -6186,7 +6209,11 @@ void DBDriverSqlite3::stepScanUpdate(sqlite3_stmt * ppStmt, int nodeId, const La
std::string DBDriverSqlite3::queryStepSensorData() const std::string DBDriverSqlite3::queryStepSensorData() const
{ {
UASSERT(uStrNumCmp(_version, "0.10.0") >= 0); UASSERT(uStrNumCmp(_version, "0.10.0") >= 0);
if(uStrNumCmp(_version, "0.16.0") >= 0) if(uStrNumCmp(_version, "0.22.0") >= 0)
{
return "INSERT INTO Data(id, image, depth, depth_confidence, calibration, scan_info, scan, user_data, ground_cells, obstacle_cells, empty_cells, cell_size, view_point_x, view_point_y, view_point_z) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);";
}
else if(uStrNumCmp(_version, "0.16.0") >= 0)
{ {
return "INSERT INTO Data(id, image, depth, calibration, scan_info, scan, user_data, ground_cells, obstacle_cells, empty_cells, cell_size, view_point_x, view_point_y, view_point_z) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?);"; return "INSERT INTO Data(id, image, depth, calibration, scan_info, scan, user_data, ground_cells, obstacle_cells, empty_cells, cell_size, view_point_x, view_point_y, view_point_z) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?);";
} }
@@ -6250,6 +6277,20 @@ void DBDriverSqlite3::stepSensorData(sqlite3_stmt * ppStmt,
} }
UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error (%s): %s", _version.c_str(), sqlite3_errmsg(_ppDb)).c_str()); UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error (%s): %s", _version.c_str(), sqlite3_errmsg(_ppDb)).c_str());
//depth confidence
if(uStrNumCmp(_version, "0.22.0") >= 0)
{
if(!sensorData.depthConfidenceCompressed().empty())
{
rc = sqlite3_bind_blob(ppStmt, index++, sensorData.depthConfidenceCompressed().data, (int)sensorData.depthConfidenceCompressed().cols, SQLITE_STATIC);
}
else
{
rc = sqlite3_bind_null(ppStmt, index++);
}
UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error (%s): %s", _version.c_str(), sqlite3_errmsg(_ppDb)).c_str());
}
// calibration // calibration
std::vector<unsigned char> calibrationData; std::vector<unsigned char> calibrationData;
std::vector<float> calibration; std::vector<float> calibration;
+25 -5
View File
@@ -607,6 +607,7 @@ SensorData DBReader::getNextData(SensorCaptureInfo * info)
// update images and local transforms // update images and local transforms
cv::Mat combinedImages; cv::Mat combinedImages;
cv::Mat combinedDepthImages; cv::Mat combinedDepthImages;
cv::Mat combinedDepthConfidenceImages;
std::vector<CameraModel> combinedModels; std::vector<CameraModel> combinedModels;
std::vector<StereoCameraModel> combinedStereoModels; std::vector<StereoCameraModel> combinedStereoModels;
for(size_t i=0; i<_cameraIndices.size(); ++i) for(size_t i=0; i<_cameraIndices.size(); ++i)
@@ -645,6 +646,18 @@ SensorData DBReader::getNextData(SensorCaptureInfo * info)
fromROI = cv::Mat(data.depthOrRightRaw(), cv::Rect(_cameraIndices[i]*subImageWidth, 0, subImageWidth, data.depthOrRightRaw().rows)); fromROI = cv::Mat(data.depthOrRightRaw(), cv::Rect(_cameraIndices[i]*subImageWidth, 0, subImageWidth, data.depthOrRightRaw().rows));
toROI = cv::Mat(combinedDepthImages, cv::Rect(addedCameras*subImageWidth, 0, subImageWidth, combinedDepthImages.rows)); toROI = cv::Mat(combinedDepthImages, cv::Rect(addedCameras*subImageWidth, 0, subImageWidth, combinedDepthImages.rows));
fromROI.copyTo(toROI); fromROI.copyTo(toROI);
if(!data.depthConfidenceRaw().empty())
{
UASSERT(data.depthConfidenceRaw().size() == data.depthOrRightRaw().size());
if(combinedDepthConfidenceImages.empty())
{
combinedDepthConfidenceImages = cv::Mat(data.depthConfidenceRaw().rows, subImageWidth*(_cameraIndices.size()-i), data.depthConfidenceRaw().type());
}
fromROI = cv::Mat(data.depthConfidenceRaw(), cv::Rect(_cameraIndices[i]*subImageWidth, 0, subImageWidth, data.depthConfidenceRaw().rows));
toROI = cv::Mat(combinedDepthConfidenceImages, cv::Rect(addedCameras*subImageWidth, 0, subImageWidth, combinedDepthConfidenceImages.rows));
fromROI.copyTo(toROI);
}
} }
if(!data.cameraModels().empty()) if(!data.cameraModels().empty())
@@ -671,7 +684,7 @@ SensorData DBReader::getNextData(SensorCaptureInfo * info)
} }
if(!combinedModels.empty()) if(!combinedModels.empty())
{ {
data.setRGBDImage(combinedImages, combinedDepthImages, combinedModels); data.setRGBDImage(combinedImages, combinedDepthImages, combinedDepthConfidenceImages, combinedModels);
} }
else else
{ {
@@ -728,10 +741,11 @@ SensorData DBReader::getNextData(SensorCaptureInfo * info)
} }
data.setLandmarks(landmarks); data.setLandmarks(landmarks);
UDEBUG("Laser=%d RGB/Left=%d Depth/Right=%d, Grid=%d, UserData=%d, GlobalPose=%d, GPS=%d, IMU=%d", UDEBUG("Laser=%d RGB/Left=%d Depth/Right=%d, Conf=%d, Grid=%d, UserData=%d, GlobalPose=%d, GPS=%d, IMU=%d",
data.laserScanRaw().isEmpty()?0:1, data.laserScanRaw().isEmpty()?0:1,
data.imageRaw().empty()?0:1, data.imageRaw().empty()?0:1,
data.depthOrRightRaw().empty()?0:1, data.depthOrRightRaw().empty()?0:1,
data.depthConfidenceRaw().empty()?0:1,
data.gridCellSize()==0.0f?0:1, data.gridCellSize()==0.0f?0:1,
data.userDataRaw().empty()?0:1, data.userDataRaw().empty()?0:1,
globalPose.isNull()?0:1, globalPose.isNull()?0:1,
@@ -780,13 +794,19 @@ SensorData DBReader::getNextData(SensorCaptureInfo * info)
} }
else if(!combinedLocalTransforms.empty()) else if(!combinedLocalTransforms.empty())
{ {
// We are overriding the camra local transforms, let's move 3D words accordingly // We are overriding the camera local transforms, let's move 3D words accordingly
UASSERT(dbModels.size() == combinedLocalTransforms.size()); UASSERT(dbModels.size() == combinedLocalTransforms.size());
std::vector<cv::Point3f> newKeypoints3D; std::vector<cv::Point3f> newKeypoints3D;
UASSERT(dbModels[0].imageWidth()>0);
int subImageWidth = dbModels[0].imageWidth();
for(size_t i = 0; i<keypoints3D.size(); ++i) for(size_t i = 0; i<keypoints3D.size(); ++i)
{ {
cv::Point3f pt = util3d::transformPoint(keypoints3D.at(i), dbModels[i].localTransform().inverse()); int cameraIndex = int(keypoints.at(i).pt.x / subImageWidth);
pt = util3d::transformPoint(pt, combinedLocalTransforms[i]); UASSERT_MSG(cameraIndex >= 0 && cameraIndex < (int)dbModels.size(),
uFormat("cameraIndex=%d, db models=%d, kpt.x=%f, image width=%d",
cameraIndex, (int)dbModels.size(), keypoints[i].pt.x, subImageWidth).c_str());
cv::Point3f pt = util3d::transformPoint(keypoints3D.at(i), dbModels[cameraIndex].localTransform().inverse());
pt = util3d::transformPoint(pt, combinedLocalTransforms[cameraIndex]);
newKeypoints3D.push_back(pt); newKeypoints3D.push_back(pt);
} }
data.setFeatures(keypoints, newKeypoints3D, descriptors); data.setFeatures(keypoints, newKeypoints3D, descriptors);
+17 -12
View File
@@ -744,9 +744,8 @@ void calcRelativeErrors (
// compute rotational and translational errors // compute rotational and translational errors
Transform pose_delta_gt = poses_gt[i].inverse()*poses_gt[i+1]; Transform pose_delta_gt = poses_gt[i].inverse()*poses_gt[i+1];
Transform pose_delta_result = poses_result[i].inverse()*poses_result[i+1]; Transform pose_delta_result = poses_result[i].inverse()*poses_result[i+1];
Transform pose_error = pose_delta_result.inverse()*pose_delta_gt; float r_err = pose_delta_result.getAngle(pose_delta_gt);
float r_err = pose_error.getAngle(); float t_err = pose_delta_result.getDistance(pose_delta_gt);
float t_err = pose_error.getNorm();
// write to file // write to file
err.push_back(errors(i,r_err,t_err,0,0)); err.push_back(errors(i,r_err,t_err,0,0));
@@ -993,15 +992,21 @@ void computeMaxGraphErrors(
if(iter->second.type() != Link::kLandmark || if(iter->second.type() != Link::kLandmark ||
1.0 / static_cast<double>(iter->second.infMatrix().at<double>(5,5)) < 9999.0) 1.0 / static_cast<double>(iter->second.infMatrix().at<double>(5,5)) < 9999.0)
{ {
float opt_roll,opt_pitch,opt_yaw; float angularError = 0.0f;
float link_roll,link_pitch,link_yaw; if(force3DoF)
t.getEulerAngles(opt_roll, opt_pitch, opt_yaw); {
linkT.getEulerAngles(link_roll, link_pitch, link_yaw); float opt_roll,opt_pitch,opt_yaw;
float angularError = uMax3( float link_roll,link_pitch,link_yaw;
force3DoF?0:fabs(opt_roll - link_roll), t.getEulerAngles(opt_roll, opt_pitch, opt_yaw);
force3DoF?0:fabs(opt_pitch - link_pitch), linkT.getEulerAngles(link_roll, link_pitch, link_yaw);
fabs(opt_yaw - link_yaw)); angularError = fabs(opt_yaw - link_yaw);
angularError = angularError>M_PI?2*M_PI-angularError:angularError; angularError = angularError>M_PI?2*M_PI-angularError:angularError;
}
else
{
angularError = t.getAngle(linkT);
}
UASSERT(iter->second.rotVariance(false)>0.0); UASSERT(iter->second.rotVariance(false)>0.0);
float stddevAngular = sqrt(iter->second.rotVariance(false)); float stddevAngular = sqrt(iter->second.rotVariance(false));
float angularErrorRatio = angularError/stddevAngular; float angularErrorRatio = angularError/stddevAngular;
+19 -3
View File
@@ -4893,9 +4893,10 @@ Signature * Memory::createSignature(const SensorData & inputData, const Transfor
else else
{ {
decimationDepth = (int)ceil(float(data.depthRaw().rows) / float(targetSize)); decimationDepth = (int)ceil(float(data.depthRaw().rows) / float(targetSize));
UASSERT(data.depthConfidenceRaw().empty() || data.depthConfidenceRaw().size() == data.depthRaw().size());
} }
} }
UDEBUG("decimation rgbOrLeft(rows=%d)=%d, depthOrRight(rows=%d)=%d", data.imageRaw().rows, _imagePreDecimation, data.depthOrRightRaw().rows, decimationDepth); UDEBUG("decimation rgbOrLeft(rows=%d)=%d, depthOrRight(rows=%d)=%d (conf? %d)", data.imageRaw().rows, _imagePreDecimation, data.depthOrRightRaw().rows, decimationDepth, data.depthConfidenceRaw().empty()?0:1);
std::vector<CameraModel> cameraModels = decimatedData.cameraModels(); std::vector<CameraModel> cameraModels = decimatedData.cameraModels();
for(unsigned int i=0; i<cameraModels.size(); ++i) for(unsigned int i=0; i<cameraModels.size(); ++i)
@@ -4907,6 +4908,7 @@ Signature * Memory::createSignature(const SensorData & inputData, const Transfor
decimatedData.setRGBDImage( decimatedData.setRGBDImage(
util2d::decimate(decimatedData.imageRaw(), _imagePreDecimation), util2d::decimate(decimatedData.imageRaw(), _imagePreDecimation),
util2d::decimate(decimatedData.depthOrRightRaw(), decimationDepth), util2d::decimate(decimatedData.depthOrRightRaw(), decimationDepth),
util2d::decimate(decimatedData.depthConfidenceRaw(), decimationDepth),
cameraModels); cameraModels);
} }
@@ -5656,6 +5658,8 @@ Signature * Memory::createSignature(const SensorData & inputData, const Transfor
cv::Mat image = data.imageRaw(); cv::Mat image = data.imageRaw();
cv::Mat depthOrRightImage = data.depthOrRightRaw(); cv::Mat depthOrRightImage = data.depthOrRightRaw();
cv::Mat depthConfidence = data.depthConfidenceRaw();
std::vector<CameraModel> cameraModels = data.cameraModels(); std::vector<CameraModel> cameraModels = data.cameraModels();
std::vector<StereoCameraModel> stereoCameraModels = data.stereoCameraModels(); std::vector<StereoCameraModel> stereoCameraModels = data.stereoCameraModels();
@@ -5666,6 +5670,7 @@ Signature * Memory::createSignature(const SensorData & inputData, const Transfor
{ {
image = decimatedData.imageRaw(); image = decimatedData.imageRaw();
depthOrRightImage = decimatedData.depthOrRightRaw(); depthOrRightImage = decimatedData.depthOrRightRaw();
depthConfidence = decimatedData.depthConfidenceRaw();
cameraModels = decimatedData.cameraModels(); cameraModels = decimatedData.cameraModels();
stereoCameraModels = decimatedData.stereoCameraModels(); stereoCameraModels = decimatedData.stereoCameraModels();
} }
@@ -5879,9 +5884,10 @@ Signature * Memory::createSignature(const SensorData & inputData, const Transfor
Signature * s; Signature * s;
if(this->isBinDataKept() && (!isIntermediateNode || _saveIntermediateNodeData)) if(this->isBinDataKept() && (!isIntermediateNode || _saveIntermediateNodeData))
{ {
UDEBUG("Bin data kept: rgb=%d, depth=%d, scan=%d, userData=%d", UDEBUG("Bin data kept: rgb=%d, depth=%d, conf=%d, scan=%d, userData=%d",
image.empty()?0:1, image.empty()?0:1,
depthOrRightImage.empty()?0:1, depthOrRightImage.empty()?0:1,
depthConfidence.empty()?0:1,
laserScan.isEmpty()?0:1, laserScan.isEmpty()?0:1,
data.userDataRaw().empty()?0:1); data.userDataRaw().empty()?0:1);
@@ -5928,12 +5934,14 @@ Signature * Memory::createSignature(const SensorData & inputData, const Transfor
cv::Mat compressedImage; cv::Mat compressedImage;
cv::Mat compressedDepth; cv::Mat compressedDepth;
cv::Mat compressedDepthConfidence;
cv::Mat compressedScan; cv::Mat compressedScan;
cv::Mat compressedUserData; cv::Mat compressedUserData;
if(_compressionParallelized) if(_compressionParallelized)
{ {
rtabmap::CompressionThread ctImage(image, _rgbCompressionFormat); rtabmap::CompressionThread ctImage(image, _rgbCompressionFormat);
rtabmap::CompressionThread ctDepth(depthOrRightImage, depthOrRightImage.type() == CV_32FC1 || depthOrRightImage.type() == CV_16UC1?_depthCompressionFormat:_rgbCompressionFormat); rtabmap::CompressionThread ctDepth(depthOrRightImage, depthOrRightImage.type() == CV_32FC1 || depthOrRightImage.type() == CV_16UC1?_depthCompressionFormat:_rgbCompressionFormat);
rtabmap::CompressionThread ctDepthConfidence(depthConfidence);
rtabmap::CompressionThread ctLaserScan(laserScan.data()); rtabmap::CompressionThread ctLaserScan(laserScan.data());
rtabmap::CompressionThread ctUserData(data.userDataRaw()); rtabmap::CompressionThread ctUserData(data.userDataRaw());
if(!image.empty()) if(!image.empty())
@@ -5944,6 +5952,10 @@ Signature * Memory::createSignature(const SensorData & inputData, const Transfor
{ {
ctDepth.start(); ctDepth.start();
} }
if(!depthConfidence.empty())
{
ctDepthConfidence.start();
}
if(!laserScan.isEmpty()) if(!laserScan.isEmpty())
{ {
ctLaserScan.start(); ctLaserScan.start();
@@ -5954,11 +5966,13 @@ Signature * Memory::createSignature(const SensorData & inputData, const Transfor
} }
ctImage.join(); ctImage.join();
ctDepth.join(); ctDepth.join();
ctDepthConfidence.join();
ctLaserScan.join(); ctLaserScan.join();
ctUserData.join(); ctUserData.join();
compressedImage = ctImage.getCompressedData(); compressedImage = ctImage.getCompressedData();
compressedDepth = ctDepth.getCompressedData(); compressedDepth = ctDepth.getCompressedData();
compressedDepthConfidence = ctDepthConfidence.getCompressedData();
compressedScan = ctLaserScan.getCompressedData(); compressedScan = ctLaserScan.getCompressedData();
compressedUserData = ctUserData.getCompressedData(); compressedUserData = ctUserData.getCompressedData();
} }
@@ -5966,6 +5980,7 @@ Signature * Memory::createSignature(const SensorData & inputData, const Transfor
{ {
compressedImage = compressImage2(image, _rgbCompressionFormat); compressedImage = compressImage2(image, _rgbCompressionFormat);
compressedDepth = compressImage2(depthOrRightImage, depthOrRightImage.type() == CV_32FC1 || depthOrRightImage.type() == CV_16UC1?_depthCompressionFormat:_rgbCompressionFormat); compressedDepth = compressImage2(depthOrRightImage, depthOrRightImage.type() == CV_32FC1 || depthOrRightImage.type() == CV_16UC1?_depthCompressionFormat:_rgbCompressionFormat);
compressedDepthConfidence = compressData2(depthConfidence);
compressedScan = compressData2(laserScan.data()); compressedScan = compressData2(laserScan.data());
compressedUserData = compressData2(data.userDataRaw()); compressedUserData = compressData2(data.userDataRaw());
} }
@@ -6016,6 +6031,7 @@ Signature * Memory::createSignature(const SensorData & inputData, const Transfor
laserScan.localTransform()), laserScan.localTransform()),
compressedImage.empty()?data.imageCompressed():compressedImage, compressedImage.empty()?data.imageCompressed():compressedImage,
compressedDepth.empty()?data.depthOrRightCompressed():compressedDepth, compressedDepth.empty()?data.depthOrRightCompressed():compressedDepth,
compressedDepthConfidence.empty()?data.depthConfidenceCompressed():compressedDepthConfidence,
cameraModels, cameraModels,
id, id,
0, 0,
@@ -6113,7 +6129,7 @@ Signature * Memory::createSignature(const SensorData & inputData, const Transfor
// set raw data // set raw data
if(!cameraModels.empty()) if(!cameraModels.empty())
{ {
s->sensorData().setRGBDImage(image, depthOrRightImage, cameraModels, false); s->sensorData().setRGBDImage(image, depthOrRightImage, depthConfidence, cameraModels, false);
} }
else else
{ {
+2 -3
View File
@@ -191,9 +191,8 @@ std::map<std::string, float> OdometryInfo::statistics(const Transform & pose)
{ {
if(!transform.isNull()) if(!transform.isNull())
{ {
rtabmap::Transform diff = transformGroundTruth.inverse()*transform; stats.insert(std::make_pair("Odometry/TG_error_lin/m", transformGroundTruth.getDistance(transform)));
stats.insert(std::make_pair("Odometry/TG_error_lin/m", diff.getNorm())); stats.insert(std::make_pair("Odometry/TG_error_ang/deg", transformGroundTruth.getAngle(transform)*180.0/CV_PI));
stats.insert(std::make_pair("Odometry/TG_error_ang/deg", diff.getAngle()*180.0/CV_PI));
} }
transformGroundTruth.getTranslationAndEulerAngles(x,y,z,roll,pitch,yaw); transformGroundTruth.getTranslationAndEulerAngles(x,y,z,roll,pitch,yaw);
+16 -12
View File
@@ -447,7 +447,8 @@ std::map<int, Transform> Optimizer::optimizeBA(
const std::map<int, Signature> & signatures, const std::map<int, Signature> & signatures,
std::map<int, cv::Point3f> & points3DMap, std::map<int, cv::Point3f> & points3DMap,
std::map<int, std::map<int, FeatureBA> > & wordReferences, std::map<int, std::map<int, FeatureBA> > & wordReferences,
bool rematchFeatures) bool rematchFeatures,
const ParametersMap & registrationParameters)
{ {
UDEBUG(""); UDEBUG("");
std::map<int, std::vector<CameraModel> > multiModels; std::map<int, std::vector<CameraModel> > multiModels;
@@ -497,7 +498,7 @@ std::map<int, Transform> Optimizer::optimizeBA(
} }
// compute correspondences // compute correspondences
this->computeBACorrespondences(poses, links, signatures, points3DMap, wordReferences, rematchFeatures); this->computeBACorrespondences(poses, links, signatures, points3DMap, wordReferences, rematchFeatures, false, registrationParameters);
return optimizeBA(rootId, poses, links, multiModels, points3DMap, wordReferences); return optimizeBA(rootId, poses, links, multiModels, points3DMap, wordReferences);
} }
@@ -507,11 +508,12 @@ std::map<int, Transform> Optimizer::optimizeBA(
const std::map<int, Transform> & poses, const std::map<int, Transform> & poses,
const std::multimap<int, Link> & links, const std::multimap<int, Link> & links,
const std::map<int, Signature> & signatures, const std::map<int, Signature> & signatures,
bool rematchFeatures) bool rematchFeatures,
const ParametersMap & registrationParameters)
{ {
std::map<int, cv::Point3f> points3DMap; std::map<int, cv::Point3f> points3DMap;
std::map<int, std::map<int, FeatureBA> > wordReferences; std::map<int, std::map<int, FeatureBA> > wordReferences;
return optimizeBA(rootId, poses, links, signatures, points3DMap, wordReferences, rematchFeatures); return optimizeBA(rootId, poses, links, signatures, points3DMap, wordReferences, rematchFeatures, registrationParameters);
} }
Transform Optimizer::optimizeBA( Transform Optimizer::optimizeBA(
@@ -557,11 +559,20 @@ void Optimizer::computeBACorrespondences(
std::map<int, cv::Point3f> & points3DMap, std::map<int, cv::Point3f> & points3DMap,
std::map<int, std::map<int, FeatureBA> > & wordReferences, std::map<int, std::map<int, FeatureBA> > & wordReferences,
bool rematchFeatures, bool rematchFeatures,
bool useLinkTransformAsGuess) bool useLinkTransformAsGuess,
ParametersMap registrationParameters)
{ {
UDEBUG("rematchFeatures=%d", rematchFeatures?1:0); UDEBUG("rematchFeatures=%d", rematchFeatures?1:0);
int wordCount = 0; int wordCount = 0;
int edgeWithWordsAdded = 0; int edgeWithWordsAdded = 0;
// Some defaults if not provided
registrationParameters.insert(ParametersPair(Parameters::kVisEstimationType(), "1"));
registrationParameters.insert(ParametersPair(Parameters::kVisPnPReprojError(), "5"));
registrationParameters.insert(ParametersPair(Parameters::kVisMinInliers(), "6"));
registrationParameters.insert(ParametersPair(Parameters::kVisCorNNDR(), "0.6"));
RegistrationVis reg(registrationParameters);
std::map<int, std::map<cv::KeyPoint, int, KeyPointCompare> > frameToWordMap; // <FrameId, <Keypoint, wordId> > std::map<int, std::map<cv::KeyPoint, int, KeyPointCompare> > frameToWordMap; // <FrameId, <Keypoint, wordId> >
for(std::multimap<int, Link>::const_iterator iter=links.lower_bound(1); iter!=links.end(); ++iter) for(std::multimap<int, Link>::const_iterator iter=links.lower_bound(1); iter!=links.end(); ++iter)
{ {
@@ -601,13 +612,6 @@ void Optimizer::computeBACorrespondences(
sTo.getWords().size() && sTo.getWords().size() &&
sFrom.getWords3().size()) sFrom.getWords3().size())
{ {
ParametersMap regParam;
regParam.insert(ParametersPair(Parameters::kVisEstimationType(), "1"));
regParam.insert(ParametersPair(Parameters::kVisPnPReprojError(), "5"));
regParam.insert(ParametersPair(Parameters::kVisMinInliers(), "6"));
regParam.insert(ParametersPair(Parameters::kVisCorNNDR(), "0.6"));
RegistrationVis reg(regParam);
if(!rematchFeatures) if(!rematchFeatures)
{ {
sFrom.setWordsDescriptors(cv::Mat()); sFrom.setWordsDescriptors(cv::Mat());
+27 -11
View File
@@ -152,6 +152,7 @@ Rtabmap::Rtabmap() :
_maxOdomCacheSize(Parameters::defaultRGBDMaxOdomCacheSize()), _maxOdomCacheSize(Parameters::defaultRGBDMaxOdomCacheSize()),
_localizationSmoothing(Parameters::defaultRGBDLocalizationSmoothing()), _localizationSmoothing(Parameters::defaultRGBDLocalizationSmoothing()),
_localizationPriorInf(1.0/(Parameters::defaultRGBDLocalizationPriorError()*Parameters::defaultRGBDLocalizationPriorError())), _localizationPriorInf(1.0/(Parameters::defaultRGBDLocalizationPriorError()*Parameters::defaultRGBDLocalizationPriorError())),
_localizationSecondTryWithoutProximityLinks(Parameters::defaultRGBDLocalizationSecondTryWithoutProximityLinks()),
_createGlobalScanMap(Parameters::defaultRGBDProximityGlobalScanMap()), _createGlobalScanMap(Parameters::defaultRGBDProximityGlobalScanMap()),
_markerPriorsLinearVariance(Parameters::defaultMarkerPriorsVarianceLinear()), _markerPriorsLinearVariance(Parameters::defaultMarkerPriorsVarianceLinear()),
_markerPriorsAngularVariance(Parameters::defaultMarkerPriorsVarianceAngular()), _markerPriorsAngularVariance(Parameters::defaultMarkerPriorsVarianceAngular()),
@@ -632,6 +633,7 @@ void Rtabmap::parseParameters(const ParametersMap & parameters)
Parameters::parse(parameters, Parameters::kRGBDLocalizationPriorError(), localizationPriorError); Parameters::parse(parameters, Parameters::kRGBDLocalizationPriorError(), localizationPriorError);
UASSERT(localizationPriorError>0.0); UASSERT(localizationPriorError>0.0);
_localizationPriorInf = 1.0/(localizationPriorError*localizationPriorError); _localizationPriorInf = 1.0/(localizationPriorError*localizationPriorError);
Parameters::parse(parameters, Parameters::kRGBDLocalizationSecondTryWithoutProximityLinks(), _localizationSecondTryWithoutProximityLinks);
Parameters::parse(parameters, Parameters::kRGBDProximityGlobalScanMap(), _createGlobalScanMap); Parameters::parse(parameters, Parameters::kRGBDProximityGlobalScanMap(), _createGlobalScanMap);
Parameters::parse(parameters, Parameters::kMarkerPriorsVarianceLinear(), _markerPriorsLinearVariance); Parameters::parse(parameters, Parameters::kMarkerPriorsVarianceLinear(), _markerPriorsLinearVariance);
@@ -1699,7 +1701,7 @@ bool Rtabmap::process(
{ {
distanceToClosestNodeInTheGraph = sqrt(sqrdDistance); distanceToClosestNodeInTheGraph = sqrt(sqrdDistance);
UDEBUG("Last localization pose = %s, closest node=%d (%f m)", newPose.prettyPrint().c_str(), closestNode, distanceToClosestNodeInTheGraph); UDEBUG("Last localization pose = %s, closest node=%d (%f m)", newPose.prettyPrint().c_str(), closestNode, distanceToClosestNodeInTheGraph);
angleToClosestNodeInTheGraph = (newPose.inverse() * _optimizedPoses.at(closestNode)).getAngle(); angleToClosestNodeInTheGraph = newPose.getAngle(_optimizedPoses.at(closestNode));
} }
} }
@@ -3181,6 +3183,7 @@ bool Rtabmap::process(
int optimizationIterations = 0; int optimizationIterations = 0;
Transform previousMapCorrection; Transform previousMapCorrection;
bool delayedLocalization = false; bool delayedLocalization = false;
int odomCacheProximityLinksCleared = 0;
UDEBUG("RGB-D SLAM mode: %d", _rgbdSlamMode?1:0); UDEBUG("RGB-D SLAM mode: %d", _rgbdSlamMode?1:0);
UDEBUG("Incremental: %d", _memory->isIncremental()); UDEBUG("Incremental: %d", _memory->isIncremental());
UDEBUG("Loop hyp: %d", _loopClosureHypothesis.first); UDEBUG("Loop hyp: %d", _loopClosureHypothesis.first);
@@ -3299,7 +3302,7 @@ bool Rtabmap::process(
if(!posesOut.empty() && if(!posesOut.empty() &&
posesOut.begin()->first < _odomCachePoses.begin()->first) posesOut.begin()->first < _odomCachePoses.begin()->first)
{ {
optPoses = _graphOptimizer->optimize(posesOut.begin()->first, posesOut, edgeConstraintsOut, locOptCovariance); optPoses = _graphOptimizer->optimize(posesOut.begin()->first, posesOut, edgeConstraintsOut, locOptCovariance, 0, &optimizationError, &optimizationIterations);
} }
else else
{ {
@@ -3424,7 +3427,8 @@ bool Rtabmap::process(
} }
bool hasGlobalLoopClosuresOrLandmarks = false; bool hasGlobalLoopClosuresOrLandmarks = false;
if(rejectLocalization && !graph::filterLinks(constraints, Link::kLocalSpaceClosure, true).empty()) if(rejectLocalization &&
(_localizationSecondTryWithoutProximityLinks && !graph::filterLinks(constraints, Link::kLocalSpaceClosure, true).empty()))
{ {
// Let's try again without local loop closures // Let's try again without local loop closures
localizationLinks = graph::filterLinks(localizationLinks, Link::kLocalSpaceClosure); localizationLinks = graph::filterLinks(localizationLinks, Link::kLocalSpaceClosure);
@@ -3448,7 +3452,7 @@ bool Rtabmap::process(
if(!posesOut.empty() && if(!posesOut.empty() &&
posesOut.begin()->first < _odomCachePoses.begin()->first) posesOut.begin()->first < _odomCachePoses.begin()->first)
{ {
optPoses = _graphOptimizer->optimize(posesOut.begin()->first, posesOut, edgeConstraintsOut, locOptCovariance); optPoses = _graphOptimizer->optimize(posesOut.begin()->first, posesOut, edgeConstraintsOut, locOptCovariance, 0, &optimizationError, &optimizationIterations);
} }
else else
{ {
@@ -3584,13 +3588,14 @@ bool Rtabmap::process(
_odomCacheConstraints = graph::filterLinks(_odomCacheConstraints, Link::kLocalSpaceClosure); _odomCacheConstraints = graph::filterLinks(_odomCacheConstraints, Link::kLocalSpaceClosure);
if(before != _odomCacheConstraints.size()) if(before != _odomCacheConstraints.size())
{ {
UWARN("Successfully optimized without local loop closures! Clear them from local odometry cache. %ld/%ld have been removed.", UWARN("Successfully optimized without local loop closures! Clearing them from local odometry cache. %ld/%ld have been removed.",
before - _odomCacheConstraints.size(), before); before - _odomCacheConstraints.size(), before);
} }
else else
{ {
UWARN("Successfully optimized without local loop closures!"); UWARN("Successfully optimized without local loop closures!");
} }
odomCacheProximityLinksCleared = before - _odomCacheConstraints.size();
} }
// Count how many localization links are in the constraints // Count how many localization links are in the constraints
@@ -3645,6 +3650,14 @@ bool Rtabmap::process(
if(hadAlreadyLocalizationLinks || _maxOdomCacheSize == 0) if(hadAlreadyLocalizationLinks || _maxOdomCacheSize == 0)
{ {
UINFO("Update localization"); UINFO("Update localization");
// update odomCachePoses with optimized poses (but make sure to put them back in odom frame)
Transform mapToOdomCache = signature->getPose() * newOptPoseInv;
for(std::map<int, Transform>::iterator iter = _odomCachePoses.begin(); iter!=_odomCachePoses.end(); ++iter)
{
iter->second = mapToOdomCache * optPoses.at(iter->first);
}
if(_optimizeFromGraphEnd) if(_optimizeFromGraphEnd)
{ {
// update all previous nodes // update all previous nodes
@@ -3941,7 +3954,7 @@ bool Rtabmap::process(
{ {
distanceToClosestNodeInTheGraph = _lastLocalizationPose.getDistance(_optimizedPoses.at(closestNode)); distanceToClosestNodeInTheGraph = _lastLocalizationPose.getDistance(_optimizedPoses.at(closestNode));
UDEBUG("Last localization pose = %s, updated closest node=%d (%f m)", _lastLocalizationPose.prettyPrint().c_str(), closestNode, distanceToClosestNodeInTheGraph); UDEBUG("Last localization pose = %s, updated closest node=%d (%f m)", _lastLocalizationPose.prettyPrint().c_str(), closestNode, distanceToClosestNodeInTheGraph);
angleToClosestNodeInTheGraph = (_lastLocalizationPose.inverse() * _optimizedPoses.at(closestNode)).getAngle(); angleToClosestNodeInTheGraph = _lastLocalizationPose.getAngle(_optimizedPoses.at(closestNode));
} }
} }
_lastLocalizationPose = _optimizedPoses.at(signature->id()); // update _lastLocalizationPose = _optimizedPoses.at(signature->id()); // update
@@ -4090,16 +4103,15 @@ bool Rtabmap::process(
if(!sLoop->getGroundTruthPose().isNull() && !signature->getGroundTruthPose().isNull()) if(!sLoop->getGroundTruthPose().isNull() && !signature->getGroundTruthPose().isNull())
{ {
Transform transformGT = sLoop->getGroundTruthPose().inverse() * signature->getGroundTruthPose(); Transform transformGT = sLoop->getGroundTruthPose().inverse() * signature->getGroundTruthPose();
Transform error = loopIter->second.transform().inverse() * transformGT; statistics_.addStatistic(Statistics::kGtLocalization_linear_error(), loopIter->second.transform().getDistance(transformGT));
statistics_.addStatistic(Statistics::kGtLocalization_linear_error(), error.getNorm()); statistics_.addStatistic(Statistics::kGtLocalization_angular_error(), loopIter->second.transform().getAngle(transformGT)*180/M_PI);
statistics_.addStatistic(Statistics::kGtLocalization_angular_error(), error.getAngle(1,0,0)*180/M_PI);
} }
} }
_distanceTravelledSinceLastLocalization = 0.0f; _distanceTravelledSinceLastLocalization = 0.0f;
statistics_.addStatistic(Statistics::kLoopMapToOdom_norm(), _mapCorrection.getNorm()); statistics_.addStatistic(Statistics::kLoopMapToOdom_norm(), _mapCorrection.getNorm());
statistics_.addStatistic(Statistics::kLoopMapToOdom_angle(), _mapCorrection.getAngle()*180.0f/M_PI); statistics_.addStatistic(Statistics::kLoopMapToOdom_angle(), _mapCorrection.getAngle(Transform::getIdentity())*180.0f/M_PI);
_mapCorrection.getTranslationAndEulerAngles(x, y, z, roll, pitch, yaw); _mapCorrection.getTranslationAndEulerAngles(x, y, z, roll, pitch, yaw);
statistics_.addStatistic(Statistics::kLoopMapToOdom_x(), x); statistics_.addStatistic(Statistics::kLoopMapToOdom_x(), x);
statistics_.addStatistic(Statistics::kLoopMapToOdom_y(), y); statistics_.addStatistic(Statistics::kLoopMapToOdom_y(), y);
@@ -4113,7 +4125,7 @@ bool Rtabmap::process(
{ {
Transform odomCorrection = (previousMapCorrection*odomPose).inverse()*_mapCorrection*odomPose; Transform odomCorrection = (previousMapCorrection*odomPose).inverse()*_mapCorrection*odomPose;
statistics_.addStatistic(Statistics::kLoopOdom_correction_norm(), odomCorrection.getNorm()); statistics_.addStatistic(Statistics::kLoopOdom_correction_norm(), odomCorrection.getNorm());
statistics_.addStatistic(Statistics::kLoopOdom_correction_angle(), odomCorrection.getAngle()*180.0f/M_PI); statistics_.addStatistic(Statistics::kLoopOdom_correction_angle(), odomCorrection.getAngle(Transform::getIdentity())*180.0f/M_PI);
odomCorrection.getTranslationAndEulerAngles(x, y, z, roll, pitch, yaw); odomCorrection.getTranslationAndEulerAngles(x, y, z, roll, pitch, yaw);
statistics_.addStatistic(Statistics::kLoopOdom_correction_x(), x); statistics_.addStatistic(Statistics::kLoopOdom_correction_x(), x);
statistics_.addStatistic(Statistics::kLoopOdom_correction_y(), y); statistics_.addStatistic(Statistics::kLoopOdom_correction_y(), y);
@@ -4134,6 +4146,10 @@ bool Rtabmap::process(
statistics_.addStatistic(Statistics::kLoopMapToBase_yaw(), yaw*180.0f/M_PI); statistics_.addStatistic(Statistics::kLoopMapToBase_yaw(), yaw*180.0f/M_PI);
UINFO("Localization pose = %s", _lastLocalizationPose.prettyPrint().c_str()); UINFO("Localization pose = %s", _lastLocalizationPose.prettyPrint().c_str());
if(_localizationSecondTryWithoutProximityLinks) {
statistics_.addStatistic(Statistics::kLoopProximity_links_cleared(), (float)odomCacheProximityLinksCleared);
}
if(_localizationCovariance.total()==36) if(_localizationCovariance.total()==36)
{ {
double varLin = _graphOptimizer->isSlam2d()? double varLin = _graphOptimizer->isSlam2d()?
+155 -7
View File
@@ -107,6 +107,25 @@ SensorData::SensorData(
setUserData(userData); setUserData(userData);
} }
// RGB-D constructor + confidence + laser scan
SensorData::SensorData(
const LaserScan & laserScan,
const cv::Mat & rgb,
const cv::Mat & depth,
const cv::Mat & depthConfidence,
const CameraModel & cameraModel,
int id,
double stamp,
const cv::Mat & userData) :
_id(id),
_stamp(stamp),
_cellSize(0.0f)
{
setRGBDImage(rgb, depth, depthConfidence, cameraModel);
setLaserScan(laserScan);
setUserData(userData);
}
// Multi-cameras RGB-D constructor // Multi-cameras RGB-D constructor
SensorData::SensorData( SensorData::SensorData(
const cv::Mat & rgb, const cv::Mat & rgb,
@@ -123,6 +142,23 @@ SensorData::SensorData(
setUserData(userData); setUserData(userData);
} }
// Multi-cameras RGB-D constructor + confidence
SensorData::SensorData(
const cv::Mat & rgb,
const cv::Mat & depth,
const cv::Mat & depthConfidence,
const std::vector<CameraModel> & cameraModels,
int id,
double stamp,
const cv::Mat & userData) :
_id(id),
_stamp(stamp),
_cellSize(0.0f)
{
setRGBDImage(rgb, depth, depthConfidence, cameraModels);
setUserData(userData);
}
// Multi-cameras RGB-D constructor + laser scan // Multi-cameras RGB-D constructor + laser scan
SensorData::SensorData( SensorData::SensorData(
const LaserScan & laserScan, const LaserScan & laserScan,
@@ -141,6 +177,25 @@ SensorData::SensorData(
setUserData(userData); setUserData(userData);
} }
// Multi-cameras RGB-D constructor + confidence + laser scan
SensorData::SensorData(
const LaserScan & laserScan,
const cv::Mat & rgb,
const cv::Mat & depth,
const cv::Mat & depthConfidence,
const std::vector<CameraModel> & cameraModels,
int id,
double stamp,
const cv::Mat & userData) :
_id(id),
_stamp(stamp),
_cellSize(0.0f)
{
setRGBDImage(rgb, depth, depthConfidence, cameraModels);
setLaserScan(laserScan);
setUserData(userData);
}
// Stereo constructor // Stereo constructor
SensorData::SensorData( SensorData::SensorData(
const cv::Mat & left, const cv::Mat & left,
@@ -234,9 +289,29 @@ void SensorData::setRGBDImage(
models.push_back(model); models.push_back(model);
setRGBDImage(rgb, depth, models, clearPreviousData); setRGBDImage(rgb, depth, models, clearPreviousData);
} }
void SensorData::setRGBDImage(
const cv::Mat & rgb,
const cv::Mat & depth,
const cv::Mat & depthConfidence,
const CameraModel & model,
bool clearPreviousData)
{
std::vector<CameraModel> models;
models.push_back(model);
setRGBDImage(rgb, depth, depthConfidence, models, clearPreviousData);
}
void SensorData::setRGBDImage(
const cv::Mat & rgb,
const cv::Mat & depth,
const std::vector<CameraModel> & models,
bool clearPreviousData)
{
setRGBDImage(rgb, depth, cv::Mat(), models, clearPreviousData);
}
void SensorData::setRGBDImage( void SensorData::setRGBDImage(
const cv::Mat & rgb, const cv::Mat & rgb,
const cv::Mat & depth, const cv::Mat & depth,
const cv::Mat & depthConfidence,
const std::vector<CameraModel> & models, const std::vector<CameraModel> & models,
bool clearPreviousData) bool clearPreviousData)
{ {
@@ -300,6 +375,30 @@ void SensorData::setRGBDImage(
_depthOrRightRaw = cv::Mat(); _depthOrRightRaw = cv::Mat();
_depthOrRightCompressed = cv::Mat(); _depthOrRightCompressed = cv::Mat();
} }
if(depthConfidence.rows == 1)
{
UASSERT(depthConfidence.type() == CV_8UC1); // Bytes
_depthConfidenceCompressed = depthConfidence;
if(clearData)
{
_depthConfidenceRaw = cv::Mat();
}
}
else if(!depthConfidence.empty())
{
UASSERT(depthConfidence.type() == CV_8UC1);
_depthConfidenceRaw = depthConfidence;
if(clearData)
{
_depthConfidenceCompressed = cv::Mat();
}
}
else if(clearData)
{
_depthConfidenceRaw = cv::Mat();
_depthConfidenceCompressed = cv::Mat();
}
} }
void SensorData::setStereoImage( void SensorData::setStereoImage(
const cv::Mat & left, const cv::Mat & left,
@@ -528,7 +627,7 @@ void SensorData::setOccupancyGrid(
void SensorData::uncompressData() void SensorData::uncompressData()
{ {
cv::Mat tmpA, tmpB, tmpD, tmpE, tmpF, tmpG; cv::Mat tmpA, tmpB, tmpD, tmpE, tmpF, tmpG, tmpH;
LaserScan tmpC; LaserScan tmpC;
uncompressData(_imageCompressed.empty()?0:&tmpA, uncompressData(_imageCompressed.empty()?0:&tmpA,
_depthOrRightCompressed.empty()?0:&tmpB, _depthOrRightCompressed.empty()?0:&tmpB,
@@ -536,7 +635,8 @@ void SensorData::uncompressData()
_userDataCompressed.empty()?0:&tmpD, _userDataCompressed.empty()?0:&tmpD,
_groundCellsCompressed.empty()?0:&tmpE, _groundCellsCompressed.empty()?0:&tmpE,
_obstacleCellsCompressed.empty()?0:&tmpF, _obstacleCellsCompressed.empty()?0:&tmpF,
_emptyCellsCompressed.empty()?0:&tmpG); _emptyCellsCompressed.empty()?0:&tmpG,
_depthConfidenceCompressed.empty()?0:&tmpH);
} }
void SensorData::uncompressData( void SensorData::uncompressData(
@@ -546,16 +646,27 @@ void SensorData::uncompressData(
cv::Mat * userDataRaw, cv::Mat * userDataRaw,
cv::Mat * groundCellsRaw, cv::Mat * groundCellsRaw,
cv::Mat * obstacleCellsRaw, cv::Mat * obstacleCellsRaw,
cv::Mat * emptyCellsRaw) cv::Mat * emptyCellsRaw,
cv::Mat * depthConfidenceRaw)
{ {
UDEBUG("%d data(%d,%d,%d,%d,%d,%d,%d)", this->id(), imageRaw?1:0, depthRaw?1:0, laserScanRaw?1:0, userDataRaw?1:0, groundCellsRaw?1:0, obstacleCellsRaw?1:0, emptyCellsRaw?1:0); UDEBUG("%d data(%d,%d,%d,%d,%d,%d,%d,%d)",
this->id(),
imageRaw?1:0,
depthRaw?1:0,
laserScanRaw?1:0,
userDataRaw?1:0,
groundCellsRaw?1:0,
obstacleCellsRaw?1:0,
emptyCellsRaw?1:0,
depthConfidenceRaw?1:0);
if(imageRaw == 0 && if(imageRaw == 0 &&
depthRaw == 0 && depthRaw == 0 &&
laserScanRaw == 0 && laserScanRaw == 0 &&
userDataRaw == 0 && userDataRaw == 0 &&
groundCellsRaw == 0 && groundCellsRaw == 0 &&
obstacleCellsRaw == 0 && obstacleCellsRaw == 0 &&
emptyCellsRaw == 0) emptyCellsRaw == 0 &&
depthConfidenceRaw == 0)
{ {
return; return;
} }
@@ -566,7 +677,8 @@ void SensorData::uncompressData(
userDataRaw, userDataRaw,
groundCellsRaw, groundCellsRaw,
obstacleCellsRaw, obstacleCellsRaw,
emptyCellsRaw); emptyCellsRaw,
depthConfidenceRaw);
if(imageRaw && !imageRaw->empty() && _imageRaw.empty()) if(imageRaw && !imageRaw->empty() && _imageRaw.empty())
{ {
@@ -588,6 +700,10 @@ void SensorData::uncompressData(
{ {
_depthOrRightRaw = *depthRaw; _depthOrRightRaw = *depthRaw;
} }
if(depthConfidenceRaw && !depthConfidenceRaw->empty() && _depthConfidenceRaw.empty())
{
_depthConfidenceRaw = *depthConfidenceRaw;
}
if(laserScanRaw && !laserScanRaw->isEmpty() && _laserScanRaw.isEmpty()) if(laserScanRaw && !laserScanRaw->isEmpty() && _laserScanRaw.isEmpty())
{ {
_laserScanRaw = *laserScanRaw; _laserScanRaw = *laserScanRaw;
@@ -628,7 +744,8 @@ void SensorData::uncompressDataConst(
cv::Mat * userDataRaw, cv::Mat * userDataRaw,
cv::Mat * groundCellsRaw, cv::Mat * groundCellsRaw,
cv::Mat * obstacleCellsRaw, cv::Mat * obstacleCellsRaw,
cv::Mat * emptyCellsRaw) const cv::Mat * emptyCellsRaw,
cv::Mat * depthConfidenceRaw) const
{ {
if(imageRaw) if(imageRaw)
{ {
@@ -638,6 +755,10 @@ void SensorData::uncompressDataConst(
{ {
*depthRaw = _depthOrRightRaw; *depthRaw = _depthOrRightRaw;
} }
if(depthConfidenceRaw)
{
*depthConfidenceRaw = _depthConfidenceRaw;
}
if(laserScanRaw) if(laserScanRaw)
{ {
*laserScanRaw = _laserScanRaw; *laserScanRaw = _laserScanRaw;
@@ -660,6 +781,7 @@ void SensorData::uncompressDataConst(
} }
if( (imageRaw && imageRaw->empty()) || if( (imageRaw && imageRaw->empty()) ||
(depthRaw && depthRaw->empty()) || (depthRaw && depthRaw->empty()) ||
(depthConfidenceRaw && depthConfidenceRaw->empty()) ||
(laserScanRaw && laserScanRaw->isEmpty()) || (laserScanRaw && laserScanRaw->isEmpty()) ||
(userDataRaw && userDataRaw->empty()) || (userDataRaw && userDataRaw->empty()) ||
(groundCellsRaw && groundCellsRaw->empty()) || (groundCellsRaw && groundCellsRaw->empty()) ||
@@ -668,6 +790,7 @@ void SensorData::uncompressDataConst(
{ {
rtabmap::CompressionThread ctImage(_imageCompressed, true); rtabmap::CompressionThread ctImage(_imageCompressed, true);
rtabmap::CompressionThread ctDepth(_depthOrRightCompressed, true); rtabmap::CompressionThread ctDepth(_depthOrRightCompressed, true);
rtabmap::CompressionThread ctDepthConfidence(_depthConfidenceCompressed, false);
rtabmap::CompressionThread ctLaserScan(_laserScanCompressed.data(), false); rtabmap::CompressionThread ctLaserScan(_laserScanCompressed.data(), false);
rtabmap::CompressionThread ctUserData(_userDataCompressed, false); rtabmap::CompressionThread ctUserData(_userDataCompressed, false);
rtabmap::CompressionThread ctGroundCells(_groundCellsCompressed, false); rtabmap::CompressionThread ctGroundCells(_groundCellsCompressed, false);
@@ -683,6 +806,11 @@ void SensorData::uncompressDataConst(
UASSERT(_depthOrRightCompressed.type() == CV_8UC1); UASSERT(_depthOrRightCompressed.type() == CV_8UC1);
ctDepth.start(); ctDepth.start();
} }
if(depthConfidenceRaw && depthConfidenceRaw->empty() && !_depthConfidenceCompressed.empty())
{
UASSERT(_depthConfidenceCompressed.type() == CV_8UC1);
ctDepthConfidence.start();
}
if(laserScanRaw && laserScanRaw->isEmpty() && !_laserScanCompressed.isEmpty()) if(laserScanRaw && laserScanRaw->isEmpty() && !_laserScanCompressed.isEmpty())
{ {
UASSERT(_laserScanCompressed.isCompressed()); UASSERT(_laserScanCompressed.isCompressed());
@@ -710,6 +838,7 @@ void SensorData::uncompressDataConst(
} }
ctImage.join(); ctImage.join();
ctDepth.join(); ctDepth.join();
ctDepthConfidence.join();
ctLaserScan.join(); ctLaserScan.join();
ctUserData.join(); ctUserData.join();
ctGroundCells.join(); ctGroundCells.join();
@@ -746,6 +875,21 @@ void SensorData::uncompressDataConst(
} }
} }
} }
if(depthConfidenceRaw && depthConfidenceRaw->empty())
{
*depthConfidenceRaw = ctDepthConfidence.getUncompressedData();
if(depthConfidenceRaw->empty())
{
if(_depthConfidenceCompressed.empty())
{
UWARN("Requested depth confidence data, but the sensor data (%d) doesn't have depth confidence.", this->id());
}
else
{
UERROR("Requested depth confidence data, but failed to uncompress (%d).", this->id());
}
}
}
if(laserScanRaw && laserScanRaw->isEmpty()) if(laserScanRaw && laserScanRaw->isEmpty())
{ {
if(_laserScanCompressed.angleIncrement() > 0.0f) if(_laserScanCompressed.angleIncrement() > 0.0f)
@@ -815,6 +959,8 @@ unsigned long SensorData::getMemoryUsed() const // Return memory usage in Bytes
(_imageRaw.empty()?0:_imageRaw.total()*_imageRaw.elemSize()) + (_imageRaw.empty()?0:_imageRaw.total()*_imageRaw.elemSize()) +
(_depthOrRightCompressed.empty()?0:_depthOrRightCompressed.total()*_depthOrRightCompressed.elemSize()) + (_depthOrRightCompressed.empty()?0:_depthOrRightCompressed.total()*_depthOrRightCompressed.elemSize()) +
(_depthOrRightRaw.empty()?0:_depthOrRightRaw.total()*_depthOrRightRaw.elemSize()) + (_depthOrRightRaw.empty()?0:_depthOrRightRaw.total()*_depthOrRightRaw.elemSize()) +
(_depthConfidenceCompressed.empty()?0:_depthConfidenceCompressed.total()*_depthConfidenceCompressed.elemSize()) +
(_depthConfidenceRaw.empty()?0:_depthConfidenceRaw.total()*_depthConfidenceRaw.elemSize()) +
(_userDataCompressed.empty()?0:_userDataCompressed.total()*_userDataCompressed.elemSize()) + (_userDataCompressed.empty()?0:_userDataCompressed.total()*_userDataCompressed.elemSize()) +
(_userDataRaw.empty()?0:_userDataRaw.total()*_userDataRaw.elemSize()) + (_userDataRaw.empty()?0:_userDataRaw.total()*_userDataRaw.elemSize()) +
(_laserScanCompressed.empty()?0:_laserScanCompressed.data().total()*_laserScanCompressed.data().elemSize()) + (_laserScanCompressed.empty()?0:_laserScanCompressed.data().total()*_laserScanCompressed.data().elemSize()) +
@@ -836,6 +982,7 @@ void SensorData::clearCompressedData(bool images, bool scan, bool userData)
{ {
_imageCompressed=cv::Mat(); _imageCompressed=cv::Mat();
_depthOrRightCompressed=cv::Mat(); _depthOrRightCompressed=cv::Mat();
_depthConfidenceCompressed=cv::Mat();
} }
if(scan) if(scan)
{ {
@@ -852,6 +999,7 @@ void SensorData::clearRawData(bool images, bool scan, bool userData)
{ {
_imageRaw=cv::Mat(); _imageRaw=cv::Mat();
_depthOrRightRaw=cv::Mat(); _depthOrRightRaw=cv::Mat();
_depthConfidenceRaw=cv::Mat();
} }
if(scan) if(scan)
{ {
+2 -4
View File
@@ -273,11 +273,9 @@ void Transform::getTranslation(float & x, float & y, float & z) const
z = this->z(); z = this->z();
} }
float Transform::getAngle(float x, float y, float z) const float Transform::getAngle(const Transform & t) const
{ {
Eigen::Vector3f vA(x,y,z); return getQuaternionf().angularDistance(t.getQuaternionf());
Eigen::Vector3f vB = this->toEigen3f().linear()*Eigen::Vector3f(1,0,0);
return pcl::getAngle3D(Eigen::Vector4f(vA[0], vA[1], vA[2], 0), Eigen::Vector4f(vB[0], vB[1], vB[2], 0));
} }
float Transform::getNorm() const float Transform::getNorm() const
+1 -1
View File
@@ -217,7 +217,7 @@ Transform OdometryDVO::computeTransform(
t = motionFromKeyFrame_.inverse() * t; t = motionFromKeyFrame_.inverse() * t;
// TODO make parameters? // TODO make parameters?
if(currentMotion.getNorm() > 0.01 || currentMotion.getAngle() > 0.01) if(currentMotion.getNorm() > 0.01 || currentMotion.getAngle(Transform::getIdentity()) > 0.01)
{ {
if(info) if(info)
{ {
+1 -1
View File
@@ -2,7 +2,7 @@
# #
# Drop this file in the root folder of SuperPoint git: https://github.com/magicleap/SuperPointPretrainedNetwork # Drop this file in the root folder of SuperPoint git: https://github.com/magicleap/SuperPointPretrainedNetwork
# To use with rtabmap: # To use with rtabmap:
# --Vis/FeatureType 15 --PyDetector/Path "~/SuperPointPretrainedNetwork/rtabmap_superpoint.py" --PyDetector/Model "~/SuperPointPretrainedNetwork/superpoint_v1.pth" # --Vis/FeatureType 15 --Kp/DetectorStrategy 15 --PyDetector/Path "~/SuperPointPretrainedNetwork/rtabmap_superpoint.py"
# #
import random import random
@@ -32,6 +32,7 @@ CREATE TABLE Data (
id INTEGER NOT NULL, id INTEGER NOT NULL,
image BLOB, -- compressed image (Grayscale or RGB) image BLOB, -- compressed image (Grayscale or RGB)
depth BLOB, -- compressed image (Depth or Right image) depth BLOB, -- compressed image (Depth or Right image)
depth_confidence BLOB, -- compressed data (low=0 high=100)
calibration BLOB, -- fx, fy, cx, cy, [baseline,] width, height, local_transform calibration BLOB, -- fx, fy, cx, cy, [baseline,] width, height, local_transform
scan BLOB, -- compressed data (Laser scan) scan BLOB, -- compressed data (Laser scan)
@@ -0,0 +1,182 @@
-- *******************************************************************
-- DatabaseSchema: Script for creating the database
-- Usage:
-- $ sqlite3 LTM.db < DatabaseSchema.sql
--
-- *******************************************************************
-- *******************************************************************
-- CLEAN
-- *******************************************************************
/*DROP TABLE Node;*/
-- *******************************************************************
-- CREATE
-- *******************************************************************
CREATE TABLE Node (
id INTEGER NOT NULL,
map_id INTEGER NOT NULL,
weight INTEGER,
stamp FLOAT,
pose BLOB, -- 3x4 float
ground_truth_pose BLOB, -- 3x4 float
velocity BLOB, -- 6 float (vx,vy,vz,vroll,vpitch,vyaw) m/s and rad/s
label TEXT,
gps BLOB, -- 1x6 double: stamp, longitude (DD), latitude (DD), altitude (m), accuracy (m), bearing (North 0->360 deg clockwise)
env_sensors BLOB, -- Variable 3xdouble: (sensorId1, value, stamp, sensorId2, value, stamp, ...)
time_enter DATE,
PRIMARY KEY (id)
);
CREATE TABLE Data (
id INTEGER NOT NULL,
image BLOB, -- compressed image (Grayscale or RGB)
depth BLOB, -- compressed image (Depth or Right image)
calibration BLOB, -- fx, fy, cx, cy, [baseline,] width, height, local_transform
scan BLOB, -- compressed data (Laser scan)
scan_info BLOB, -- scan_max_pts, scan_max_range, scan_format, local_transform
ground_cells BLOB, -- compressed data (occupancy grid)
obstacle_cells BLOB, -- compressed data (occupancy grid)
empty_cells BLOB, -- compressed data (occupancy grid)
cell_size FLOAT,
view_point_x FLOAT,
view_point_y FLOAT,
view_point_z FLOAT,
user_data BLOB, -- compressed data (User data)
time_enter DATE,
PRIMARY KEY (id)
);
CREATE TABLE Link (
from_id INTEGER NOT NULL,
to_id INTEGER NOT NULL,
type INTEGER NOT NULL, -- kNeighbor=0, kGlobalClosure=1, kLocalSpaceClosure=2, kLocalTimeClosure=3, kUserClosure=4, kVirtualClosure=5, kNeighborMerged=6, kPosePrior=7, kLandmark=8
information_matrix BLOB NOT NULL, -- 6x6 double (inverse covariance)
transform BLOB, -- 3x4 float
user_data BLOB, -- compressed data (User data)
FOREIGN KEY (from_id) REFERENCES Node(id),
FOREIGN KEY (to_id) REFERENCES Node(id)
);
--
CREATE TABLE Word (
id INTEGER NOT NULL,
descriptor_size INTEGER NOT NULL,
descriptor BLOB NOT NULL,
time_enter DATE,
PRIMARY KEY (id)
);
CREATE TABLE Feature (
node_id INTEGER NOT NULL,
word_id INTEGER NOT NULL,
pos_x FLOAT NOT NULL,
pos_y FLOAT NOT NULL,
size INTEGER NOT NULL,
dir FLOAT NOT NULL,
response FLOAT NOT NULL,
octave INTEGER NOT NULL,
depth_x FLOAT,
depth_y FLOAT,
depth_z FLOAT,
descriptor_size INTEGER,
descriptor BLOB,
FOREIGN KEY (node_id) REFERENCES Node(id)
);
CREATE TABLE GlobalDescriptor (
node_id INTEGER NOT NULL,
type INTEGER NOT NULL,
info BLOB,
data BLOB NOT NULL,
FOREIGN KEY (node_id) REFERENCES Node(id)
);
--
CREATE TABLE Info (
STM_size INTEGER,
last_sign_added INTEGER,
process_mem_used INTEGER,
database_mem_used INTEGER,
dictionary_size INTEGER,
parameters TEXT,
time_enter DATE
);
CREATE TABLE Statistics (
id INTEGER NOT NULL,
stamp FLOAT,
data BLOB, -- compressed string
wm_state BLOB, -- compressed data
FOREIGN KEY (id) REFERENCES Node(id)
);
CREATE TABLE Admin (
version TEXT,
preview_image BLOB, -- compressed image
opt_cloud BLOB, -- compressed data
opt_ids BLOB, -- Node ids used to generate the optimized cloud/mesh
opt_poses BLOB, -- compressed N*3x4 float
opt_last_localization BLOB, -- 3x4 float
opt_polygons_size INTEGER, -- e.g., 3
opt_polygons BLOB, -- compressed data [length_v0, i0,i1,i3, length_v1, i0,i1,i3]
opt_tex_coords BLOB, -- compressed data [length_v0, u0,v0,u1,v1,u2,v2, length_v1, u0,v0,u1,v1,u2,v2]
opt_tex_materials BLOB, -- compressed image
opt_map BLOB, -- compressed CV_8SC1 occupancy grid
opt_map_x_min FLOAT,
opt_map_y_min FLOAT,
opt_map_resolution FLOAT,
time_enter DATE
);
-- *******************************************************************
-- TRIGGERS
-- *******************************************************************
CREATE TRIGGER insert_Feature BEFORE INSERT ON Feature
WHEN NOT EXISTS (SELECT Node.id FROM Node WHERE Node.id = NEW.node_id)
BEGIN
SELECT RAISE(ABORT, 'Foreign key constraint failed in Feature table');
END;
-- Creating a trigger for time_enter
CREATE TRIGGER insert_Node_timeEnter AFTER INSERT ON Node
BEGIN
UPDATE Node SET time_enter = DATETIME('NOW') WHERE rowid = new.rowid;
END;
CREATE TRIGGER insert_Data_timeEnter AFTER INSERT ON Data
BEGIN
UPDATE Node SET time_enter = DATETIME('NOW') WHERE rowid = new.rowid;
END;
CREATE TRIGGER insert_Word_timeEnter AFTER INSERT ON Word
BEGIN
UPDATE Word SET time_enter = DATETIME('NOW') WHERE rowid = new.rowid;
END;
CREATE TRIGGER insert_Info_timeEnter AFTER INSERT ON Info
BEGIN
UPDATE Info SET time_enter = DATETIME('NOW') WHERE rowid = new.rowid;
END;
-- *******************************************************************
-- INDEXES
-- *******************************************************************
CREATE UNIQUE INDEX IDX_Node_id on Node (id);
CREATE INDEX IDX_Feature_node_id on Feature (node_id);
CREATE INDEX IDX_GlobalDescriptor_node_id on GlobalDescriptor (node_id);
CREATE INDEX IDX_Link_from_id on Link (from_id);
CREATE UNIQUE INDEX IDX_node_label on Node (label);
CREATE UNIQUE INDEX IDX_Statistics_id on Statistics (id);
-- *******************************************************************
-- VERSION
-- *******************************************************************
INSERT INTO Admin(version) VALUES('0.20.0');
+1 -2
View File
@@ -242,8 +242,7 @@ cv::Mat SPDetector::compute(const std::vector<cv::KeyPoint> &keypoints)
auto desc = torch::grid_sampler(desc_, grid, 0, 0, true); // [1, 256, 1, n_keypoints] auto desc = torch::grid_sampler(desc_, grid, 0, 0, true); // [1, 256, 1, n_keypoints]
// normalize to 1 // normalize to 1
desc = torch::nn::functional::normalize(desc.reshape({1, desc_.size(1), -1})); //[1, 256, n_keypoints] desc = torch::nn::functional::normalize(desc.reshape({desc_.size(1), -1}), torch::nn::functional::NormalizeFuncOptions().dim(0)); //[256, n_keypoints]
desc = desc.squeeze(); //[256, n_keypoints]
desc = desc.transpose(0, 1).contiguous(); //[n_keypoints, 256] desc = desc.transpose(0, 1).contiguous(); //[n_keypoints, 256]
if(cuda_) if(cuda_)
+91 -1
View File
@@ -1359,18 +1359,38 @@ cv::Mat interpolate(const cv::Mat & image, int factor, float depthErrorRatio)
} }
// Registration Depth to RGB (return registered depth image) // Registration Depth to RGB (return registered depth image)
cv::Mat registerDepth(
const cv::Mat & depth,
const cv::Mat & depthK,
const cv::Size & colorSize,
const cv::Mat & colorK,
const rtabmap::Transform & transform)
{
cv::Mat tmp;
return registerDepth(
depth,
cv::Mat(),
depthK,
colorSize,
colorK,
transform,
tmp);
}
cv::Mat registerDepth( cv::Mat registerDepth(
const cv::Mat & depth, const cv::Mat & depth,
const cv::Mat & confidence,
const cv::Mat & depthK, const cv::Mat & depthK,
const cv::Size & colorSize, const cv::Size & colorSize,
const cv::Mat & colorK, const cv::Mat & colorK,
const rtabmap::Transform & transform) const rtabmap::Transform & transform,
cv::Mat & registeredConfidence)
{ {
UASSERT(!transform.isNull()); UASSERT(!transform.isNull());
UASSERT(!depth.empty()); UASSERT(!depth.empty());
UASSERT(depth.type() == CV_16UC1 || depth.type() == CV_32FC1); // mm or m UASSERT(depth.type() == CV_16UC1 || depth.type() == CV_32FC1); // mm or m
UASSERT(depthK.type() == CV_64FC1 && depthK.cols == 3 && depthK.cols == 3); UASSERT(depthK.type() == CV_64FC1 && depthK.cols == 3 && depthK.cols == 3);
UASSERT(colorK.type() == CV_64FC1 && colorK.cols == 3 && colorK.cols == 3); UASSERT(colorK.type() == CV_64FC1 && colorK.cols == 3 && colorK.cols == 3);
UASSERT(confidence.empty() || (confidence.size() == depth.size() && confidence.type()==CV_8UC1));
float fx = depthK.at<double>(0,0); float fx = depthK.at<double>(0,0);
float fy = depthK.at<double>(1,1); float fy = depthK.at<double>(1,1);
@@ -1389,10 +1409,19 @@ cv::Mat registerDepth(
Eigen::Vector4f P4,P3; Eigen::Vector4f P4,P3;
P4[3] = 1; P4[3] = 1;
cv::Mat registered = cv::Mat::zeros(colorSize, depth.type()); cv::Mat registered = cv::Mat::zeros(colorSize, depth.type());
registeredConfidence = cv::Mat();
if(!confidence.empty())
{
registeredConfidence = cv::Mat::zeros(colorSize, confidence.type());
}
bool depthInMM = depth.type() == CV_16UC1; bool depthInMM = depth.type() == CV_16UC1;
for(int y=0; y<depth.rows; ++y) for(int y=0; y<depth.rows; ++y)
{ {
const unsigned char * confPtr = 0;
if(!confidence.empty()) {
confPtr = confidence.ptr<unsigned char>(y);
}
for(int x=0; x<depth.cols; ++x) for(int x=0; x<depth.cols; ++x)
{ {
//filtering //filtering
@@ -1419,6 +1448,9 @@ cv::Mat registerDepth(
if(zReg == 0 || z16 < zReg) if(zReg == 0 || z16 < zReg)
{ {
zReg = z16; zReg = z16;
if(confPtr) {
registeredConfidence.at<unsigned char>(dy, dx) = confPtr[x];
}
} }
} }
else else
@@ -1427,6 +1459,9 @@ cv::Mat registerDepth(
if(zReg == 0 || z < zReg) if(zReg == 0 || z < zReg)
{ {
zReg = z; zReg = z;
if(confPtr) {
registeredConfidence.at<unsigned char>(dy, dx) = confPtr[x];
}
} }
} }
} }
@@ -1931,6 +1966,61 @@ cv::Mat fastBilateralFiltering(const cv::Mat & depth, float sigmaS, float sigmaR
return output; return output;
} }
void depthBleedingFiltering(cv::Mat & depth, float maxDepthError)
{
if(depth.empty())
{
return;
}
UASSERT(depth.type() == CV_32FC1 || depth.type() == CV_16UC1);
// ignore border
depth.row(0).setTo(cv::Scalar(0));
depth.row(depth.rows-1).setTo(cv::Scalar(0));
depth.col(0).setTo(cv::Scalar(0));
depth.col(depth.cols-1).setTo(cv::Scalar(0));
if(depth.type() == CV_32FC1)
{
float * depthPtr = depth.ptr<float>();
for(int v=1; v<depth.rows-1; ++v)
{
for(int u=1; u<depth.cols-1; ++u)
{
int row = depth.cols*v;
float & ref = depthPtr[row + u];
if((fabs(ref - depthPtr[row + u - 1]) > maxDepthError &&
fabs(ref - depthPtr[row + u + 1]) > maxDepthError) ||
(fabs(ref - depthPtr[depth.cols*(v-1) + u]) > maxDepthError &&
fabs(ref - depthPtr[depth.cols*(v+1) + u]) > maxDepthError))
{
ref = 0.0f;
}
}
}
}
else if(depth.type() == CV_16UC1)
{
unsigned short * depthPtr = depth.ptr<unsigned short>();
unsigned short maxDepthErrorMM = (unsigned short)(maxDepthError*1000.0f);
for(int v=1; v<depth.rows-1; ++v)
{
for(int u=1; u<depth.cols-1; ++u)
{
int row = depth.cols*v;
unsigned short & ref = depthPtr[row + u];
if((abs((int)ref - (int)depthPtr[row + u - 1]) > maxDepthErrorMM &&
abs((int)ref - (int)depthPtr[row + u + 1]) > maxDepthErrorMM) ||
(abs((int)ref - (int)depthPtr[depth.cols*(v-1) + u]) > maxDepthErrorMM &&
abs((int)ref - (int)depthPtr[depth.cols*(v+1) + u]) > maxDepthErrorMM))
{
ref = 0;
}
}
}
}
}
/** /**
* \brief Automatic brightness and contrast optimization with optional histogram clipping * \brief Automatic brightness and contrast optimization with optional histogram clipping
* \param [in]src Input image GRAY or BGR or BGRA * \param [in]src Input image GRAY or BGR or BGRA
+207 -90
View File
@@ -276,12 +276,33 @@ pcl::PointCloud<pcl::PointXYZ>::Ptr cloudFromDepth(
return cloudFromDepth(imageDepth, model, decimation, maxDepth, minDepth, validIndices); return cloudFromDepth(imageDepth, model, decimation, maxDepth, minDepth, validIndices);
} }
pcl::PointCloud<pcl::PointXYZ>::Ptr cloudFromDepth(
const cv::Mat & imageDepthIn,
const CameraModel & model,
int decimation,
float maxDepth,
float minDepth,
std::vector<int> * validIndices)
{
return cloudFromDepth(
imageDepthIn,
cv::Mat(),
model,
decimation,
maxDepth,
minDepth,
0,
validIndices);
}
pcl::PointCloud<pcl::PointXYZ>::Ptr cloudFromDepth( pcl::PointCloud<pcl::PointXYZ>::Ptr cloudFromDepth(
const cv::Mat & imageDepthIn, const cv::Mat & imageDepthIn,
const cv::Mat & imageDepthConfidenceIn,
const CameraModel & model, const CameraModel & model,
int decimation, int decimation,
float maxDepth, float maxDepth,
float minDepth, float minDepth,
unsigned char confidenceThr,
std::vector<int> * validIndices) std::vector<int> * validIndices)
{ {
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>); pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
@@ -294,8 +315,10 @@ pcl::PointCloud<pcl::PointXYZ>::Ptr cloudFromDepth(
UASSERT(model.isValidForProjection()); UASSERT(model.isValidForProjection());
UASSERT(!imageDepthIn.empty() && (imageDepthIn.type() == CV_16UC1 || imageDepthIn.type() == CV_32FC1)); UASSERT(!imageDepthIn.empty() && (imageDepthIn.type() == CV_16UC1 || imageDepthIn.type() == CV_32FC1));
UASSERT(imageDepthConfidenceIn.empty() || confidenceThr == 0 || (imageDepthConfidenceIn.type() == CV_8UC1 && imageDepthConfidenceIn.size() == imageDepthIn.size()));
cv::Mat imageDepth = imageDepthIn; cv::Mat imageDepth = imageDepthIn;
cv::Mat imageDepthConfidence = confidenceThr==0?cv::Mat():imageDepthConfidenceIn;
if(model.imageHeight()>0 && model.imageWidth()>0) if(model.imageHeight()>0 && model.imageWidth()>0)
{ {
UASSERT(model.imageHeight() % imageDepthIn.rows == 0 && model.imageWidth() % imageDepthIn.cols == 0); UASSERT(model.imageHeight() % imageDepthIn.rows == 0 && model.imageWidth() % imageDepthIn.cols == 0);
@@ -322,6 +345,9 @@ pcl::PointCloud<pcl::PointXYZ>::Ptr cloudFromDepth(
{ {
UDEBUG("Depth interpolation factor=%d", targetSize/imageDepthIn.rows); UDEBUG("Depth interpolation factor=%d", targetSize/imageDepthIn.rows);
imageDepth = util2d::interpolate(imageDepthIn, targetSize/imageDepthIn.rows); imageDepth = util2d::interpolate(imageDepthIn, targetSize/imageDepthIn.rows);
if(!imageDepthConfidence.empty()) {
imageDepthConfidence = util2d::interpolate(imageDepthConfidenceIn, targetSize/imageDepthConfidenceIn.rows);
}
decimation = 1; decimation = 1;
} }
else if(targetSize == imageDepthIn.rows) else if(targetSize == imageDepthIn.rows)
@@ -373,11 +399,13 @@ pcl::PointCloud<pcl::PointXYZ>::Ptr cloudFromDepth(
float depthCx = model.cx() * rgbToDepthFactorX; float depthCx = model.cx() * rgbToDepthFactorX;
float depthCy = model.cy() * rgbToDepthFactorY; float depthCy = model.cy() * rgbToDepthFactorY;
UDEBUG("depth=%dx%d fx=%f fy=%f cx=%f cy=%f (depth factors=%f %f) decimation=%d", UDEBUG("depth=%dx%d fx=%f fy=%f cx=%f cy=%f (depth factors=%f %f) has confidence=%d (thr=%d) decimation=%d",
imageDepth.cols, imageDepth.rows, imageDepth.cols, imageDepth.rows,
model.fx(), model.fy(), model.cx(), model.cy(), model.fx(), model.fy(), model.cx(), model.cy(),
rgbToDepthFactorX, rgbToDepthFactorX,
rgbToDepthFactorY, rgbToDepthFactorY,
imageDepthConfidenceIn.empty()?0:1,
(int)confidenceThr,
decimation); decimation);
int oi = 0; int oi = 0;
@@ -387,21 +415,21 @@ pcl::PointCloud<pcl::PointXYZ>::Ptr cloudFromDepth(
{ {
pcl::PointXYZ & pt = cloud->at((h/decimation)*cloud->width + (w/decimation)); pcl::PointXYZ & pt = cloud->at((h/decimation)*cloud->width + (w/decimation));
pcl::PointXYZ ptXYZ = projectDepthTo3D(imageDepth, w, h, depthCx, depthCy, depthFx, depthFy, false); pt.x = pt.y = pt.z = std::numeric_limits<float>::quiet_NaN();
if(pcl::isFinite(ptXYZ) && ptXYZ.z>=minDepth && (maxDepth<=0.0f || ptXYZ.z <= maxDepth)) if(imageDepthConfidence.empty() || imageDepthConfidence.at<unsigned char>(h,w) >= confidenceThr)
{ {
pt.x = ptXYZ.x; pcl::PointXYZ ptXYZ = projectDepthTo3D(imageDepth, w, h, depthCx, depthCy, depthFx, depthFy, false);
pt.y = ptXYZ.y; if(pcl::isFinite(ptXYZ) && ptXYZ.z>=minDepth && (maxDepth<=0.0f || ptXYZ.z <= maxDepth))
pt.z = ptXYZ.z;
if(validIndices)
{ {
validIndices->at(oi++) = (h/decimation)*cloud->width + (w/decimation); pt.x = ptXYZ.x;
pt.y = ptXYZ.y;
pt.z = ptXYZ.z;
if(validIndices)
{
validIndices->at(oi++) = (h/decimation)*cloud->width + (w/decimation);
}
} }
} }
else
{
pt.x = pt.y = pt.z = std::numeric_limits<float>::quiet_NaN();
}
} }
} }
@@ -427,13 +455,36 @@ pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudFromDepthRGB(
return cloudFromDepthRGB(imageRgb, imageDepth, model, decimation, maxDepth, minDepth, validIndices); return cloudFromDepthRGB(imageRgb, imageDepth, model, decimation, maxDepth, minDepth, validIndices);
} }
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudFromDepthRGB(
const cv::Mat & imageRgb,
const cv::Mat & imageDepthIn,
const CameraModel & model,
int decimation,
float maxDepth,
float minDepth,
std::vector<int> * validIndices)
{
return cloudFromDepthRGB(
imageRgb,
imageDepthIn,
cv::Mat(),
model,
decimation,
maxDepth,
minDepth,
0,
validIndices);
}
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudFromDepthRGB( pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudFromDepthRGB(
const cv::Mat & imageRgb, const cv::Mat & imageRgb,
const cv::Mat & imageDepthIn, const cv::Mat & imageDepthIn,
const cv::Mat & imageDepthConfidenceIn,
const CameraModel & model, const CameraModel & model,
int decimation, int decimation,
float maxDepth, float maxDepth,
float minDepth, float minDepth,
unsigned char confidenceThr,
std::vector<int> * validIndices) std::vector<int> * validIndices)
{ {
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>); pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
@@ -449,6 +500,7 @@ pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudFromDepthRGB(
//UASSERT_MSG(imageRgb.rows % imageDepthIn.rows == 0 && imageRgb.cols % imageDepthIn.cols == 0, //UASSERT_MSG(imageRgb.rows % imageDepthIn.rows == 0 && imageRgb.cols % imageDepthIn.cols == 0,
// uFormat("rgb=%dx%d depth=%dx%d", imageRgb.cols, imageRgb.rows, imageDepthIn.cols, imageDepthIn.rows).c_str()); // uFormat("rgb=%dx%d depth=%dx%d", imageRgb.cols, imageRgb.rows, imageDepthIn.cols, imageDepthIn.rows).c_str());
UASSERT(!imageDepthIn.empty() && (imageDepthIn.type() == CV_16UC1 || imageDepthIn.type() == CV_32FC1)); UASSERT(!imageDepthIn.empty() && (imageDepthIn.type() == CV_16UC1 || imageDepthIn.type() == CV_32FC1));
UASSERT(imageDepthConfidenceIn.empty() || confidenceThr==0 || (imageDepthConfidenceIn.type() == CV_8UC1 && imageDepthConfidenceIn.size() == imageDepthIn.size()));
if(decimation < 0) if(decimation < 0)
{ {
if(imageRgb.rows % decimation != 0 || imageRgb.cols % decimation != 0) if(imageRgb.rows % decimation != 0 || imageRgb.cols % decimation != 0)
@@ -491,6 +543,7 @@ pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudFromDepthRGB(
} }
cv::Mat imageDepth = imageDepthIn; cv::Mat imageDepth = imageDepthIn;
cv::Mat imageDepthConfidence = confidenceThr==0?cv::Mat():imageDepthConfidenceIn;
if(decimation < 0) if(decimation < 0)
{ {
UDEBUG("Decimation from RGB image (%d)", decimation); UDEBUG("Decimation from RGB image (%d)", decimation);
@@ -502,6 +555,9 @@ pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudFromDepthRGB(
{ {
UDEBUG("Depth interpolation factor=%d", targetSize/imageDepthIn.rows); UDEBUG("Depth interpolation factor=%d", targetSize/imageDepthIn.rows);
imageDepth = util2d::interpolate(imageDepthIn, targetSize/imageDepthIn.rows); imageDepth = util2d::interpolate(imageDepthIn, targetSize/imageDepthIn.rows);
if(!imageDepthConfidence.empty()) {
imageDepthConfidence = util2d::interpolate(imageDepthConfidenceIn, targetSize/imageDepthConfidenceIn.rows);
}
decimation = 1; decimation = 1;
} }
else if(targetSize == imageDepthIn.rows) else if(targetSize == imageDepthIn.rows)
@@ -546,12 +602,14 @@ pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudFromDepthRGB(
float depthCx = model.cx() / rgbToDepthFactorX; float depthCx = model.cx() / rgbToDepthFactorX;
float depthCy = model.cy() / rgbToDepthFactorY; float depthCy = model.cy() / rgbToDepthFactorY;
UDEBUG("rgb=%dx%d depth=%dx%d fx=%f fy=%f cx=%f cy=%f (depth factors=%f %f) decimation=%d", UDEBUG("rgb=%dx%d depth=%dx%d fx=%f fy=%f cx=%f cy=%f (depth factors=%f %f) has confidence=%d (thr=%d) decimation=%d",
imageRgb.cols, imageRgb.rows, imageRgb.cols, imageRgb.rows,
imageDepth.cols, imageDepth.rows, imageDepth.cols, imageDepth.rows,
model.fx(), model.fy(), model.cx(), model.cy(), model.fx(), model.fy(), model.cx(), model.cy(),
rgbToDepthFactorX, rgbToDepthFactorX,
rgbToDepthFactorY, rgbToDepthFactorY,
imageDepthConfidenceIn.empty()?0:1,
(int)confidenceThr,
decimation); decimation);
int oi = 0; int oi = 0;
@@ -579,21 +637,21 @@ pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudFromDepthRGB(
pt.r = v; pt.r = v;
} }
pcl::PointXYZ ptXYZ = projectDepthTo3D(imageDepth, w, h, depthCx, depthCy, depthFx, depthFy, false); pt.x = pt.y = pt.z = std::numeric_limits<float>::quiet_NaN();
if (pcl::isFinite(ptXYZ) && ptXYZ.z >= minDepth && (maxDepth <= 0.0f || ptXYZ.z <= maxDepth)) if(imageDepthConfidence.empty() || imageDepthConfidence.at<unsigned char>(h,w) >= confidenceThr)
{ {
pt.x = ptXYZ.x; pcl::PointXYZ ptXYZ = projectDepthTo3D(imageDepth, w, h, depthCx, depthCy, depthFx, depthFy, false);
pt.y = ptXYZ.y; if (pcl::isFinite(ptXYZ) && ptXYZ.z >= minDepth && (maxDepth <= 0.0f || ptXYZ.z <= maxDepth))
pt.z = ptXYZ.z;
if (validIndices)
{ {
validIndices->at(oi) = (h / decimation)*cloud->width + (w / decimation); pt.x = ptXYZ.x;
pt.y = ptXYZ.y;
pt.z = ptXYZ.z;
if (validIndices)
{
validIndices->at(oi) = (h / decimation)*cloud->width + (w / decimation);
}
++oi;
} }
++oi;
}
else
{
pt.x = pt.y = pt.z = std::numeric_limits<float>::quiet_NaN();
} }
} }
} }
@@ -868,7 +926,8 @@ std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> cloudsFromSensorData(
float minDepth, float minDepth,
std::vector<pcl::IndicesPtr> * validIndices, std::vector<pcl::IndicesPtr> * validIndices,
const ParametersMap & stereoParameters, const ParametersMap & stereoParameters,
const std::vector<float> & roiRatios) const std::vector<float> & roiRatios,
unsigned char confidenceThr)
{ {
if(decimation == 0) if(decimation == 0)
{ {
@@ -881,6 +940,7 @@ std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> cloudsFromSensorData(
{ {
//depth //depth
UASSERT(int((sensorData.depthRaw().cols/sensorData.cameraModels().size())*sensorData.cameraModels().size()) == sensorData.depthRaw().cols); UASSERT(int((sensorData.depthRaw().cols/sensorData.cameraModels().size())*sensorData.cameraModels().size()) == sensorData.depthRaw().cols);
UASSERT(sensorData.depthConfidenceRaw().empty() || confidenceThr==0 || (sensorData.depthConfidenceRaw().type() == CV_8UC1 && sensorData.depthConfidenceRaw().cols == sensorData.depthRaw().cols && sensorData.depthConfidenceRaw().rows == sensorData.depthRaw().rows));
int subImageWidth = sensorData.depthRaw().cols/sensorData.cameraModels().size(); int subImageWidth = sensorData.depthRaw().cols/sensorData.cameraModels().size();
for(unsigned int i=0; i<sensorData.cameraModels().size(); ++i) for(unsigned int i=0; i<sensorData.cameraModels().size(); ++i)
{ {
@@ -892,6 +952,10 @@ std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> cloudsFromSensorData(
if(sensorData.cameraModels()[i].isValidForProjection()) if(sensorData.cameraModels()[i].isValidForProjection())
{ {
cv::Mat depth = cv::Mat(sensorData.depthRaw(), cv::Rect(subImageWidth*i, 0, subImageWidth, sensorData.depthRaw().rows)); cv::Mat depth = cv::Mat(sensorData.depthRaw(), cv::Rect(subImageWidth*i, 0, subImageWidth, sensorData.depthRaw().rows));
cv::Mat depthConfidence;
if(!sensorData.depthConfidenceRaw().empty() && confidenceThr > 0) {
depthConfidence = cv::Mat(sensorData.depthConfidenceRaw(), cv::Rect(subImageWidth*i, 0, subImageWidth, sensorData.depthConfidenceRaw().rows));
}
CameraModel model = sensorData.cameraModels()[i]; CameraModel model = sensorData.cameraModels()[i];
if( roiRatios.size() == 4 && if( roiRatios.size() == 4 &&
(roiRatios[0] > 0.0f || (roiRatios[0] > 0.0f ||
@@ -912,6 +976,9 @@ std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> cloudsFromSensorData(
roiRgb.height%decimation==0))) roiRgb.height%decimation==0)))
{ {
depth = cv::Mat(depth, roiDepth); depth = cv::Mat(depth, roiDepth);
if(!depthConfidence.empty()) {
depthConfidence = cv::Mat(depthConfidence, roiDepth);
}
if(model.imageWidth() != 0 && model.imageHeight() != 0) if(model.imageWidth() != 0 && model.imageHeight() != 0)
{ {
model = model.roi(util2d::computeRoi(model.imageSize(), roiRatios)); model = model.roi(util2d::computeRoi(model.imageSize(), roiRatios));
@@ -940,10 +1007,12 @@ std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> cloudsFromSensorData(
pcl::PointCloud<pcl::PointXYZ>::Ptr tmp = util3d::cloudFromDepth( pcl::PointCloud<pcl::PointXYZ>::Ptr tmp = util3d::cloudFromDepth(
depth, depth,
depthConfidence,
model, model,
decimation, decimation,
maxDepth, maxDepth,
minDepth, minDepth,
confidenceThr,
validIndices?validIndices->back().get():0); validIndices?validIndices->back().get():0);
if(tmp->size()) if(tmp->size())
@@ -1064,7 +1133,8 @@ pcl::PointCloud<pcl::PointXYZ>::Ptr cloudFromSensorData(
float minDepth, float minDepth,
std::vector<int> * validIndices, std::vector<int> * validIndices,
const ParametersMap & stereoParameters, const ParametersMap & stereoParameters,
const std::vector<float> & roiRatios) const std::vector<float> & roiRatios,
unsigned char confidenceThr)
{ {
std::vector<pcl::IndicesPtr> validIndicesV; std::vector<pcl::IndicesPtr> validIndicesV;
std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> clouds = cloudsFromSensorData( std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> clouds = cloudsFromSensorData(
@@ -1074,7 +1144,8 @@ pcl::PointCloud<pcl::PointXYZ>::Ptr cloudFromSensorData(
minDepth, minDepth,
validIndices?&validIndicesV:0, validIndices?&validIndicesV:0,
stereoParameters, stereoParameters,
roiRatios); roiRatios,
confidenceThr);
if(validIndices) if(validIndices)
{ {
@@ -1117,7 +1188,8 @@ std::vector<pcl::PointCloud<pcl::PointXYZRGB>::Ptr> cloudsRGBFromSensorData(
float minDepth, float minDepth,
std::vector<pcl::IndicesPtr> * validIndices, std::vector<pcl::IndicesPtr> * validIndices,
const ParametersMap & stereoParameters, const ParametersMap & stereoParameters,
const std::vector<float> & roiRatios) const std::vector<float> & roiRatios,
unsigned char confidenceThr)
{ {
if(decimation == 0) if(decimation == 0)
{ {
@@ -1136,6 +1208,7 @@ std::vector<pcl::PointCloud<pcl::PointXYZRGB>::Ptr> cloudsRGBFromSensorData(
//UASSERT_MSG(sensorData.imageRaw().rows % sensorData.depthRaw().rows == 0, uFormat("rgb=%d depth=%d", sensorData.imageRaw().rows, sensorData.depthRaw().rows).c_str()); //UASSERT_MSG(sensorData.imageRaw().rows % sensorData.depthRaw().rows == 0, uFormat("rgb=%d depth=%d", sensorData.imageRaw().rows, sensorData.depthRaw().rows).c_str());
int subRGBWidth = sensorData.imageRaw().cols/sensorData.cameraModels().size(); int subRGBWidth = sensorData.imageRaw().cols/sensorData.cameraModels().size();
int subDepthWidth = sensorData.depthRaw().cols/sensorData.cameraModels().size(); int subDepthWidth = sensorData.depthRaw().cols/sensorData.cameraModels().size();
UASSERT(sensorData.depthConfidenceRaw().empty() || confidenceThr==0 || (sensorData.depthConfidenceRaw().type() == CV_8UC1 && sensorData.depthConfidenceRaw().cols == sensorData.depthRaw().cols && sensorData.depthConfidenceRaw().rows == sensorData.depthRaw().rows));
for(unsigned int i=0; i<sensorData.cameraModels().size(); ++i) for(unsigned int i=0; i<sensorData.cameraModels().size(); ++i)
{ {
@@ -1148,6 +1221,10 @@ std::vector<pcl::PointCloud<pcl::PointXYZRGB>::Ptr> cloudsRGBFromSensorData(
{ {
cv::Mat rgb(sensorData.imageRaw(), cv::Rect(subRGBWidth*i, 0, subRGBWidth, sensorData.imageRaw().rows)); cv::Mat rgb(sensorData.imageRaw(), cv::Rect(subRGBWidth*i, 0, subRGBWidth, sensorData.imageRaw().rows));
cv::Mat depth(sensorData.depthRaw(), cv::Rect(subDepthWidth*i, 0, subDepthWidth, sensorData.depthRaw().rows)); cv::Mat depth(sensorData.depthRaw(), cv::Rect(subDepthWidth*i, 0, subDepthWidth, sensorData.depthRaw().rows));
cv::Mat depthConfidence;
if(!sensorData.depthConfidenceRaw().empty() && confidenceThr>0) {
depthConfidence = cv::Mat(sensorData.depthConfidenceRaw(), cv::Rect(subDepthWidth*i, 0, subDepthWidth, sensorData.depthConfidenceRaw().rows));
}
CameraModel model = sensorData.cameraModels()[i]; CameraModel model = sensorData.cameraModels()[i];
if( roiRatios.size() == 4 && if( roiRatios.size() == 4 &&
((roiRatios[0] > 0.0f && roiRatios[0] <= 1.0f) || ((roiRatios[0] > 0.0f && roiRatios[0] <= 1.0f) ||
@@ -1163,6 +1240,9 @@ std::vector<pcl::PointCloud<pcl::PointXYZRGB>::Ptr> cloudsRGBFromSensorData(
roiRgb.height%decimation==0) roiRgb.height%decimation==0)
{ {
depth = cv::Mat(depth, roiDepth); depth = cv::Mat(depth, roiDepth);
if(!depthConfidence.empty()) {
depthConfidence = cv::Mat(depthConfidence, roiDepth);
}
rgb = cv::Mat(rgb, roiRgb); rgb = cv::Mat(rgb, roiRgb);
model = model.roi(roiRgb); model = model.roi(roiRgb);
} }
@@ -1186,10 +1266,12 @@ std::vector<pcl::PointCloud<pcl::PointXYZRGB>::Ptr> cloudsRGBFromSensorData(
pcl::PointCloud<pcl::PointXYZRGB>::Ptr tmp = util3d::cloudFromDepthRGB( pcl::PointCloud<pcl::PointXYZRGB>::Ptr tmp = util3d::cloudFromDepthRGB(
rgb, rgb,
depth, depth,
depthConfidence,
model, model,
decimation, decimation,
maxDepth, maxDepth,
minDepth, minDepth,
confidenceThr,
validIndices?validIndices->back().get():0); validIndices?validIndices->back().get():0);
if(tmp->size()) if(tmp->size())
@@ -1292,7 +1374,8 @@ pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudRGBFromSensorData(
float minDepth, float minDepth,
std::vector<int> * validIndices, std::vector<int> * validIndices,
const ParametersMap & stereoParameters, const ParametersMap & stereoParameters,
const std::vector<float> & roiRatios) const std::vector<float> & roiRatios,
unsigned char confidenceThr)
{ {
std::vector<pcl::IndicesPtr> validIndicesV; std::vector<pcl::IndicesPtr> validIndicesV;
std::vector<pcl::PointCloud<pcl::PointXYZRGB>::Ptr> clouds = cloudsRGBFromSensorData( std::vector<pcl::PointCloud<pcl::PointXYZRGB>::Ptr> clouds = cloudsRGBFromSensorData(
@@ -1302,7 +1385,8 @@ pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudRGBFromSensorData(
minDepth, minDepth,
validIndices?&validIndicesV:0, validIndices?&validIndicesV:0,
stereoParameters, stereoParameters,
roiRatios); roiRatios,
confidenceThr);
if(validIndices) if(validIndices)
{ {
@@ -3149,6 +3233,18 @@ public:
float distance; float distance;
}; };
class RegisteredPoints {
public:
class Point {
public:
Point(float distance_, int index_) : distance(distance_), index(index_) {}
float distance;
int index;
};
float minDistance;
std::vector<Point> points;
};
/** /**
* For each point, return pixel of the best camera (NodeID->CameraIndex) * For each point, return pixel of the best camera (NodeID->CameraIndex)
* looking at it based on the policy and parameters * looking at it based on the policy and parameters
@@ -3160,6 +3256,7 @@ std::vector<std::pair< std::pair<int, int>, pcl::PointXY> > projectCloudToCamera
const std::map<int, std::vector<CameraModel> > & cameraModels, const std::map<int, std::vector<CameraModel> > & cameraModels,
float maxDistance, float maxDistance,
float maxAngle, float maxAngle,
float maxDepthError,
const std::vector<float> & roiRatios, const std::vector<float> & roiRatios,
const cv::Mat & projMask, const cv::Mat & projMask,
bool distanceToCamPolicy, bool distanceToCamPolicy,
@@ -3170,6 +3267,7 @@ std::vector<std::pair< std::pair<int, int>, pcl::PointXY> > projectCloudToCamera
UINFO("cameraModels=%d", (int)cameraModels.size()); UINFO("cameraModels=%d", (int)cameraModels.size());
UINFO("maxDistance=%f", maxDistance); UINFO("maxDistance=%f", maxDistance);
UINFO("maxAngle=%f", maxAngle); UINFO("maxAngle=%f", maxAngle);
UINFO("maxDepthError=%f", maxDepthError);
UINFO("distanceToCamPolicy=%s", distanceToCamPolicy?"true":"false"); UINFO("distanceToCamPolicy=%s", distanceToCamPolicy?"true":"false");
UINFO("roiRatios=%s", roiRatios.size() == 4?uFormat("%f %f %f %f", roiRatios[0], roiRatios[1], roiRatios[2], roiRatios[3]).c_str():""); UINFO("roiRatios=%s", roiRatios.size() == 4?uFormat("%f %f %f %f", roiRatios[0], roiRatios[1], roiRatios[2], roiRatios[3]).c_str():"");
UINFO("projMask=%dx%d", projMask.cols, projMask.rows); UINFO("projMask=%dx%d", projMask.cols, projMask.rows);
@@ -3235,8 +3333,9 @@ std::vector<std::pair< std::pair<int, int>, pcl::PointXY> > projectCloudToCamera
float cx = cameraMatrixK.at<double>(0,2); float cx = cameraMatrixK.at<double>(0,2);
float cy = cameraMatrixK.at<double>(1,2); float cy = cameraMatrixK.at<double>(1,2);
// depth: 2 channels UINT: [depthMM, indexPt] // [rows][cols][depth, indexPt]
cv::Mat registered = cv::Mat::zeros(imageSize, CV_32SC2); std::vector<std::vector<RegisteredPoints> > registered(
imageSize.height, std::vector<RegisteredPoints>(imageSize.width));
Transform t = cameraTransform.inverse(); Transform t = cameraTransform.inverse();
cv::Rect roi(0,0,imageSize.width, imageSize.height); cv::Rect roi(0,0,imageSize.width, imageSize.height);
@@ -3258,34 +3357,44 @@ std::vector<std::pair< std::pair<int, int>, pcl::PointXY> > projectCloudToCamera
if(z > 0.0f && (maxDistance<=0 || z<maxDistance)) if(z > 0.0f && (maxDistance<=0 || z<maxDistance))
{ {
float invZ = 1.0f/z; float invZ = 1.0f/z;
float dx = (fx*ptScan.x)*invZ + cx; float u = (fx*ptScan.x)*invZ + cx;
float dy = (fy*ptScan.y)*invZ + cy; float v = (fy*ptScan.y)*invZ + cy;
int dx_low = dx; int x = u + 0.5f;
int dy_low = dy; int y = v + 0.5f;
int dx_high = dx + 0.5f;
int dy_high = dy + 0.5f; if(uIsInBounds(x, roi.x, roi.x+roi.width) && uIsInBounds(y, roi.y, roi.y+roi.height) &&
int zMM = z * 1000; (validProjMask.empty() || validProjMask.at<unsigned char>(y, imageSize.width*camIndex+x) > 0)) {
if(uIsInBounds(dx_low, roi.x, roi.x+roi.width) && uIsInBounds(dy_low, roi.y, roi.y+roi.height) && RegisteredPoints &zReg = registered[y][x];
(validProjMask.empty() || validProjMask.at<unsigned char>(dy_low, imageSize.width*camIndex+dx_low) > 0)) if(zReg.points.empty()) {
{ zReg.minDistance = z;
set = true; zReg.points.push_back(RegisteredPoints::Point(z, i));
cv::Vec2i &zReg = registered.at<cv::Vec2i>(dy_low, dx_low); set = true;
if(zReg[0] == 0 || zMM < zReg[0])
{
zReg[0] = zMM;
zReg[1] = i;
} }
} else if(z < zReg.minDistance) {
if((dx_low != dx_high || dy_low != dy_high) && zReg.minDistance = z;
uIsInBounds(dx_high, roi.x, roi.x+roi.width) && uIsInBounds(dy_high, roi.y, roi.y+roi.height) && if(maxDepthError<=0.0f) {
(validProjMask.empty() || validProjMask.at<unsigned char>(dy_high, imageSize.width*camIndex+dx_high) > 0)) // keeping only closest point, just update it
{ zReg.points[0].distance = z;
set = true; zReg.points[0].index = i;
cv::Vec2i &zReg = registered.at<cv::Vec2i>(dy_high, dx_high); }
if(zReg[0] == 0 || zMM < zReg[0]) else {
{ // update the points attached to same pixel based on new closest distance
zReg[0] = zMM; std::vector<RegisteredPoints::Point> reOrderedPts;
zReg[1] = i; reOrderedPts.push_back(RegisteredPoints::Point(z, i));
for(size_t p=0; p<zReg.points.size(); ++p) {
if(zReg.points[p].distance - z < maxDepthError) {
reOrderedPts.push_back(zReg.points[p]);
}
}
zReg.points = reOrderedPts;
}
set = true;
}
else if(maxDepthError>=0.0f && z - zReg.minDistance < maxDepthError) {
// The point is closer than current closest one to camera,
// but still under max depth difference, just append
zReg.points.push_back(RegisteredPoints::Point(z, i));
set = true;
} }
} }
} }
@@ -3296,19 +3405,19 @@ std::vector<std::pair< std::pair<int, int>, pcl::PointXY> > projectCloudToCamera
} }
if(count == 0) if(count == 0)
{ {
registered = cv::Mat(); registered.clear();
UINFO("No points projected in camera %d/%d", pter->first, camIndex); UINFO("No points projected in camera %d/%d", pter->first, camIndex);
} }
else else
{ {
UDEBUG("%d points projected in camera %d/%d", count, pter->first, camIndex); UDEBUG("%d points projected in camera %d/%d", count, pter->first, camIndex);
} }
for(int u=0; u<registered.cols; ++u) for(int u=0; u<imageSize.width; ++u)
{ {
for(int v=0; v<registered.rows; ++v) for(int v=0; v<imageSize.height; ++v)
{ {
cv::Vec2i &zReg = registered.at<cv::Vec2i>(v, u); RegisteredPoints &zReg = registered[v][u];
if(zReg[0] > 0) if(!zReg.points.empty())
{ {
ProjectionInfo info; ProjectionInfo info;
info.nodeID = pter->first; info.nodeID = pter->first;
@@ -3316,36 +3425,40 @@ std::vector<std::pair< std::pair<int, int>, pcl::PointXY> > projectCloudToCamera
info.uv.x = float(u)/float(imageSize.width); info.uv.x = float(u)/float(imageSize.width);
info.uv.y = float(v)/float(imageSize.height); info.uv.y = float(v)/float(imageSize.height);
const Transform & cam = cameraPoses.at(info.nodeID); const Transform & cam = cameraPoses.at(info.nodeID);
const PointT & pt = cloud.at(zReg[1]); for(size_t p=0; p<zReg.points.size(); ++p)
Eigen::Vector4f camDir(cam.x()-pt.x, cam.y()-pt.y, cam.z()-pt.z, 0);
Eigen::Vector4f normal(pt.normal_x, pt.normal_y, pt.normal_z, 0);
float angleToCam = maxAngle<=0?0:pcl::getAngle3D(normal, camDir);
float distanceToCam = zReg[0]/1000.0f;
if( (maxAngle<=0 || (camDir.dot(normal) > 0 && angleToCam < maxAngle)) && // is facing camera? is point normal perpendicular to camera?
(maxDistance<=0 || distanceToCam<maxDistance)) // is point not too far from camera?
{ {
float vx = info.uv.x-0.5f; int ptIdx = zReg.points[p].index;
float vy = info.uv.y-0.5f; const PointT & pt = cloud.at(ptIdx);
Eigen::Vector4f camDir(cam.x()-pt.x, cam.y()-pt.y, cam.z()-pt.z, 0);
float distanceToCenter = vx*vx+vy*vy; Eigen::Vector4f normal(pt.normal_x, pt.normal_y, pt.normal_z, 0);
float distance = distanceToCenter; float angleToCam = maxAngle<=0?0:pcl::getAngle3D(normal, camDir);
if(distanceToCamPolicy) float distanceToCam = zReg.points[p].distance;
if( (maxAngle<=0 || (camDir.dot(normal) > 0 && angleToCam < maxAngle)) && // is facing camera? is point normal perpendicular to camera?
(maxDistance<=0 || distanceToCam<maxDistance)) // is point not too far from camera?
{ {
distance = distanceToCam; float vx = info.uv.x-0.5f;
} float vy = info.uv.y-0.5f;
info.distance = distance; float distanceToCenter = vx*vx+vy*vy;
float distance = distanceToCenter;
if(invertedIndex[zReg[1]].distance != -1.0f) if(distanceToCamPolicy)
{
if(distance <= invertedIndex[zReg[1]].distance)
{ {
invertedIndex[zReg[1]] = info; distance = distanceToCam;
}
info.distance = distance;
if(invertedIndex[ptIdx].distance != -1.0f)
{
if(distance <= invertedIndex[ptIdx].distance)
{
invertedIndex[ptIdx] = info;
}
}
else
{
invertedIndex[ptIdx] = info;
} }
}
else
{
invertedIndex[zReg[1]] = info;
} }
} }
} }
@@ -3415,6 +3528,7 @@ std::vector<std::pair< std::pair<int, int>, pcl::PointXY> > projectCloudToCamera
const std::map<int, std::vector<CameraModel> > & cameraModels, const std::map<int, std::vector<CameraModel> > & cameraModels,
float maxDistance, float maxDistance,
float maxAngle, float maxAngle,
float maxDepthError,
const std::vector<float> & roiRatios, const std::vector<float> & roiRatios,
const cv::Mat & projMask, const cv::Mat & projMask,
bool distanceToCamPolicy, bool distanceToCamPolicy,
@@ -3425,6 +3539,7 @@ std::vector<std::pair< std::pair<int, int>, pcl::PointXY> > projectCloudToCamera
cameraModels, cameraModels,
maxDistance, maxDistance,
maxAngle, maxAngle,
maxDepthError,
roiRatios, roiRatios,
projMask, projMask,
distanceToCamPolicy, distanceToCamPolicy,
@@ -3437,6 +3552,7 @@ std::vector<std::pair< std::pair<int, int>, pcl::PointXY> > projectCloudToCamera
const std::map<int, std::vector<CameraModel> > & cameraModels, const std::map<int, std::vector<CameraModel> > & cameraModels,
float maxDistance, float maxDistance,
float maxAngle, float maxAngle,
float maxDepthError,
const std::vector<float> & roiRatios, const std::vector<float> & roiRatios,
const cv::Mat & projMask, const cv::Mat & projMask,
bool distanceToCamPolicy, bool distanceToCamPolicy,
@@ -3447,6 +3563,7 @@ std::vector<std::pair< std::pair<int, int>, pcl::PointXY> > projectCloudToCamera
cameraModels, cameraModels,
maxDistance, maxDistance,
maxAngle, maxAngle,
maxDepthError,
roiRatios, roiRatios,
projMask, projMask,
distanceToCamPolicy, distanceToCamPolicy,
+1 -4
View File
@@ -781,10 +781,7 @@ pcl::TextureMesh::Ptr createTextureMesh(
pcl::TextureMapping<pcl::PointXYZ> tm; // TextureMapping object that will perform the sort pcl::TextureMapping<pcl::PointXYZ> tm; // TextureMapping object that will perform the sort
tm.setMaxDistance(maxDistance); tm.setMaxDistance(maxDistance);
tm.setMaxAngle(maxAngle); tm.setMaxAngle(maxAngle);
if(maxDepthError > 0.0f) tm.setMaxDepthError(maxDepthError);
{
tm.setMaxDepthError(maxDepthError);
}
tm.setMinClusterSize(minClusterSize); tm.setMinClusterSize(minClusterSize);
if(tm.textureMeshwithMultipleCameras2(*textureMesh, cameras, state, vertexToPixels, distanceToCamPolicy)) if(tm.textureMeshwithMultipleCameras2(*textureMesh, cameras, state, vertexToPixels, distanceToCamPolicy))
{ {
+2 -2
View File
@@ -46,7 +46,7 @@ RUN git clone https://github.com/laurentkneip/opengv.git && \
mkdir build && \ mkdir build && \
cd build && \ cd build && \
~/cmake -DCMAKE_BUILD_TYPE=Release .. && \ ~/cmake -DCMAKE_BUILD_TYPE=Release .. && \
make -j$(nproc) && \ make -j4 && \
make install && \ make install && \
cd && \ cd && \
rm -r opengv rm -r opengv
@@ -63,7 +63,7 @@ COPY . /root/rtabmap
RUN source /ros_entrypoint.sh && \ RUN source /ros_entrypoint.sh && \
cd rtabmap/build && \ cd rtabmap/build && \
~/cmake -DWITH_OPENGV=ON .. && \ ~/cmake -DWITH_OPENGV=ON .. && \
make -j$(nproc) && \ make -j4 && \
make install && \ make install && \
cd ../.. && \ cd ../.. && \
rm -rf rtabmap && \ rm -rf rtabmap && \
+1 -17
View File
@@ -2,22 +2,6 @@
FROM introlab3it/rtabmap:focal-deps FROM introlab3it/rtabmap:focal-deps
# June 19 2023: moved opengv here so that focal-deps can be built on my computer. Not sure why but on my machine opengv arm64 fails, but not on CI.
#commit Aug 6 2020
RUN apt-get update && apt install wget && apt-get clean && rm -rf /var/lib/apt/lists/
RUN git clone https://github.com/laurentkneip/opengv.git && \
cd opengv && \
git checkout 91f4b19c73450833a40e463ad3648aae80b3a7f3 && \
wget https://gist.githubusercontent.com/matlabbe/a412cf7c4627253874f81a00745a7fbb/raw/accc3acf465d1ffd0304a46b17741f62d4d354ef/opengv_disable_march_native.patch && \
git apply opengv_disable_march_native.patch && \
mkdir build && \
cd build && \
cmake -DCMAKE_BUILD_TYPE=Release .. && \
make -j$(nproc) && \
make install && \
cd && \
rm -r opengv
# Will be used to read/store databases on host # Will be used to read/store databases on host
RUN mkdir -p /root/Documents/RTAB-Map && chmod 777 /root/Documents/RTAB-Map RUN mkdir -p /root/Documents/RTAB-Map && chmod 777 /root/Documents/RTAB-Map
@@ -28,7 +12,7 @@ COPY . /root/rtabmap
RUN source /ros_entrypoint.sh && \ RUN source /ros_entrypoint.sh && \
cd rtabmap/build && \ cd rtabmap/build && \
cmake -DWITH_ALICE_VISION=ON -DWITH_OPENGV=ON .. && \ cmake -DWITH_ALICE_VISION=ON -DWITH_OPENGV=ON .. && \
make -j$(nproc) && \ make -j4 && \
make install && \ make install && \
cd ../.. && \ cd ../.. && \
rm -rf rtabmap && \ rm -rf rtabmap && \
+30 -9
View File
@@ -10,6 +10,13 @@ ENV DEBIAN_FRONTEND=noninteractive
WORKDIR /root/ WORKDIR /root/
# issue: https://github.com/introlab/rtabmap/issues/1523
RUN rm /etc/apt/sources.list.d/ros1-latest.list && \
apt-get update && apt-get install -y curl && \
sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list' && \
curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | sudo apt-key add - && \
apt-get clean && rm -rf /var/lib/apt/lists/
# Install build dependencies # Install build dependencies
RUN if [ "$TARGETPLATFORM" = "linux/arm/v7" ]; then \ RUN if [ "$TARGETPLATFORM" = "linux/arm/v7" ]; then \
apt-get update && \ apt-get update && \
@@ -29,7 +36,7 @@ RUN if [ "$TARGETPLATFORM" = "linux/arm/v7" ]; then \
export CFLAGS="-D_FILE_OFFSET_BITS=64" && \ export CFLAGS="-D_FILE_OFFSET_BITS=64" && \
export CXXFLAGS="-D_FILE_OFFSET_BITS=64" && \ export CXXFLAGS="-D_FILE_OFFSET_BITS=64" && \
./bootstrap && \ ./bootstrap && \
make -j$(nproc) && \ make -j4 && \
sudo make install && \ sudo make install && \
cd .. && \ cd .. && \
cmake --version && \ cmake --version && \
@@ -52,7 +59,7 @@ RUN apt-get update && apt-get install -y ros-noetic-librealsense2 && \
# Taken from https://github.com/microsoft/Azure-Kinect-Sensor-SDK/issues/1190#issuecomment-822772494 # Taken from https://github.com/microsoft/Azure-Kinect-Sensor-SDK/issues/1190#issuecomment-822772494
# K4A binaries on 20.04 not released yet, we should take those from 18.04 # K4A binaries on 20.04 not released yet, we should take those from 18.04
RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then echo "Installing k4a..." && \ RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then echo "Installing k4a..." && \
apt-get update && apt-get install -y curl && \ apt-get update && \
echo "Download libk4a1.3_1.3.0_amd64.deb..." && \ echo "Download libk4a1.3_1.3.0_amd64.deb..." && \
curl -sSL https://packages.microsoft.com/ubuntu/18.04/prod/pool/main/libk/libk4a1.3/libk4a1.3_1.3.0_amd64.deb > /tmp/libk4a1.3_1.3.0_amd64.deb && \ curl -sSL https://packages.microsoft.com/ubuntu/18.04/prod/pool/main/libk/libk4a1.3/libk4a1.3_1.3.0_amd64.deb > /tmp/libk4a1.3_1.3.0_amd64.deb && \
echo "Download libk4a1.3-dev_1.3.0_amd64.deb..." && \ echo "Download libk4a1.3-dev_1.3.0_amd64.deb..." && \
@@ -84,7 +91,7 @@ RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then echo "Installing libfreenect2
mkdir build && \ mkdir build && \
cd build && \ cd build && \
cmake .. && \ cmake .. && \
make -j$(nproc) && \ make -j4 && \
make install && \ make install && \
cd && \ cd && \
rm -r libfreenect2; fi rm -r libfreenect2; fi
@@ -98,7 +105,7 @@ RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then echo "Installing zed-open-cap
mkdir build && \ mkdir build && \
cd build && \ cd build && \
cmake .. && \ cmake .. && \
make -j$(nproc) && \ make -j4 && \
make install && \ make install && \
cd && \ cd && \
rm -r zed-open-capture; fi rm -r zed-open-capture; fi
@@ -117,7 +124,7 @@ RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then git clone https://github.com/
mkdir build && \ mkdir build && \
cd build && \ cd build && \
cmake -DUSE_PYTHON=OFF -DOIIO_BUILD_TESTS=OFF -DOIIO_BUILD_TOOLS=OFF .. && \ cmake -DUSE_PYTHON=OFF -DOIIO_BUILD_TESTS=OFF -DOIIO_BUILD_TOOLS=OFF .. && \
make -j$(nproc) && \ make -j4 && \
make install && \ make install && \
cd && \ cd && \
rm -r oiio; fi rm -r oiio; fi
@@ -127,7 +134,7 @@ RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then git clone https://github.com/
mkdir build && \ mkdir build && \
cd build && \ cd build && \
cmake .. && \ cmake .. && \
make -j$(nproc) && \ make -j4 && \
make install && \ make install && \
cd && \ cd && \
rm -r assimp; fi rm -r assimp; fi
@@ -140,7 +147,7 @@ RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then git clone https://github.com/
git apply geogram_8b2ae61.patch && \ git apply geogram_8b2ae61.patch && \
./configure.sh && \ ./configure.sh && \
cd build/Linux64-gcc-dynamic-Release && \ cd build/Linux64-gcc-dynamic-Release && \
make -j$(nproc) && \ make -j4 && \
make install && \ make install && \
cd && \ cd && \
rm -r geogram; fi rm -r geogram; fi
@@ -153,7 +160,7 @@ RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then git clone https://github.com/
mkdir build && \ mkdir build && \
cd build && \ cd build && \
cmake -DALICEVISION_USE_CUDA=OFF -DALICEVISION_USE_APRILTAG=OFF -DALICEVISION_BUILD_SOFTWARE=OFF .. && \ cmake -DALICEVISION_USE_CUDA=OFF -DALICEVISION_USE_APRILTAG=OFF -DALICEVISION_BUILD_SOFTWARE=OFF .. && \
make -j$(nproc) && \ make -j4 && \
make install && \ make install && \
cd && \ cd && \
rm -r AliceVision; fi rm -r AliceVision; fi
@@ -164,11 +171,25 @@ RUN git clone --branch 4.2.0 https://github.com/opencv/opencv.git && \
mkdir build && \ mkdir build && \
cd build && \ cd build && \
cmake -DWITH_TBB=ON -DWITH_OPENMP=ON -DBUILD_opencv_python3=OFF -DBUILD_opencv_python_bindings_generator=OFF -DBUILD_opencv_python_tests=OFF -DBUILD_PERF_TESTS=OFF -DBUILD_TESTS=OFF -DOPENCV_ENABLE_NONFREE=ON -DWITH_VTK=OFF -DOPENCV_EXTRA_MODULES_PATH=/root/opencv_contrib/modules .. && \ cmake -DWITH_TBB=ON -DWITH_OPENMP=ON -DBUILD_opencv_python3=OFF -DBUILD_opencv_python_bindings_generator=OFF -DBUILD_opencv_python_tests=OFF -DBUILD_PERF_TESTS=OFF -DBUILD_TESTS=OFF -DOPENCV_ENABLE_NONFREE=ON -DWITH_VTK=OFF -DOPENCV_EXTRA_MODULES_PATH=/root/opencv_contrib/modules .. && \
make -j$(nproc) && \ make -j4 && \
make install && \ make install && \
cd ../.. && \ cd ../.. && \
rm -rf opencv opencv_contrib rm -rf opencv opencv_contrib
RUN if [ "$TARGETPLATFORM" = "linux/arm64" ]; then apt-get update && apt install wget && apt-get clean && rm -rf /var/lib/apt/lists/; fi
RUN git clone https://github.com/laurentkneip/opengv.git && \
cd opengv && \
git checkout 91f4b19c73450833a40e463ad3648aae80b3a7f3 && \
wget https://gist.githubusercontent.com/matlabbe/a412cf7c4627253874f81a00745a7fbb/raw/accc3acf465d1ffd0304a46b17741f62d4d354ef/opengv_disable_march_native.patch && \
git apply opengv_disable_march_native.patch && \
mkdir build && \
cd build && \
cmake -DCMAKE_BUILD_TYPE=Release .. && \
make -j4 && \
make install && \
cd && \
rm -r opengv
RUN rm /bin/sh && ln -s /bin/bash /bin/sh RUN rm /bin/sh && ln -s /bin/bash /bin/sh
# for jetson (https://github.com/introlab/rtabmap/issues/776) # for jetson (https://github.com/introlab/rtabmap/issues/776)
+1 -1
View File
@@ -12,7 +12,7 @@ COPY . /root/rtabmap
RUN source /ros_entrypoint.sh && \ RUN source /ros_entrypoint.sh && \
cd rtabmap/build && \ cd rtabmap/build && \
cmake -DWITH_OPENGV=ON .. && \ cmake -DWITH_OPENGV=ON .. && \
make -j$(nproc) && \ make -j4 && \
make install && \ make install && \
cd ../.. && \ cd ../.. && \
rm -rf rtabmap && \ rm -rf rtabmap && \
+5 -5
View File
@@ -49,7 +49,7 @@ RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then echo "Installing libfreenect2
mkdir build && \ mkdir build && \
cd build && \ cd build && \
cmake .. && \ cmake .. && \
make -j$(nproc) && \ make -j2 && \
make install && \ make install && \
cd && \ cd && \
rm -r libfreenect2; fi rm -r libfreenect2; fi
@@ -63,7 +63,7 @@ RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then echo "Installing zed-open-cap
mkdir build && \ mkdir build && \
cd build && \ cd build && \
cmake .. && \ cmake .. && \
make -j$(nproc) && \ make -j2 && \
make install && \ make install && \
cd && \ cd && \
rm -r zed-open-capture; fi rm -r zed-open-capture; fi
@@ -74,7 +74,7 @@ RUN git clone --branch 4.5.4 https://github.com/opencv/opencv.git && \
mkdir build && \ mkdir build && \
cd build && \ cd build && \
cmake -DWITH_TBB=ON -DWITH_OPENMP=ON -DBUILD_opencv_python3=OFF -DBUILD_opencv_python_bindings_generator=OFF -DBUILD_opencv_python_tests=OFF -DBUILD_PERF_TESTS=OFF -DBUILD_TESTS=OFF -DOPENCV_ENABLE_NONFREE=ON -DOPENCV_EXTRA_MODULES_PATH=/root/opencv_contrib/modules .. && \ cmake -DWITH_TBB=ON -DWITH_OPENMP=ON -DBUILD_opencv_python3=OFF -DBUILD_opencv_python_bindings_generator=OFF -DBUILD_opencv_python_tests=OFF -DBUILD_PERF_TESTS=OFF -DBUILD_TESTS=OFF -DOPENCV_ENABLE_NONFREE=ON -DOPENCV_EXTRA_MODULES_PATH=/root/opencv_contrib/modules .. && \
make -j$(nproc) && \ make -j2 && \
make install && \ make install && \
cd ../.. && \ cd ../.. && \
rm -rf opencv opencv_contrib rm -rf opencv opencv_contrib
@@ -90,14 +90,14 @@ RUN git clone https://github.com/laurentkneip/opengv.git && \
mkdir build && \ mkdir build && \
cd build && \ cd build && \
cmake -DCMAKE_BUILD_TYPE=Release .. && \ cmake -DCMAKE_BUILD_TYPE=Release .. && \
make -j$(nproc) && \ make -j2 && \
make install && \ make install && \
cd && \ cd && \
rm -r opengv rm -r opengv
RUN rm /bin/sh && ln -s /bin/bash /bin/sh RUN rm /bin/sh && ln -s /bin/bash /bin/sh
COPY ./docker/jammy/deps/ros_entrypoint.sh /ros_entrypoint.sh RUN echo -e '#!/bin/bash\nset -e\n\n# setup ros2 environment\nsource "/opt/ros/humble/setup.bash" --\nexec "$@"' > /ros_entrypoint.sh
RUN chmod +x /ros_entrypoint.sh RUN chmod +x /ros_entrypoint.sh
ENTRYPOINT [ "/ros_entrypoint.sh" ] ENTRYPOINT [ "/ros_entrypoint.sh" ]
-6
View File
@@ -1,6 +0,0 @@
#!/bin/bash
set -e
# setup ros2 environment
source "/opt/ros/humble/setup.bash" --
exec "$@"
+20
View File
@@ -0,0 +1,20 @@
# Image: introlab3it/rtabmap:noble-kilted
FROM introlab3it/rtabmap:noble-kilted-deps
# Will be used to read/store databases on host
RUN mkdir -p /root/Documents/RTAB-Map && chmod 777 /root/Documents/RTAB-Map
# Copy current source code
COPY . /root/rtabmap
# Build RTAB-Map project
RUN source /ros_entrypoint.sh && \
cd rtabmap/build && \
cmake -DWITH_OPENGV=ON .. && \
make -j4 && \
make install && \
cd ../.. && \
rm -rf rtabmap && \
ldconfig
+132
View File
@@ -0,0 +1,132 @@
# Image: introlab3it/rtabmap:noble-kilted-deps
FROM ubuntu:24.04
ARG TARGETPLATFORM
ENV TARGETPLATFORM=${TARGETPLATFORM:-linux/amd64}
RUN echo "I am building for $TARGETPLATFORM"
ENV DEBIAN_FRONTEND=noninteractive
# Install ROS2
RUN apt update && \
apt install software-properties-common -y && \
add-apt-repository universe && \
apt update && \
apt install curl -y && \
curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg && \
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" | tee /etc/apt/sources.list.d/ros2.list > /dev/null && \
apt-get clean && rm -rf /var/lib/apt/lists/
# Install build dependencies
RUN apt-get update && \
apt upgrade -y && \
apt-get install -y \
git \
wget \
libtbb-dev \
libproj-dev \
libpcl-dev \
liboctomap-dev \
libfreenect-dev \
ros-kilted-ros-base \
ros-dev-tools \
ros-kilted-cv-bridge \
ros-kilted-image-geometry \
ros-kilted-laser-geometry \
ros-kilted-pcl-conversions \
ros-kilted-rviz-common \
ros-kilted-rviz-rendering \
ros-kilted-rviz-default-plugins \
ros-kilted-pcl-ros \
ros-kilted-imu-filter-madgwick \
ros-kilted-velodyne \
ros-kilted-image-transport \
ros-kilted-octomap-msgs \
ros-kilted-libg2o \
ros-kilted-libpointmatcher \
ros-kilted-qt-gui-cpp \
ros-kilted-diagnostic-updater && \
apt-get clean && rm -rf /var/lib/apt/lists/
WORKDIR /root/
# GTSAM (we cannot use ros-kilted-gtsam on Noble because it is linked to a different internal Eigen version than system one)
RUN git clone https://github.com/borglab/gtsam.git && \
cd gtsam && \
git checkout 4.2.0 && \
mkdir build && \
cd build && \
cmake -DCMAKE_BUILD_TYPE=Release -DGTSAM_BUILD_WITH_MARCH_NATIVE=OFF -DGTSAM_USE_SYSTEM_EIGEN=ON .. && \
make -j4 && \
make install && \
cd && \
rm -r gtsam
# libfreenect2
RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then echo "Installing libfreenect2..." && \
apt-get update && apt-get install -y mesa-utils xserver-xorg-video-all libusb-1.0-0-dev libturbojpeg0-dev libglfw3-dev && \
apt-get clean && rm -rf /var/lib/apt/lists/ && \
git clone https://github.com/OpenKinect/libfreenect2 && \
cd libfreenect2 && \
mkdir build && \
cd build && \
cmake -DCMAKE_BUILD_TYPE=Release .. && \
make -j4 && \
make install && \
cd && \
rm -r libfreenect2; fi
# zed open capture
RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then echo "Installing zed-open-capture..." && \
apt-get update && apt install -y libusb-1.0-0-dev libhidapi-libusb0 libhidapi-dev wget && \
apt-get clean && rm -rf /var/lib/apt/lists/ && \
git clone https://github.com/stereolabs/zed-open-capture.git && \
cd zed-open-capture && \
mkdir build && \
cd build && \
cmake -DCMAKE_BUILD_TYPE=Release .. && \
make -j4 && \
make install && \
cd && \
rm -r zed-open-capture; fi
# OpenCV with all modules (same version than distro version to avoid conflicts with cv_bridge ros package)
RUN git clone --branch 4.6.0 https://github.com/opencv/opencv.git && \
git clone --branch 4.6.0 https://github.com/opencv/opencv_contrib.git && \
cd opencv && \
sed -i '/#include <libavformat\/avformat.h>/i #include <libavcodec/version.h>' modules/videoio/src/ffmpeg_codecs.hpp && \
mkdir build && \
cd build && \
cmake -DCMAKE_BUILD_TYPE=Release -DWITH_TBB=ON -DWITH_ADE=OFF -DWITH_OPENMP=ON -DBUILD_opencv_python3=OFF -DBUILD_opencv_python_bindings_generator=OFF -DBUILD_opencv_python_tests=OFF -DBUILD_PERF_TESTS=OFF -DBUILD_TESTS=OFF -DOPENCV_ENABLE_NONFREE=ON -DOPENCV_EXTRA_MODULES_PATH=/root/opencv_contrib/modules .. && \
make -j4 && \
make install && \
cd ../.. && \
rm -rf opencv opencv_contrib
RUN git clone https://github.com/laurentkneip/opengv.git && \
cd opengv && \
git checkout 91f4b19c73450833a40e463ad3648aae80b3a7f3 && \
wget https://gist.githubusercontent.com/matlabbe/a412cf7c4627253874f81a00745a7fbb/raw/accc3acf465d1ffd0304a46b17741f62d4d354ef/opengv_disable_march_native.patch && \
git apply opengv_disable_march_native.patch && \
mkdir build && \
cd build && \
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTS=OFF .. && \
make -j4 && \
make install && \
cd && \
rm -r opengv
RUN rm /bin/sh && ln -s /bin/bash /bin/sh
RUN echo -e '#!/bin/bash\nset -e\n\n# setup ros2 environment\nsource "/opt/ros/kilted/setup.bash" --\nexec "$@"' > /ros_entrypoint.sh
RUN chmod +x /ros_entrypoint.sh
ENTRYPOINT [ "/ros_entrypoint.sh" ]
# ros2 seems not sourcing by default its multi-arch folders
ENV LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/ros/kilted/lib/x86_64-linux-gnu:/opt/ros/kilted/lib/aarch64-linux-gnu
# for jetson (https://github.com/introlab/rtabmap/issues/776)
ENV LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/aarch64-linux-gnu/tegra
+1 -15
View File
@@ -2,20 +2,6 @@
FROM introlab3it/rtabmap:noble-deps FROM introlab3it/rtabmap:noble-deps
# OpenGV (issue seg fault on my computer, moved here from noble-deps to be built on ci)
RUN git clone https://github.com/laurentkneip/opengv.git && \
cd opengv && \
git checkout 91f4b19c73450833a40e463ad3648aae80b3a7f3 && \
wget https://gist.githubusercontent.com/matlabbe/a412cf7c4627253874f81a00745a7fbb/raw/accc3acf465d1ffd0304a46b17741f62d4d354ef/opengv_disable_march_native.patch && \
git apply opengv_disable_march_native.patch && \
mkdir build && \
cd build && \
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTS=OFF .. && \
make -j$(nproc) && \
make install && \
cd && \
rm -r opengv
# Will be used to read/store databases on host # Will be used to read/store databases on host
RUN mkdir -p /root/Documents/RTAB-Map && chmod 777 /root/Documents/RTAB-Map RUN mkdir -p /root/Documents/RTAB-Map && chmod 777 /root/Documents/RTAB-Map
@@ -26,7 +12,7 @@ COPY . /root/rtabmap
RUN source /ros_entrypoint.sh && \ RUN source /ros_entrypoint.sh && \
cd rtabmap/build && \ cd rtabmap/build && \
cmake -DWITH_OPENGV=ON .. && \ cmake -DWITH_OPENGV=ON .. && \
make -j$(nproc) && \ make -j4 && \
make install && \ make install && \
cd ../.. && \ cd ../.. && \
rm -rf rtabmap && \ rm -rf rtabmap && \
+19 -8
View File
@@ -58,7 +58,7 @@ RUN git clone https://github.com/borglab/gtsam.git && \
mkdir build && \ mkdir build && \
cd build && \ cd build && \
cmake -DCMAKE_BUILD_TYPE=Release -DGTSAM_BUILD_WITH_MARCH_NATIVE=OFF -DGTSAM_USE_SYSTEM_EIGEN=ON .. && \ cmake -DCMAKE_BUILD_TYPE=Release -DGTSAM_BUILD_WITH_MARCH_NATIVE=OFF -DGTSAM_USE_SYSTEM_EIGEN=ON .. && \
make -j$(nproc) && \ make -j4 && \
make install && \ make install && \
cd && \ cd && \
rm -r gtsam rm -r gtsam
@@ -72,7 +72,7 @@ RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then echo "Installing libfreenect2
mkdir build && \ mkdir build && \
cd build && \ cd build && \
cmake -DCMAKE_BUILD_TYPE=Release .. && \ cmake -DCMAKE_BUILD_TYPE=Release .. && \
make -j$(nproc) && \ make -j4 && \
make install && \ make install && \
cd && \ cd && \
rm -r libfreenect2; fi rm -r libfreenect2; fi
@@ -86,29 +86,40 @@ RUN if [ "$TARGETPLATFORM" = "linux/amd64" ]; then echo "Installing zed-open-cap
mkdir build && \ mkdir build && \
cd build && \ cd build && \
cmake -DCMAKE_BUILD_TYPE=Release .. && \ cmake -DCMAKE_BUILD_TYPE=Release .. && \
make -j$(nproc) && \ make -j4 && \
make install && \ make install && \
cd && \ cd && \
rm -r zed-open-capture; fi rm -r zed-open-capture; fi
# OpenCV with all modules (same version than distro version to avoid conflicts with cv_bridge ros package) # OpenCV with all modules (same version than distro version to avoid conflicts with cv_bridge ros package)
COPY ./docker/noble/deps/opencv_4_6_0_ffmpeg.patch .
RUN git clone --branch 4.6.0 https://github.com/opencv/opencv.git && \ RUN git clone --branch 4.6.0 https://github.com/opencv/opencv.git && \
git clone --branch 4.6.0 https://github.com/opencv/opencv_contrib.git && \ git clone --branch 4.6.0 https://github.com/opencv/opencv_contrib.git && \
mv opencv_4_6_0_ffmpeg.patch opencv/. && \
cd opencv && \ cd opencv && \
git apply opencv_4_6_0_ffmpeg.patch && \ sed -i '/#include <libavformat\/avformat.h>/i #include <libavcodec/version.h>' modules/videoio/src/ffmpeg_codecs.hpp && \
mkdir build && \ mkdir build && \
cd build && \ cd build && \
cmake -DCMAKE_BUILD_TYPE=Release -DWITH_TBB=ON -DWITH_ADE=OFF -DWITH_OPENMP=ON -DBUILD_opencv_python3=OFF -DBUILD_opencv_python_bindings_generator=OFF -DBUILD_opencv_python_tests=OFF -DBUILD_PERF_TESTS=OFF -DBUILD_TESTS=OFF -DOPENCV_ENABLE_NONFREE=ON -DOPENCV_EXTRA_MODULES_PATH=/root/opencv_contrib/modules .. && \ cmake -DCMAKE_BUILD_TYPE=Release -DWITH_TBB=ON -DWITH_ADE=OFF -DWITH_OPENMP=ON -DBUILD_opencv_python3=OFF -DBUILD_opencv_python_bindings_generator=OFF -DBUILD_opencv_python_tests=OFF -DBUILD_PERF_TESTS=OFF -DBUILD_TESTS=OFF -DOPENCV_ENABLE_NONFREE=ON -DOPENCV_EXTRA_MODULES_PATH=/root/opencv_contrib/modules .. && \
make -j$(nproc) && \ make -j4 && \
make install && \ make install && \
cd ../.. && \ cd ../.. && \
rm -rf opencv opencv_contrib rm -rf opencv opencv_contrib
RUN git clone https://github.com/laurentkneip/opengv.git && \
cd opengv && \
git checkout 91f4b19c73450833a40e463ad3648aae80b3a7f3 && \
wget https://gist.githubusercontent.com/matlabbe/a412cf7c4627253874f81a00745a7fbb/raw/accc3acf465d1ffd0304a46b17741f62d4d354ef/opengv_disable_march_native.patch && \
git apply opengv_disable_march_native.patch && \
mkdir build && \
cd build && \
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTS=OFF .. && \
make -j4 && \
make install && \
cd && \
rm -r opengv
RUN rm /bin/sh && ln -s /bin/bash /bin/sh RUN rm /bin/sh && ln -s /bin/bash /bin/sh
COPY ./docker/noble/deps/ros_entrypoint.sh /ros_entrypoint.sh RUN echo -e '#!/bin/bash\nset -e\n\n# setup ros2 environment\nsource "/opt/ros/jazzy/setup.bash" --\nexec "$@"' > /ros_entrypoint.sh
RUN chmod +x /ros_entrypoint.sh RUN chmod +x /ros_entrypoint.sh
ENTRYPOINT [ "/ros_entrypoint.sh" ] ENTRYPOINT [ "/ros_entrypoint.sh" ]
@@ -1,12 +0,0 @@
diff --git a/modules/videoio/src/ffmpeg_codecs.hpp b/modules/videoio/src/ffmpeg_codecs.hpp
index 61788e0345..faad2596ed 100644
--- a/modules/videoio/src/ffmpeg_codecs.hpp
+++ b/modules/videoio/src/ffmpeg_codecs.hpp
@@ -60,6 +60,7 @@ extern "C" {
#include <errno.h>
#endif
+#include <libavcodec/version.h>
#include <libavformat/avformat.h>
#ifdef __cplusplus
-6
View File
@@ -1,6 +0,0 @@
#!/bin/bash
set -e
# setup ros2 environment
source "/opt/ros/jazzy/setup.bash" --
exec "$@"
+2 -1
View File
@@ -256,7 +256,8 @@ int main(int argc, char * argv[])
node.sensorData(), node.sensorData(),
4, // image decimation before creating the clouds 4, // image decimation before creating the clouds
4.0f, // maximum depth of the cloud 4.0f, // maximum depth of the cloud
0.0f); 0.0f,
0);
pcl::PointCloud<pcl::PointXYZRGB>::Ptr tmpNoNaN(new pcl::PointCloud<pcl::PointXYZRGB>); pcl::PointCloud<pcl::PointXYZRGB>::Ptr tmpNoNaN(new pcl::PointCloud<pcl::PointXYZRGB>);
std::vector<int> index; std::vector<int> index;
pcl::removeNaNFromPointCloud(*tmp, *tmpNoNaN, index); pcl::removeNaNFromPointCloud(*tmp, *tmpNoNaN, index);
+4 -2
View File
@@ -65,6 +65,8 @@ class ExportCloudsDialog;
class EditDepthArea; class EditDepthArea;
class EditMapArea; class EditMapArea;
class LinkRefiningDialog; class LinkRefiningDialog;
class Registration;
class RegistrationIcp;
class RTABMAP_GUI_EXPORT DatabaseViewer : public QMainWindow class RTABMAP_GUI_EXPORT DatabaseViewer : public QMainWindow
{ {
@@ -202,8 +204,8 @@ private:
void updateLoopClosuresSlider(int from = 0, int to = 0); void updateLoopClosuresSlider(int from = 0, int to = 0);
void updateCovariances(const QList<Link> & links); void updateCovariances(const QList<Link> & links);
void refineLinks(const QList<Link> & links); void refineLinks(const QList<Link> & links);
void refineConstraint(int from, int to, bool silent); void refineConstraint(int from, int to, Registration * reg, RegistrationIcp * regIcp, bool silent);
bool addConstraint(int from, int to, bool silent, bool silentlyUseOptimizedGraphAsGuess = false); bool addConstraint(int from, int to, Registration * reg, bool silent, bool silentlyUseOptimizedGraphAsGuess = false);
void exportPoses(int format); void exportPoses(int format);
void exportGPS(int format); void exportGPS(int format);
+8 -2
View File
@@ -60,6 +60,7 @@ public:
QRectF sceneRect() const; QRectF sceneRect() const;
bool isImageShown() const; bool isImageShown() const;
bool isImageDepthShown() const; bool isImageDepthShown() const;
bool isImageDepthConfidenceShown() const;
bool isFeaturesShown() const; bool isFeaturesShown() const;
bool isLinesShown() const; bool isLinesShown() const;
int getAlpha() const {return _alpha;} int getAlpha() const {return _alpha;}
@@ -82,6 +83,7 @@ public:
void setFeaturesShown(bool shown); void setFeaturesShown(bool shown);
void setImageShown(bool shown); void setImageShown(bool shown);
void setImageDepthShown(bool shown); void setImageDepthShown(bool shown);
void setImageDepthConfidenceShown(bool shown);
void setLinesShown(bool shown); void setLinesShown(bool shown);
void setGraphicsViewMode(bool on); void setGraphicsViewMode(bool on);
void setGraphicsViewScaled(bool scaled); void setGraphicsViewScaled(bool scaled);
@@ -98,8 +100,8 @@ public:
void addFeature(int id, const cv::KeyPoint & kpt, float depth, QColor color); void addFeature(int id, const cv::KeyPoint & kpt, float depth, QColor color);
void addLine(float x1, float y1, float x2, float y2, QColor color, const QString & text = QString()); void addLine(float x1, float y1, float x2, float y2, QColor color, const QString & text = QString());
void setImage(const QImage & image, const std::vector<CameraModel> & models = std::vector<CameraModel>(), const Transform & pose = Transform()); void setImage(const QImage & image, const std::vector<CameraModel> & models = std::vector<CameraModel>(), const Transform & pose = Transform());
void setImageDepth(const cv::Mat & imageDepth); void setImageDepth(const cv::Mat & imageDepth, const cv::Mat & imageDepthConfidence = cv::Mat());
void setImageDepth(const QImage & image); void setImageDepth(const QImage & image, const QImage & imageDepthConfidence = QImage());
void setFeatureColor(int id, QColor color); void setFeatureColor(int id, QColor color);
void setFeaturesColor(QColor color); void setFeaturesColor(QColor color);
void setAlpha(int alpha); void setAlpha(int alpha);
@@ -147,6 +149,7 @@ private:
QMenu * _menu; QMenu * _menu;
QAction * _showImage; QAction * _showImage;
QAction * _showImageDepth; QAction * _showImageDepth;
QAction * _showImageDepthConfidence;
QAction * _showFeatures; QAction * _showFeatures;
QAction * _showLines; QAction * _showLines;
QAction * _setFeatureColor; QAction * _setFeatureColor;
@@ -175,9 +178,12 @@ private:
QList<QGraphicsLineItem*> _lines; QList<QGraphicsLineItem*> _lines;
QGraphicsPixmapItem * _imageItem; QGraphicsPixmapItem * _imageItem;
QGraphicsPixmapItem * _imageDepthItem; QGraphicsPixmapItem * _imageDepthItem;
QGraphicsPixmapItem * _imageDepthConfidenceItem;
QPixmap _image; QPixmap _image;
QPixmap _imageDepth; QPixmap _imageDepth;
QPixmap _imageDepthConfidence;
cv::Mat _imageDepthCv; cv::Mat _imageDepthCv;
cv::Mat _imageDepthConfidenceCv;
std::vector<CameraModel> _models; std::vector<CameraModel> _models;
Transform _pose; Transform _pose;
}; };
@@ -208,6 +208,7 @@ public:
double getCloudMaxDepth(int index) const; // 0=map, 1=odom double getCloudMaxDepth(int index) const; // 0=map, 1=odom
double getCloudMinDepth(int index) const; // 0=map, 1=odom double getCloudMinDepth(int index) const; // 0=map, 1=odom
std::vector<float> getCloudRoiRatios(int index) const; // 0=map, 1=odom std::vector<float> getCloudRoiRatios(int index) const; // 0=map, 1=odom
unsigned char getCloudConfidenceThr(int index) const; // 0=map, 1=odom
int getCloudColorScheme(int index) const; // 0=map, 1=odom int getCloudColorScheme(int index) const; // 0=map, 1=odom
double getCloudOpacity(int index) const; // 0=map, 1=odom double getCloudOpacity(int index) const; // 0=map, 1=odom
int getCloudPointSize(int index) const; // 0=map, 1=odom int getCloudPointSize(int index) const; // 0=map, 1=odom
@@ -466,6 +467,7 @@ private:
QVector<QDoubleSpinBox*> _3dRenderingMaxDepth; QVector<QDoubleSpinBox*> _3dRenderingMaxDepth;
QVector<QDoubleSpinBox*> _3dRenderingMinDepth; QVector<QDoubleSpinBox*> _3dRenderingMinDepth;
QVector<QLineEdit*> _3dRenderingRoiRatios; QVector<QLineEdit*> _3dRenderingRoiRatios;
QVector<QSpinBox*> _3dRenderingDepthConfidenceThr;
QVector<QSpinBox*> _3dRenderingColorScheme; QVector<QSpinBox*> _3dRenderingColorScheme;
QVector<QDoubleSpinBox*> _3dRenderingOpacity; QVector<QDoubleSpinBox*> _3dRenderingOpacity;
QVector<QSpinBox*> _3dRenderingPtSize; QVector<QSpinBox*> _3dRenderingPtSize;
+25 -4
View File
@@ -39,7 +39,7 @@ enum uCvQtDepthColorMap{
* depth (float32, uint16) image and RGB/BGR 8bits images. * depth (float32, uint16) image and RGB/BGR 8bits images.
* @param image the cv::Mat image (can be 1 channel [CV_8U, CV_16U or CV_32F] or 3 channels [CV_U8]) * @param image the cv::Mat image (can be 1 channel [CV_8U, CV_16U or CV_32F] or 3 channels [CV_U8])
* @param isBgr if 3 channels, it is BGR or RGB order. * @param isBgr if 3 channels, it is BGR or RGB order.
* @param colorMap gradient of color to use to visualize depth * @param colorMap gradient of color to use to visualize depth or monochrome images
* @param depthMin fixed minimum range (m) of the depth gradient (if depthMax<=depthMin, max/min are computed based on data in depth image) * @param depthMin fixed minimum range (m) of the depth gradient (if depthMax<=depthMin, max/min are computed based on data in depth image)
* @param depthMax fixed maximum range (m) of the depth gradient (if depthMax<=depthMin, max/min are computed based on data in depth image) * @param depthMax fixed maximum range (m) of the depth gradient (if depthMax<=depthMin, max/min are computed based on data in depth image)
* @return the QImage * @return the QImage
@@ -47,7 +47,7 @@ enum uCvQtDepthColorMap{
inline QImage uCvMat2QImage( inline QImage uCvMat2QImage(
const cv::Mat & image, const cv::Mat & image,
bool isBgr = true, bool isBgr = true,
uCvQtDepthColorMap colorMap = uCvQtDepthWhiteToBlack, uCvQtDepthColorMap colorMap = uCvQtDepthBlackToWhite,
float depthMin = 0, float depthMin = 0,
float depthMax = 0) float depthMax = 0)
{ {
@@ -81,9 +81,30 @@ inline QImage uCvMat2QImage(
{ {
// mono grayscale // mono grayscale
qtemp = QImage(image.data, image.cols, image.rows, image.cols, QImage::Format_Indexed8).copy(); qtemp = QImage(image.data, image.cols, image.rows, image.cols, QImage::Format_Indexed8).copy();
QVector<QRgb> my_table; QVector<QRgb> my_table;
for(int i = 0; i < 256; i++) my_table.reserve(256);
my_table.push_back(qRgb(i,i,i)); if(colorMap == uCvQtDepthRedToBlue || colorMap == uCvQtDepthBlueToRed)
{
if(colorMap == uCvQtDepthBlueToRed) {
for(int i = 0; i < 256; i++)
my_table.push_back(QColor::fromHsv(255-i, 255, 255, 255).rgb());
}
else {
for(int i = 0; i < 256; i++)
my_table.push_back(QColor::fromHsv(i, 255, 255, 255).rgb());
}
}
else if(colorMap == uCvQtDepthBlackToWhite)
{
for(int i = 0; i < 256; i++)
my_table.push_back(qRgb(i,i,i));
}
else // uCvQtDepthWhiteToBlack
{
for(int i = 0; i < 256; i++)
my_table.push_back(qRgb(255-i,255-i,255-i));
}
qtemp.setColorTable(my_table); qtemp.setColorTable(my_table);
} }
else else
+6 -2
View File
@@ -156,8 +156,12 @@ void DataRecorder::addData(const rtabmap::SensorData & data, const Transform & p
void DataRecorder::showImage(const cv::Mat & image, const cv::Mat & depth) void DataRecorder::showImage(const cv::Mat & image, const cv::Mat & depth)
{ {
processingImages_ = true; processingImages_ = true;
imageView_->setImage(uCvMat2QImage(image)); if(!image.empty()) {
imageView_->setImageDepth(depth); imageView_->setImage(uCvMat2QImage(image));
}
if(!depth.empty()) {
imageView_->setImageDepth(depth);
}
label_->setText(tr("Images=%1 (~%2 MB)").arg(count_).arg(totalSizeKB_/1000)); label_->setText(tr("Images=%1 (~%2 MB)").arg(count_).arg(totalSizeKB_/1000));
processingImages_ = false; processingImages_ = false;
} }
+102 -22
View File
@@ -427,6 +427,10 @@ DatabaseViewer::DatabaseViewer(const QString & ini, QWidget * parent) :
connect(ui_->checkBox_showDisparityInsteadOfRight, SIGNAL(stateChanged(int)), this, SLOT(update3dView())); connect(ui_->checkBox_showDisparityInsteadOfRight, SIGNAL(stateChanged(int)), this, SLOT(update3dView()));
connect(ui_->spinBox_decimation, SIGNAL(valueChanged(int)), this, SLOT(updateConstraintView())); connect(ui_->spinBox_decimation, SIGNAL(valueChanged(int)), this, SLOT(updateConstraintView()));
connect(ui_->spinBox_decimation, SIGNAL(valueChanged(int)), this, SLOT(update3dView())); connect(ui_->spinBox_decimation, SIGNAL(valueChanged(int)), this, SLOT(update3dView()));
connect(ui_->spinBox_depthConfidence, SIGNAL(valueChanged(int)), this, SLOT(updateConstraintView()));
connect(ui_->spinBox_depthConfidence, SIGNAL(valueChanged(int)), this, SLOT(update3dView()));
connect(ui_->doubleSpinBox_depthEdgeBleedingError, SIGNAL(valueChanged(double)), this, SLOT(updateConstraintView()));
connect(ui_->doubleSpinBox_depthEdgeBleedingError, SIGNAL(valueChanged(double)), this, SLOT(update3dView()));
connect(ui_->groupBox_posefiltering, SIGNAL(clicked(bool)), this, SLOT(updateGraphView())); connect(ui_->groupBox_posefiltering, SIGNAL(clicked(bool)), this, SLOT(updateGraphView()));
connect(ui_->doubleSpinBox_posefilteringRadius, SIGNAL(editingFinished()), this, SLOT(updateGraphView())); connect(ui_->doubleSpinBox_posefilteringRadius, SIGNAL(editingFinished()), this, SLOT(updateGraphView()));
connect(ui_->doubleSpinBox_posefilteringAngle, SIGNAL(editingFinished()), this, SLOT(updateGraphView())); connect(ui_->doubleSpinBox_posefilteringAngle, SIGNAL(editingFinished()), this, SLOT(updateGraphView()));
@@ -457,6 +461,8 @@ DatabaseViewer::DatabaseViewer(const QString & ini, QWidget * parent) :
connect(ui_->checkBox_cameraProjection, SIGNAL(stateChanged(int)), this, SLOT(configModified())); connect(ui_->checkBox_cameraProjection, SIGNAL(stateChanged(int)), this, SLOT(configModified()));
connect(ui_->checkBox_showDisparityInsteadOfRight, SIGNAL(stateChanged(int)), this, SLOT(configModified())); connect(ui_->checkBox_showDisparityInsteadOfRight, SIGNAL(stateChanged(int)), this, SLOT(configModified()));
connect(ui_->spinBox_decimation, SIGNAL(valueChanged(int)), this, SLOT(configModified())); connect(ui_->spinBox_decimation, SIGNAL(valueChanged(int)), this, SLOT(configModified()));
connect(ui_->spinBox_depthConfidence, SIGNAL(valueChanged(int)), this, SLOT(configModified()));
connect(ui_->doubleSpinBox_depthEdgeBleedingError, SIGNAL(valueChanged(double)), this, SLOT(configModified()));
connect(ui_->groupBox_posefiltering, SIGNAL(clicked(bool)), this, SLOT(configModified())); connect(ui_->groupBox_posefiltering, SIGNAL(clicked(bool)), this, SLOT(configModified()));
connect(ui_->doubleSpinBox_posefilteringRadius, SIGNAL(valueChanged(double)), this, SLOT(configModified())); connect(ui_->doubleSpinBox_posefilteringRadius, SIGNAL(valueChanged(double)), this, SLOT(configModified()));
connect(ui_->doubleSpinBox_posefilteringAngle, SIGNAL(valueChanged(double)), this, SLOT(configModified())); connect(ui_->doubleSpinBox_posefilteringAngle, SIGNAL(valueChanged(double)), this, SLOT(configModified()));
@@ -616,6 +622,8 @@ void DatabaseViewer::readSettings()
ui_->doubleSpinBox_gainCompensationRadius->setValue(settings.value("gainCompensationRadius", ui_->doubleSpinBox_gainCompensationRadius->value()).toDouble()); ui_->doubleSpinBox_gainCompensationRadius->setValue(settings.value("gainCompensationRadius", ui_->doubleSpinBox_gainCompensationRadius->value()).toDouble());
ui_->doubleSpinBox_voxelSize->setValue(settings.value("voxelSize", ui_->doubleSpinBox_voxelSize->value()).toDouble()); ui_->doubleSpinBox_voxelSize->setValue(settings.value("voxelSize", ui_->doubleSpinBox_voxelSize->value()).toDouble());
ui_->spinBox_decimation->setValue(settings.value("decimation", ui_->spinBox_decimation->value()).toInt()); ui_->spinBox_decimation->setValue(settings.value("decimation", ui_->spinBox_decimation->value()).toInt());
ui_->spinBox_depthConfidence->setValue(settings.value("depth_confidence_thr", ui_->spinBox_depthConfidence->value()).toInt());
ui_->doubleSpinBox_depthEdgeBleedingError->setValue(settings.value("depth_bleeding_error", ui_->doubleSpinBox_depthEdgeBleedingError->value()).toDouble());
ui_->checkBox_cameraProjection->setChecked(settings.value("camProj", ui_->checkBox_cameraProjection->isChecked()).toBool()); ui_->checkBox_cameraProjection->setChecked(settings.value("camProj", ui_->checkBox_cameraProjection->isChecked()).toBool());
ui_->checkBox_showDisparityInsteadOfRight->setChecked(settings.value("showDisp", ui_->checkBox_showDisparityInsteadOfRight->isChecked()).toBool()); ui_->checkBox_showDisparityInsteadOfRight->setChecked(settings.value("showDisp", ui_->checkBox_showDisparityInsteadOfRight->isChecked()).toBool());
settings.endGroup(); settings.endGroup();
@@ -707,6 +715,8 @@ void DatabaseViewer::writeSettings()
settings.setValue("gainCompensationRadius", ui_->doubleSpinBox_gainCompensationRadius->value()); settings.setValue("gainCompensationRadius", ui_->doubleSpinBox_gainCompensationRadius->value());
settings.setValue("voxelSize", ui_->doubleSpinBox_voxelSize->value()); settings.setValue("voxelSize", ui_->doubleSpinBox_voxelSize->value());
settings.setValue("decimation", ui_->spinBox_decimation->value()); settings.setValue("decimation", ui_->spinBox_decimation->value());
settings.setValue("depth_confidence", ui_->spinBox_depthConfidence->value());
settings.setValue("depth_bleeding_error", ui_->doubleSpinBox_depthEdgeBleedingError->value());
settings.setValue("camProj", ui_->checkBox_cameraProjection->isChecked()); settings.setValue("camProj", ui_->checkBox_cameraProjection->isChecked());
settings.setValue("showDisp", ui_->checkBox_showDisparityInsteadOfRight->isChecked()); settings.setValue("showDisp", ui_->checkBox_showDisparityInsteadOfRight->isChecked());
settings.endGroup(); settings.endGroup();
@@ -801,6 +811,8 @@ void DatabaseViewer::restoreDefaultSettings()
ui_->doubleSpinBox_gainCompensationRadius->setValue(0.0); ui_->doubleSpinBox_gainCompensationRadius->setValue(0.0);
ui_->doubleSpinBox_voxelSize->setValue(0.0); ui_->doubleSpinBox_voxelSize->setValue(0.0);
ui_->spinBox_decimation->setValue(1); ui_->spinBox_decimation->setValue(1);
ui_->spinBox_depthConfidence->setValue(0);
ui_->doubleSpinBox_depthEdgeBleedingError->setValue(0.0);
ui_->checkBox_cameraProjection->setChecked(false); ui_->checkBox_cameraProjection->setChecked(false);
ui_->checkBox_showDisparityInsteadOfRight->setChecked(false); ui_->checkBox_showDisparityInsteadOfRight->setChecked(false);
@@ -1584,6 +1596,11 @@ void DatabaseViewer::extractImages()
dir.mkdir(QString("%1/rgb").arg(path)); dir.mkdir(QString("%1/rgb").arg(path));
dir.mkdir(QString("%1/depth").arg(path)); dir.mkdir(QString("%1/depth").arg(path));
dir.mkdir(QString("%1/calib").arg(path)); dir.mkdir(QString("%1/calib").arg(path));
if(!data.depthConfidenceRaw().empty())
{
dir.mkdir(QString("%1/confidence").arg(path));
directoriesCreated = true;
}
directoriesCreated = true; directoriesCreated = true;
} }
} }
@@ -1668,7 +1685,14 @@ void DatabaseViewer::extractImages()
UWARN("Failed saving \"%s\"", QString("%1/rgb/%2.%3").arg(path).arg(id).arg(ext).toStdString().c_str()); UWARN("Failed saving \"%s\"", QString("%1/rgb/%2.%3").arg(path).arg(id).arg(ext).toStdString().c_str());
if(!cv::imwrite(QString("%1/depth/%2.png").arg(path).arg(id).toStdString(), data.depthRaw().type()==CV_32FC1?util2d::cvtDepthFromFloat(data.depthRaw()):data.depthRaw())) if(!cv::imwrite(QString("%1/depth/%2.png").arg(path).arg(id).toStdString(), data.depthRaw().type()==CV_32FC1?util2d::cvtDepthFromFloat(data.depthRaw()):data.depthRaw()))
UWARN("Failed saving \"%s\"", QString("%1/depth/%2.png").arg(path).arg(id).toStdString().c_str()); UWARN("Failed saving \"%s\"", QString("%1/depth/%2.png").arg(path).arg(id).toStdString().c_str());
UINFO(QString("Saved rgb/%1.%2 and depth/%1.png").arg(id).arg(ext).toStdString().c_str()); if(data.depthConfidenceRaw().empty()) {
UINFO(QString("Saved rgb/%1.%2 and depth/%1.png").arg(id).arg(ext).toStdString().c_str());
}
else {
if(!cv::imwrite(QString("%1/confidence/%2.png").arg(path).arg(id).toStdString(), data.depthConfidenceRaw()))
UWARN("Failed saving \"%s\"", QString("%1/confidence/%2.png").arg(path).arg(id).toStdString().c_str());
UINFO(QString("Saved rgb/%1.%2, depth/%1.png and confidence/%1.png").arg(id).arg(ext).toStdString().c_str());
}
} }
else else
{ {
@@ -4263,6 +4287,8 @@ void DatabaseViewer::detectMoreLoopClosures()
return; return;
} }
std::shared_ptr<Registration> reg(Registration::create(ui_->parameters_toolbox->getParameters()));
for(int n=0; n<iterations; ++n) for(int n=0; n<iterations; ++n)
{ {
UINFO("iteration %d/%d", n+1, iterations); UINFO("iteration %d/%d", n+1, iterations);
@@ -4310,7 +4336,7 @@ void DatabaseViewer::detectMoreLoopClosures()
delta.getNorm() >= ui_->doubleSpinBox_detectMore_radiusMin->value()) delta.getNorm() >= ui_->doubleSpinBox_detectMore_radiusMin->value())
{ {
checkedLoopClosures.insert(std::make_pair(from, to)); checkedLoopClosures.insert(std::make_pair(from, to));
if(addConstraint(from, to, true, useOptimizedGraphAsGuess)) if(addConstraint(from, to, reg.get(), true, useOptimizedGraphAsGuess))
{ {
UINFO("Added new loop closure between %d and %d.", from, to); UINFO("Added new loop closure between %d and %d.", from, to);
++added; ++added;
@@ -4568,13 +4594,16 @@ void DatabaseViewer::refineLinks(const QList<Link> & links)
progressDialog->setMinimumWidth(800); progressDialog->setMinimumWidth(800);
progressDialog->show(); progressDialog->show();
RegistrationIcp regProximity(ui_->parameters_toolbox->getParameters());
std::shared_ptr<Registration> reg(Registration::create(ui_->parameters_toolbox->getParameters()));
for(int i=0; i<links.size(); ++i) for(int i=0; i<links.size(); ++i)
{ {
int from = links[i].from(); int from = links[i].from();
int to = links[i].to(); int to = links[i].to();
if(from > 0 && to > 0) if(from > 0 && to > 0)
{ {
this->refineConstraint(links[i].from(), links[i].to(), true); this->refineConstraint(links[i].from(), links[i].to(), reg.get(), &regProximity, true);
progressDialog->appendText(tr("Refined link %1->%2 (%3/%4)").arg(from).arg(to).arg(i+1).arg(links.size())); progressDialog->appendText(tr("Refined link %1->%2 (%3/%4)").arg(from).arg(to).arg(i+1).arg(links.size()));
} }
else else
@@ -4802,7 +4831,7 @@ void DatabaseViewer::update(int value,
if(!imgDepth.empty()) if(!imgDepth.empty())
{ {
view->setImageDepth(imgDepth); view->setImageDepth(imgDepth, data.depthConfidenceRaw());
if(img.isNull()) if(img.isNull())
{ {
rect.setWidth(imgDepth.cols); rect.setWidth(imgDepth.cols);
@@ -5261,6 +5290,12 @@ void DatabaseViewer::update(int value,
{ {
if(!data.depthOrRightRaw().empty()) if(!data.depthOrRightRaw().empty())
{ {
if(!data.depthRaw().empty() && ui_->doubleSpinBox_depthEdgeBleedingError->value() > 0.0) {
cv::Mat depth = data.depthRaw();
util2d::depthBleedingFiltering(depth, ui_->doubleSpinBox_depthEdgeBleedingError->value());
data.setRGBDImage(data.imageRaw(), depth, data.depthConfidenceRaw(), data.cameraModels());
}
if(!data.imageRaw().empty()) if(!data.imageRaw().empty())
{ {
std::vector<pcl::PointCloud<pcl::PointXYZRGB>::Ptr> clouds; std::vector<pcl::PointCloud<pcl::PointXYZRGB>::Ptr> clouds;
@@ -5276,8 +5311,13 @@ void DatabaseViewer::update(int value,
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud = util3d::cloudFromDepthRGB( pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud = util3d::cloudFromDepthRGB(
data.imageRaw(), data.imageRaw(),
depth, depth,
data.depthConfidenceRaw(),
data.cameraModels()[0], data.cameraModels()[0],
ui_->spinBox_decimation->value(),0,0,indices.get()); ui_->spinBox_decimation->value(),
0,
0,
(unsigned char)ui_->spinBox_depthConfidence->value(),
indices.get());
if(indices->size()) if(indices->size())
{ {
clouds.push_back(util3d::transformPointCloud(cloud, data.cameraModels()[0].localTransform())); clouds.push_back(util3d::transformPointCloud(cloud, data.cameraModels()[0].localTransform()));
@@ -5286,7 +5326,14 @@ void DatabaseViewer::update(int value,
} }
else else
{ {
clouds = util3d::cloudsRGBFromSensorData(data, ui_->spinBox_decimation->value(), 0, 0, &allIndices, ui_->parameters_toolbox->getParameters()); clouds = util3d::cloudsRGBFromSensorData(
data,
ui_->spinBox_decimation->value(),
0,
0,
&allIndices,
ui_->parameters_toolbox->getParameters(),std::vector<float>(),
(unsigned char)ui_->spinBox_depthConfidence->value());
} }
UASSERT(clouds.size() == allIndices.size()); UASSERT(clouds.size() == allIndices.size());
for(size_t i=0; i<allIndices.size(); ++i) for(size_t i=0; i<allIndices.size(); ++i)
@@ -5361,7 +5408,14 @@ void DatabaseViewer::update(int value,
std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> clouds; std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> clouds;
std::vector<pcl::IndicesPtr> allIndices; std::vector<pcl::IndicesPtr> allIndices;
clouds = util3d::cloudsFromSensorData(data, ui_->spinBox_decimation->value(), 0, 0, &allIndices, ui_->parameters_toolbox->getParameters()); clouds = util3d::cloudsFromSensorData(
data,
ui_->spinBox_decimation->value(),
0,
0,
&allIndices, ui_->parameters_toolbox->getParameters(),
std::vector<float>(),
(unsigned char)ui_->spinBox_depthConfidence->value());
UASSERT(clouds.size() == allIndices.size()); UASSERT(clouds.size() == allIndices.size());
for(size_t i=0; i<allIndices.size(); ++i) for(size_t i=0; i<allIndices.size(); ++i)
{ {
@@ -6353,11 +6407,12 @@ void DatabaseViewer::updateConstraintView(
ui_->checkBox_showOptimized->setEnabled(true); ui_->checkBox_showOptimized->setEnabled(true);
Transform topt = iterFrom->second.inverse()*iterTo->second; Transform topt = iterFrom->second.inverse()*iterTo->second;
float diff = topt.getDistance(t); float diff = topt.getDistance(t);
Transform v1 = t.rotation()*Transform(1,0,0,0,0,0); Transform v1 = t.rotation()*Transform(1,0,0,0,0,0);
Transform v2 = topt.rotation()*Transform(1,0,0,0,0,0); Transform v2 = topt.rotation()*Transform(1,0,0,0,0,0);
float a = pcl::getAngle3D(Eigen::Vector4f(v1.x(), v1.y(), v1.z(), 0), Eigen::Vector4f(v2.x(), v2.y(), v2.z(), 0)); float a = pcl::getAngle3D(Eigen::Vector4f(v1.x(), v1.y(), v1.z(), 0), Eigen::Vector4f(v2.x(), v2.y(), v2.z(), 0));
a = (a *180.0f) / CV_PI; a = (a *180.0f) / CV_PI;
ui_->label_constraint_opt->setText(QString("%1\n(error=%2% a=%3)").arg(QString(topt.prettyPrint().c_str()).replace(" ", "\n")).arg((t.getNorm()>0?diff/t.getNorm():0)*100.0f).arg(a)); ui_->label_constraint_opt->setText(QString("%1\n(error=%2% a=%3 deg)").arg(QString(topt.prettyPrint().c_str()).replace(" ", "\n")).arg((t.getNorm()>0?diff/t.getNorm():0)*100.0f).arg(a));
if(ui_->checkBox_showOptimized->isChecked()) if(ui_->checkBox_showOptimized->isChecked())
{ {
@@ -6488,11 +6543,37 @@ void DatabaseViewer::updateConstraintView(
pcl::IndicesPtr indicesTo(new std::vector<int>); pcl::IndicesPtr indicesTo(new std::vector<int>);
if(!dataFrom.imageRaw().empty() && !dataFrom.depthOrRightRaw().empty()) if(!dataFrom.imageRaw().empty() && !dataFrom.depthOrRightRaw().empty())
{ {
cloudFrom=util3d::cloudRGBFromSensorData(dataFrom, ui_->spinBox_decimation->value(), 0, 0, indicesFrom.get(), ui_->parameters_toolbox->getParameters()); if(!dataFrom.depthRaw().empty() && ui_->doubleSpinBox_depthEdgeBleedingError->value() > 0.0) {
cv::Mat depth = dataFrom.depthRaw();
util2d::depthBleedingFiltering(depth, ui_->doubleSpinBox_depthEdgeBleedingError->value());
dataFrom.setRGBDImage(dataFrom.imageRaw(), depth, dataFrom.depthConfidenceRaw(), dataFrom.cameraModels());
}
cloudFrom=util3d::cloudRGBFromSensorData(
dataFrom,
ui_->spinBox_decimation->value(),
0,
0,
indicesFrom.get(),
ui_->parameters_toolbox->getParameters(),
std::vector<float>(),
(unsigned char)ui_->spinBox_depthConfidence->value());
} }
if(!dataTo.imageRaw().empty() && !dataTo.depthOrRightRaw().empty()) if(!dataTo.imageRaw().empty() && !dataTo.depthOrRightRaw().empty())
{ {
cloudTo=util3d::cloudRGBFromSensorData(dataTo, ui_->spinBox_decimation->value(), 0, 0, indicesTo.get(), ui_->parameters_toolbox->getParameters()); if(!dataTo.depthRaw().empty() && ui_->doubleSpinBox_depthEdgeBleedingError->value() > 0.0) {
cv::Mat depth = dataTo.depthRaw();
util2d::depthBleedingFiltering(depth, ui_->doubleSpinBox_depthEdgeBleedingError->value());
dataTo.setRGBDImage(dataTo.imageRaw(), depth, dataTo.depthConfidenceRaw(), dataTo.cameraModels());
}
cloudTo=util3d::cloudRGBFromSensorData(
dataTo,
ui_->spinBox_decimation->value(),
0,
0,
indicesTo.get(),
ui_->parameters_toolbox->getParameters(),
std::vector<float>(),
(unsigned char)ui_->spinBox_depthConfidence->value());
} }
if(cloudTo.get() && indicesTo->size()) if(cloudTo.get() && indicesTo->size())
@@ -7140,7 +7221,7 @@ void DatabaseViewer::sliderIterationsValueChanged(int value)
} }
if(!allNodesAreInWM) if(!allNodesAreInWM)
{ {
ui_->graphViewer->updatePosterior(colors, 1, 1); ui_->graphViewer->updateNodeColorByValue("In WM", colors, 1, false, 1);
} }
} }
QGraphicsRectItem * rectScaleItem = 0; QGraphicsRectItem * rectScaleItem = 0;
@@ -8085,10 +8166,12 @@ void DatabaseViewer::refineConstraint()
{ {
int from = ids_.at(ui_->horizontalSlider_A->value()); int from = ids_.at(ui_->horizontalSlider_A->value());
int to = ids_.at(ui_->horizontalSlider_B->value()); int to = ids_.at(ui_->horizontalSlider_B->value());
refineConstraint(from, to, false); RegistrationIcp regProximity(ui_->parameters_toolbox->getParameters());
std::shared_ptr<Registration> reg(Registration::create(ui_->parameters_toolbox->getParameters()));
refineConstraint(from, to, reg.get(), &regProximity, false);
} }
void DatabaseViewer::refineConstraint(int from, int to, bool silent) void DatabaseViewer::refineConstraint(int from, int to, Registration * reg, RegistrationIcp * regProximity, bool silent)
{ {
UDEBUG("%d -> %d", from, to); UDEBUG("%d -> %d", from, to);
bool switchedIds = false; bool switchedIds = false;
@@ -8361,8 +8444,7 @@ void DatabaseViewer::refineConstraint(int from, int to, bool silent)
fromScan.is2d()?Transform(0,0,fromScan.localTransform().z(),0,0,0):Transform::getIdentity())); fromScan.is2d()?Transform(0,0,fromScan.localTransform().z(),0,0,0):Transform::getIdentity()));
toS = new Signature(assembledData); toS = new Signature(assembledData);
RegistrationIcp registrationIcp(parameters); transform = regProximity->computeTransformationMod(*fromS, *toS, currentLink.transform(), &info);
transform = registrationIcp.computeTransformationMod(*fromS, *toS, currentLink.transform(), &info);
if(!transform.isNull()) if(!transform.isNull())
{ {
// local scan matching proximity detection should have higher variance (see Rtabmap::process()) // local scan matching proximity detection should have higher variance (see Rtabmap::process())
@@ -8380,7 +8462,6 @@ void DatabaseViewer::refineConstraint(int from, int to, bool silent)
} }
bool reextractVisualFeatures = uStr2Bool(parameters.at(Parameters::kRGBDLoopClosureReextractFeatures())); bool reextractVisualFeatures = uStr2Bool(parameters.at(Parameters::kRGBDLoopClosureReextractFeatures()));
Registration * reg = Registration::create(parameters);
if( reg->isScanRequired() || if( reg->isScanRequired() ||
reg->isUserDataRequired() || reg->isUserDataRequired() ||
reextractVisualFeatures || reextractVisualFeatures ||
@@ -8477,8 +8558,6 @@ void DatabaseViewer::refineConstraint(int from, int to, bool silent)
transform = reg->computeTransformationMod(*toS, *fromS, t.isNull()?t:t.inverse(), &info); transform = reg->computeTransformationMod(*toS, *fromS, t.isNull()?t:t.inverse(), &info);
switchedIds = true; switchedIds = true;
} }
delete reg;
} }
UINFO("(%d ->%d) Registration time: %f s", currentLink.from(), currentLink.to(), timer.ticks()); UINFO("(%d ->%d) Registration time: %f s", currentLink.from(), currentLink.to(), timer.ticks());
@@ -8610,11 +8689,14 @@ void DatabaseViewer::addConstraint()
{ {
int from = ids_.at(ui_->horizontalSlider_A->value()); int from = ids_.at(ui_->horizontalSlider_A->value());
int to = ids_.at(ui_->horizontalSlider_B->value()); int to = ids_.at(ui_->horizontalSlider_B->value());
addConstraint(from, to, false); std::shared_ptr<Registration> reg(Registration::create(ui_->parameters_toolbox->getParameters()));
addConstraint(from, to, reg.get(), false);
} }
bool DatabaseViewer::addConstraint(int from, int to, bool silent, bool silentlyUseOptimizedGraphAsGuess) bool DatabaseViewer::addConstraint(int from, int to, Registration * reg, bool silent, bool silentlyUseOptimizedGraphAsGuess)
{ {
UASSERT(reg);
bool switchedIds = false; bool switchedIds = false;
if(from == to) if(from == to)
{ {
@@ -8641,7 +8723,6 @@ bool DatabaseViewer::addConstraint(int from, int to, bool silent, bool silentlyU
UASSERT(!containsLink(linksRefined_, from, to)); UASSERT(!containsLink(linksRefined_, from, to));
ParametersMap parameters = ui_->parameters_toolbox->getParameters(); ParametersMap parameters = ui_->parameters_toolbox->getParameters();
Registration * reg = Registration::create(parameters);
bool loopCovLimited = Parameters::defaultRGBDLoopCovLimited(); bool loopCovLimited = Parameters::defaultRGBDLoopCovLimited();
Parameters::parse(parameters, Parameters::kRGBDLoopCovLimited(), loopCovLimited); Parameters::parse(parameters, Parameters::kRGBDLoopCovLimited(), loopCovLimited);
@@ -8823,7 +8904,6 @@ bool DatabaseViewer::addConstraint(int from, int to, bool silent, bool silentlyU
{ {
t = reg->computeTransformationMod(*fromS, *toS, guess, &info); t = reg->computeTransformationMod(*fromS, *toS, guess, &info);
} }
delete reg;
UDEBUG(""); UDEBUG("");
if(!t.isNull()) if(!t.isNull())
+29 -7
View File
@@ -194,17 +194,39 @@ void ExportBundlerDialog::exportBundler(
ParametersMap parametersSBA = parameters; ParametersMap parametersSBA = parameters;
uInsert(parametersSBA, std::make_pair(Parameters::kOptimizerIterations(), uNumber2Str(_ui->sba_iterations->value()))); uInsert(parametersSBA, std::make_pair(Parameters::kOptimizerIterations(), uNumber2Str(_ui->sba_iterations->value())));
uInsert(parametersSBA, std::make_pair(Parameters::kg2oPixelVariance(), uNumber2Str(_ui->sba_variance->value()))); uInsert(parametersSBA, std::make_pair(Parameters::kg2oPixelVariance(), uNumber2Str(_ui->sba_variance->value())));
Optimizer * sba = Optimizer::create(sbaType, parametersSBA); std::shared_ptr<Optimizer> sba(Optimizer::create(sbaType, parametersSBA));
sba->getConnectedGraph(poses.begin()->first, poses, links, posesOut, linksOut); sba->getConnectedGraph(poses.begin()->first, poses, links, posesOut, linksOut);
poses = sba->optimizeBA( // set input poses as initial optimization guess
posesOut.begin()->first, for(std::map<int, Transform>::iterator iter=posesOut.begin(); iter!=posesOut.end(); ++iter)
posesOut, {
linksOut, iter->second = poses.at(iter->first);
}
if(_ui->sba_iterations->value() > 0)
{
UINFO("Do BA optimization with %d iterations.", _ui->sba_iterations->value());
poses = sba->optimizeBA(
posesOut.begin()->first,
posesOut,
linksOut,
signatures.toStdMap(),
points3DMap,
wordReferences,
_ui->sba_rematchFeatures->isChecked(),
parametersSBA);
}
else
{
UINFO("Do not optimize, just compute 3D features and word correspondences.");
poses = posesOut;
sba->computeBACorrespondences(poses,
linksOut,
signatures.toStdMap(), signatures.toStdMap(),
points3DMap, points3DMap,
wordReferences, wordReferences,
_ui->sba_rematchFeatures->isChecked()); _ui->sba_rematchFeatures->isChecked(),
delete sba; false,
parametersSBA);
}
if(poses.empty()) if(poses.empty())
{ {
+37 -6
View File
@@ -151,6 +151,9 @@ ExportCloudsDialog::ExportCloudsDialog(QWidget *parent) :
connect(_ui->lineEdit_distortionModel, SIGNAL(textChanged(const QString &)), this, SIGNAL(configChanged())); connect(_ui->lineEdit_distortionModel, SIGNAL(textChanged(const QString &)), this, SIGNAL(configChanged()));
connect(_ui->toolButton_distortionModel, SIGNAL(clicked()), this, SLOT(selectDistortionModel())); connect(_ui->toolButton_distortionModel, SIGNAL(clicked()), this, SLOT(selectDistortionModel()));
connect(_ui->spinBox_depthConfidence, SIGNAL(valueChanged(int)), this, SIGNAL(configChanged()));
connect(_ui->doubleSpinBox_depthEdgeFiltering, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
connect(_ui->checkBox_bilateral, SIGNAL(stateChanged(int)), this, SIGNAL(configChanged())); connect(_ui->checkBox_bilateral, SIGNAL(stateChanged(int)), this, SIGNAL(configChanged()));
connect(_ui->checkBox_bilateral, SIGNAL(stateChanged(int)), this, SLOT(updateReconstructionFlavor())); connect(_ui->checkBox_bilateral, SIGNAL(stateChanged(int)), this, SLOT(updateReconstructionFlavor()));
connect(_ui->doubleSpinBox_bilateral_sigmaS, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged())); connect(_ui->doubleSpinBox_bilateral_sigmaS, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
@@ -209,6 +212,7 @@ ExportCloudsDialog::ExportCloudsDialog(QWidget *parent) :
connect(_ui->spinBox_camProjDecimation, SIGNAL(valueChanged(int)), this, SIGNAL(configChanged())); connect(_ui->spinBox_camProjDecimation, SIGNAL(valueChanged(int)), this, SIGNAL(configChanged()));
connect(_ui->doubleSpinBox_camProjMaxDistance, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged())); connect(_ui->doubleSpinBox_camProjMaxDistance, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
connect(_ui->doubleSpinBox_camProjMaxAngle, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged())); connect(_ui->doubleSpinBox_camProjMaxAngle, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
connect(_ui->doubleSpinBox_camProjMaxDepthError, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
connect(_ui->checkBox_camProjDistanceToCamPolicy, SIGNAL(stateChanged(int)), this, SIGNAL(configChanged())); connect(_ui->checkBox_camProjDistanceToCamPolicy, SIGNAL(stateChanged(int)), this, SIGNAL(configChanged()));
connect(_ui->checkBox_camProjKeepPointsNotSeenByCameras, SIGNAL(stateChanged(int)), this, SIGNAL(configChanged())); connect(_ui->checkBox_camProjKeepPointsNotSeenByCameras, SIGNAL(stateChanged(int)), this, SIGNAL(configChanged()));
connect(_ui->checkBox_camProjRecolorPoints, SIGNAL(stateChanged(int)), this, SIGNAL(configChanged())); connect(_ui->checkBox_camProjRecolorPoints, SIGNAL(stateChanged(int)), this, SIGNAL(configChanged()));
@@ -400,6 +404,8 @@ void ExportCloudsDialog::saveSettings(QSettings & settings, const QString & grou
settings.setValue("regenerate_fill_error", _ui->spinBox_fillDepthHolesError->value()); settings.setValue("regenerate_fill_error", _ui->spinBox_fillDepthHolesError->value());
settings.setValue("regenerate_roi", _ui->lineEdit_roiRatios->text()); settings.setValue("regenerate_roi", _ui->lineEdit_roiRatios->text());
settings.setValue("regenerate_distortion_model", _ui->lineEdit_distortionModel->text()); settings.setValue("regenerate_distortion_model", _ui->lineEdit_distortionModel->text());
settings.setValue("regenerate_min_depth_confidence", _ui->spinBox_depthConfidence->value());
settings.setValue("regenerate_edge_bleeding_error", _ui->doubleSpinBox_depthEdgeFiltering->value());
settings.setValue("bilateral", _ui->checkBox_bilateral->isChecked()); settings.setValue("bilateral", _ui->checkBox_bilateral->isChecked());
settings.setValue("bilateral_sigma_s", _ui->doubleSpinBox_bilateral_sigmaS->value()); settings.setValue("bilateral_sigma_s", _ui->doubleSpinBox_bilateral_sigmaS->value());
@@ -443,6 +449,7 @@ void ExportCloudsDialog::saveSettings(QSettings & settings, const QString & grou
settings.setValue("cam_proj_decimation", _ui->spinBox_camProjDecimation->value()); settings.setValue("cam_proj_decimation", _ui->spinBox_camProjDecimation->value());
settings.setValue("cam_proj_max_distance", _ui->doubleSpinBox_camProjMaxDistance->value()); settings.setValue("cam_proj_max_distance", _ui->doubleSpinBox_camProjMaxDistance->value());
settings.setValue("cam_proj_max_angle", _ui->doubleSpinBox_camProjMaxAngle->value()); settings.setValue("cam_proj_max_angle", _ui->doubleSpinBox_camProjMaxAngle->value());
settings.setValue("cam_proj_max_depth_error", _ui->doubleSpinBox_camProjMaxDepthError->value());
settings.setValue("cam_proj_distance_policy", _ui->checkBox_camProjDistanceToCamPolicy->isChecked()); settings.setValue("cam_proj_distance_policy", _ui->checkBox_camProjDistanceToCamPolicy->isChecked());
settings.setValue("cam_proj_keep_points", _ui->checkBox_camProjKeepPointsNotSeenByCameras->isChecked()); settings.setValue("cam_proj_keep_points", _ui->checkBox_camProjKeepPointsNotSeenByCameras->isChecked());
settings.setValue("cam_proj_recolor_points", _ui->checkBox_camProjRecolorPoints->isChecked()); settings.setValue("cam_proj_recolor_points", _ui->checkBox_camProjRecolorPoints->isChecked());
@@ -582,6 +589,8 @@ void ExportCloudsDialog::loadSettings(QSettings & settings, const QString & grou
_ui->spinBox_fillDepthHolesError->setValue(settings.value("regenerate_fill_error", _ui->spinBox_fillDepthHolesError->value()).toInt()); _ui->spinBox_fillDepthHolesError->setValue(settings.value("regenerate_fill_error", _ui->spinBox_fillDepthHolesError->value()).toInt());
_ui->lineEdit_roiRatios->setText(settings.value("regenerate_roi", _ui->lineEdit_roiRatios->text()).toString()); _ui->lineEdit_roiRatios->setText(settings.value("regenerate_roi", _ui->lineEdit_roiRatios->text()).toString());
_ui->lineEdit_distortionModel->setText(settings.value("regenerate_distortion_model", _ui->lineEdit_distortionModel->text()).toString()); _ui->lineEdit_distortionModel->setText(settings.value("regenerate_distortion_model", _ui->lineEdit_distortionModel->text()).toString());
_ui->spinBox_depthConfidence->setValue(settings.value("regenerate_min_depth_confidence", _ui->spinBox_depthConfidence->value()).toInt());
_ui->doubleSpinBox_depthEdgeFiltering->setValue(settings.value("regenerate_edge_bleeding_error", _ui->doubleSpinBox_depthEdgeFiltering->value()).toDouble());
_ui->checkBox_bilateral->setChecked(settings.value("bilateral", _ui->checkBox_bilateral->isChecked()).toBool()); _ui->checkBox_bilateral->setChecked(settings.value("bilateral", _ui->checkBox_bilateral->isChecked()).toBool());
_ui->doubleSpinBox_bilateral_sigmaS->setValue(settings.value("bilateral_sigma_s", _ui->doubleSpinBox_bilateral_sigmaS->value()).toDouble()); _ui->doubleSpinBox_bilateral_sigmaS->setValue(settings.value("bilateral_sigma_s", _ui->doubleSpinBox_bilateral_sigmaS->value()).toDouble());
@@ -628,6 +637,7 @@ void ExportCloudsDialog::loadSettings(QSettings & settings, const QString & grou
_ui->spinBox_camProjDecimation->setValue(settings.value("cam_proj_decimation", _ui->spinBox_camProjDecimation->value()).toInt()); _ui->spinBox_camProjDecimation->setValue(settings.value("cam_proj_decimation", _ui->spinBox_camProjDecimation->value()).toInt());
_ui->doubleSpinBox_camProjMaxDistance->setValue(settings.value("cam_proj_max_distance", _ui->doubleSpinBox_camProjMaxDistance->value()).toDouble()); _ui->doubleSpinBox_camProjMaxDistance->setValue(settings.value("cam_proj_max_distance", _ui->doubleSpinBox_camProjMaxDistance->value()).toDouble());
_ui->doubleSpinBox_camProjMaxAngle->setValue(settings.value("cam_proj_max_angle", _ui->doubleSpinBox_camProjMaxAngle->value()).toDouble()); _ui->doubleSpinBox_camProjMaxAngle->setValue(settings.value("cam_proj_max_angle", _ui->doubleSpinBox_camProjMaxAngle->value()).toDouble());
_ui->doubleSpinBox_camProjMaxDepthError->setValue(settings.value("cam_proj_max_depth_error", _ui->doubleSpinBox_camProjMaxDepthError->value()).toDouble());
_ui->checkBox_camProjDistanceToCamPolicy->setChecked(settings.value("cam_proj_distance_policy", _ui->checkBox_camProjDistanceToCamPolicy->isChecked()).toBool()); _ui->checkBox_camProjDistanceToCamPolicy->setChecked(settings.value("cam_proj_distance_policy", _ui->checkBox_camProjDistanceToCamPolicy->isChecked()).toBool());
_ui->checkBox_camProjKeepPointsNotSeenByCameras->setChecked(settings.value("cam_proj_keep_points", _ui->checkBox_camProjKeepPointsNotSeenByCameras->isChecked()).toBool()); _ui->checkBox_camProjKeepPointsNotSeenByCameras->setChecked(settings.value("cam_proj_keep_points", _ui->checkBox_camProjKeepPointsNotSeenByCameras->isChecked()).toBool());
_ui->checkBox_camProjRecolorPoints->setChecked(settings.value("cam_proj_recolor_points", _ui->checkBox_camProjRecolorPoints->isChecked()).toBool()); _ui->checkBox_camProjRecolorPoints->setChecked(settings.value("cam_proj_recolor_points", _ui->checkBox_camProjRecolorPoints->isChecked()).toBool());
@@ -767,6 +777,8 @@ void ExportCloudsDialog::restoreDefaults()
_ui->spinBox_fillDepthHolesError->setValue(2); _ui->spinBox_fillDepthHolesError->setValue(2);
_ui->lineEdit_roiRatios->setText("0.0 0.0 0.0 0.0"); _ui->lineEdit_roiRatios->setText("0.0 0.0 0.0 0.0");
_ui->lineEdit_distortionModel->setText(""); _ui->lineEdit_distortionModel->setText("");
_ui->spinBox_depthConfidence->setValue(0);
_ui->doubleSpinBox_depthEdgeFiltering->setValue(0.0);
_ui->checkBox_bilateral->setChecked(false); _ui->checkBox_bilateral->setChecked(false);
_ui->doubleSpinBox_bilateral_sigmaS->setValue(10.0); _ui->doubleSpinBox_bilateral_sigmaS->setValue(10.0);
@@ -810,6 +822,7 @@ void ExportCloudsDialog::restoreDefaults()
_ui->spinBox_camProjDecimation->setValue(1); _ui->spinBox_camProjDecimation->setValue(1);
_ui->doubleSpinBox_camProjMaxDistance->setValue(0); _ui->doubleSpinBox_camProjMaxDistance->setValue(0);
_ui->doubleSpinBox_camProjMaxAngle->setValue(0); _ui->doubleSpinBox_camProjMaxAngle->setValue(0);
_ui->doubleSpinBox_camProjMaxDepthError->setValue(0);
_ui->checkBox_camProjDistanceToCamPolicy->setChecked(true); _ui->checkBox_camProjDistanceToCamPolicy->setChecked(true);
_ui->checkBox_camProjKeepPointsNotSeenByCameras->setChecked(false); _ui->checkBox_camProjKeepPointsNotSeenByCameras->setChecked(false);
_ui->checkBox_camProjRecolorPoints->setChecked(true); _ui->checkBox_camProjRecolorPoints->setChecked(true);
@@ -2911,6 +2924,7 @@ bool ExportCloudsDialog::getExportedClouds(
cameraModelsProj, cameraModelsProj,
_ui->doubleSpinBox_camProjMaxDistance->value(), _ui->doubleSpinBox_camProjMaxDistance->value(),
_ui->doubleSpinBox_camProjMaxAngle->value()*M_PI/180.0, _ui->doubleSpinBox_camProjMaxAngle->value()*M_PI/180.0,
_ui->doubleSpinBox_camProjMaxDepthError->value(),
roiRatios, roiRatios,
projMask, projMask,
_ui->checkBox_camProjDistanceToCamPolicy->isChecked(), _ui->checkBox_camProjDistanceToCamPolicy->isChecked(),
@@ -3680,20 +3694,30 @@ std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::Indic
{ {
const Signature & s = cachedSignatures.find(iter->first).value(); const Signature & s = cachedSignatures.find(iter->first).value();
data = s.sensorData(); data = s.sensorData();
cv::Mat image,depth; cv::Mat image,depth,confidence;
data.uncompressData( data.uncompressData(
_ui->checkBox_fromDepth->isChecked()?&image:0, _ui->checkBox_fromDepth->isChecked()?&image:0,
_ui->checkBox_fromDepth->isChecked()?&depth:0, _ui->checkBox_fromDepth->isChecked()?&depth:0,
!_ui->checkBox_fromDepth->isChecked()?&scan:0); !_ui->checkBox_fromDepth->isChecked()?&scan:0,
0,
0,
0,
0,
_ui->checkBox_fromDepth->isChecked()?&confidence:0);
} }
else if(_dbDriver) else if(_dbDriver)
{ {
cv::Mat image,depth; cv::Mat image,depth,confidence;
_dbDriver->getNodeData(iter->first, data, _ui->checkBox_fromDepth->isChecked(), !_ui->checkBox_fromDepth->isChecked(), false, false); _dbDriver->getNodeData(iter->first, data, _ui->checkBox_fromDepth->isChecked(), !_ui->checkBox_fromDepth->isChecked(), false, false);
data.uncompressData( data.uncompressData(
_ui->checkBox_fromDepth->isChecked()?&image:0, _ui->checkBox_fromDepth->isChecked()?&image:0,
_ui->checkBox_fromDepth->isChecked()?&depth:0, _ui->checkBox_fromDepth->isChecked()?&depth:0,
!_ui->checkBox_fromDepth->isChecked()?&scan:0); !_ui->checkBox_fromDepth->isChecked()?&scan:0,
0,
0,
0,
0,
_ui->checkBox_fromDepth->isChecked()?&confidence:0);
} }
if(_ui->checkBox_fromDepth->isChecked() && !data.imageRaw().empty() && !data.depthOrRightRaw().empty()) if(_ui->checkBox_fromDepth->isChecked() && !data.imageRaw().empty() && !data.depthOrRightRaw().empty())
@@ -3714,6 +3738,12 @@ std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::Indic
model.undistort(depth); model.undistort(depth);
} }
// edge bleeding filter
if(!depth.empty() && _ui->doubleSpinBox_depthEdgeFiltering->value()>0.0)
{
util2d::depthBleedingFiltering(depth, _ui->doubleSpinBox_depthEdgeFiltering->value());
}
// bilateral filtering // bilateral filtering
if(!depth.empty() && _ui->checkBox_bilateral->isChecked()) if(!depth.empty() && _ui->checkBox_bilateral->isChecked())
{ {
@@ -3724,7 +3754,7 @@ std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::Indic
if(!depth.empty()) if(!depth.empty())
{ {
data.setRGBDImage(data.imageRaw(), depth, data.cameraModels()); data.setRGBDImage(data.imageRaw(), depth, data.depthConfidenceRaw(), data.cameraModels());
} }
UASSERT(iter->first == data.id()); UASSERT(iter->first == data.id());
@@ -3749,7 +3779,8 @@ std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::Indic
_ui->doubleSpinBox_minDepth->value(), _ui->doubleSpinBox_minDepth->value(),
indices.get(), indices.get(),
parameters, parameters,
roiRatios); roiRatios,
(unsigned char)_ui->spinBox_depthConfidence->value());
if(cloudWithoutNormals->size()) if(cloudWithoutNormals->size())
{ {
+156 -47
View File
@@ -181,7 +181,8 @@ ImageView::ImageView(QWidget * parent) :
_depthColorMapMinRange(0), _depthColorMapMinRange(0),
_depthColorMapMaxRange(0), _depthColorMapMaxRange(0),
_imageItem(0), _imageItem(0),
_imageDepthItem(0) _imageDepthItem(0),
_imageDepthConfidenceItem(0)
{ {
#if QT_VERSION >= 0x050000 #if QT_VERSION >= 0x050000
_savedFileName = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation); _savedFileName = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation);
@@ -209,9 +210,12 @@ ImageView::ImageView(QWidget * parent) :
_showImage = _menu->addAction(tr("Show image")); _showImage = _menu->addAction(tr("Show image"));
_showImage->setCheckable(true); _showImage->setCheckable(true);
_showImage->setChecked(true); _showImage->setChecked(true);
_showImageDepth = _menu->addAction(tr("Show image depth")); _showImageDepth = _menu->addAction(tr("Show depth image"));
_showImageDepth->setCheckable(true); _showImageDepth->setCheckable(true);
_showImageDepth->setChecked(false); _showImageDepth->setChecked(false);
_showImageDepthConfidence = _menu->addAction(tr("Show depth confidence"));
_showImageDepthConfidence->setCheckable(true);
_showImageDepthConfidence->setChecked(false);
_featureMenu = _menu->addMenu("Features"); _featureMenu = _menu->addMenu("Features");
_showFeatures = _featureMenu->addAction(tr("Show features")); _showFeatures = _featureMenu->addAction(tr("Show features"));
_showFeatures->setCheckable(true); _showFeatures->setCheckable(true);
@@ -293,6 +297,7 @@ void ImageView::saveSettings(QSettings & settings, const QString & group) const
} }
settings.setValue("image_shown", this->isImageShown()); settings.setValue("image_shown", this->isImageShown());
settings.setValue("depth_shown", this->isImageDepthShown()); settings.setValue("depth_shown", this->isImageDepthShown());
settings.setValue("confidence_shown", this->isImageDepthConfidenceShown());
settings.setValue("features_shown", this->isFeaturesShown()); settings.setValue("features_shown", this->isFeaturesShown());
settings.setValue("features_size", this->getFeaturesSize()); settings.setValue("features_size", this->getFeaturesSize());
settings.setValue("lines_shown", this->isLinesShown()); settings.setValue("lines_shown", this->isLinesShown());
@@ -322,6 +327,7 @@ void ImageView::loadSettings(QSettings & settings, const QString & group)
} }
this->setImageShown(settings.value("image_shown", this->isImageShown()).toBool()); this->setImageShown(settings.value("image_shown", this->isImageShown()).toBool());
this->setImageDepthShown(settings.value("depth_shown", this->isImageDepthShown()).toBool()); this->setImageDepthShown(settings.value("depth_shown", this->isImageDepthShown()).toBool());
this->setImageDepthConfidenceShown(settings.value("confidence_shown", this->isImageDepthConfidenceShown()).toBool());
this->setFeaturesShown(settings.value("features_shown", this->isFeaturesShown()).toBool()); this->setFeaturesShown(settings.value("features_shown", this->isFeaturesShown()).toBool());
this->setFeaturesSize(settings.value("features_size", this->getFeaturesSize()).toInt()); this->setFeaturesSize(settings.value("features_size", this->getFeaturesSize()).toInt());
this->setLinesShown(settings.value("lines_shown", this->isLinesShown()).toBool()); this->setLinesShown(settings.value("lines_shown", this->isLinesShown()).toBool());
@@ -363,6 +369,11 @@ bool ImageView::isImageDepthShown() const
return _showImageDepth->isChecked(); return _showImageDepth->isChecked();
} }
bool ImageView::isImageDepthConfidenceShown() const
{
return _showImageDepthConfidence->isChecked();
}
bool ImageView::isFeaturesShown() const bool ImageView::isFeaturesShown() const
{ {
return _showFeatures->isChecked(); return _showFeatures->isChecked();
@@ -466,6 +477,13 @@ void ImageView::setImageShown(bool shown)
void ImageView::setImageDepthShown(bool shown) void ImageView::setImageDepthShown(bool shown)
{ {
_showImageDepth->setChecked(shown); _showImageDepth->setChecked(shown);
if(shown)
{
_showImageDepthConfidence->setChecked(false);
if(_imageDepthConfidenceItem) {
_imageDepthConfidenceItem->setVisible(false);
}
}
if(_imageDepthItem) if(_imageDepthItem)
{ {
_imageDepthItem->setVisible(_showImageDepth->isChecked()); _imageDepthItem->setVisible(_showImageDepth->isChecked());
@@ -478,6 +496,28 @@ void ImageView::setImageDepthShown(bool shown)
} }
} }
void ImageView::setImageDepthConfidenceShown(bool shown)
{
_showImageDepthConfidence->setChecked(shown);
if(shown)
{
_showImageDepth->setChecked(false);
if(_imageDepthItem) {
_imageDepthItem->setVisible(false);
}
}
if(_imageDepthConfidenceItem)
{
_imageDepthConfidenceItem->setVisible(_showImageDepthConfidence->isChecked());
this->updateOpacity();
}
if(!_graphicsView->isVisible())
{
this->update();
}
}
bool ImageView::isLinesShown() const bool ImageView::isLinesShown() const
{ {
return _showLines->isChecked(); return _showLines->isChecked();
@@ -517,6 +557,8 @@ void ImageView::setGraphicsViewMode(bool on)
_graphicsView->setVisible(on); _graphicsView->setVisible(on);
_scaleMenu->setEnabled(on); _scaleMenu->setEnabled(on);
_mouseTracking->setEnabled(!on);
if(on) if(on)
{ {
for(QMultiMap<int, KeypointItem*>::iterator iter=_features.begin(); iter!=_features.end(); ++iter) for(QMultiMap<int, KeypointItem*>::iterator iter=_features.begin(); iter!=_features.end(); ++iter)
@@ -550,11 +592,20 @@ void ImageView::setGraphicsViewMode(bool on)
{ {
_imageDepthItem->setPixmap(_imageDepth); _imageDepthItem->setPixmap(_imageDepth);
} }
else else if(!_imageDepth.isNull())
{ {
_imageDepthItem = _graphicsView->scene()->addPixmap(_imageDepth); _imageDepthItem = _graphicsView->scene()->addPixmap(_imageDepth);
_imageDepthItem->setVisible(_showImageDepth->isChecked()); _imageDepthItem->setVisible(_showImageDepth->isChecked());
} }
if(_imageDepthConfidenceItem)
{
_imageDepthConfidenceItem->setPixmap(_imageDepthConfidence);
}
else if(!_imageDepthConfidence.isNull())
{
_imageDepthConfidenceItem = _graphicsView->scene()->addPixmap(_imageDepthConfidence);
_imageDepthConfidenceItem->setVisible(_showImageDepthConfidence->isChecked());
}
this->updateOpacity(); this->updateOpacity();
if(_graphicsViewScaled->isChecked()) if(_graphicsViewScaled->isChecked())
@@ -790,7 +841,8 @@ void ImageView::paintEvent(QPaintEvent *event)
painter.save(); painter.save();
if(_showImage->isChecked() && !_image.isNull() && if(_showImage->isChecked() && !_image.isNull() &&
_showImageDepth->isChecked() && !_imageDepth.isNull()) ((_showImageDepth->isChecked() && !_imageDepth.isNull()) ||
(_showImageDepthConfidence->isChecked()&&!_imageDepthConfidence.isNull())))
{ {
painter.setOpacity(0.5); painter.setOpacity(0.5);
} }
@@ -804,6 +856,10 @@ void ImageView::paintEvent(QPaintEvent *event)
{ {
painter.drawPixmap(QPoint(0,0), _imageDepth); painter.drawPixmap(QPoint(0,0), _imageDepth);
} }
else if(_showImageDepthConfidence->isChecked() && !_imageDepthConfidence.isNull())
{
painter.drawPixmap(QPoint(0,0), _imageDepthConfidence);
}
painter.restore(); painter.restore();
if(_showFeatures->isChecked()) if(_showFeatures->isChecked())
@@ -966,6 +1022,11 @@ void ImageView::contextMenuEvent(QContextMenuEvent * e)
this->setImageDepthShown(_showImageDepth->isChecked()); this->setImageDepthShown(_showImageDepth->isChecked());
Q_EMIT configChanged(); Q_EMIT configChanged();
} }
else if(action == _showImageDepthConfidence)
{
this->setImageDepthConfidenceShown(_showImageDepthConfidence->isChecked());
Q_EMIT configChanged();
}
else if(action == _showLines) else if(action == _showLines)
{ {
this->setLinesShown(_showLines->isChecked()); this->setLinesShown(_showLines->isChecked());
@@ -988,8 +1049,9 @@ void ImageView::contextMenuEvent(QContextMenuEvent * e)
} }
else if(action == _colorMapBlackToWhite || action == _colorMapWhiteToBlack || action == _colorMapRedToBlue || action == _colorMapBlueToRed) else if(action == _colorMapBlackToWhite || action == _colorMapWhiteToBlack || action == _colorMapRedToBlue || action == _colorMapBlueToRed)
{ {
if(!_imageDepthCv.empty()) if(!_imageDepthCv.empty()) {
this->setImageDepth(_imageDepthCv); this->setImageDepth(_imageDepthCv, _imageDepthConfidenceCv);
}
Q_EMIT configChanged(); Q_EMIT configChanged();
} }
else if(action == _colorMapMinRange) else if(action == _colorMapMinRange)
@@ -999,8 +1061,9 @@ void ImageView::contextMenuEvent(QContextMenuEvent * e)
if(ok) if(ok)
{ {
this->setDepthColorMapRange(value, _depthColorMapMaxRange); this->setDepthColorMapRange(value, _depthColorMapMaxRange);
if(!_imageDepthCv.empty()) if(!_imageDepthCv.empty()) {
this->setImageDepth(_imageDepthCv); this->setImageDepth(_imageDepthCv, _imageDepthConfidenceCv);
}
Q_EMIT configChanged(); Q_EMIT configChanged();
} }
} }
@@ -1011,8 +1074,9 @@ void ImageView::contextMenuEvent(QContextMenuEvent * e)
if(ok) if(ok)
{ {
this->setDepthColorMapRange(_depthColorMapMinRange, value); this->setDepthColorMapRange(_depthColorMapMinRange, value);
if(!_imageDepthCv.empty()) if(!_imageDepthCv.empty()) {
this->setImageDepth(_imageDepthCv); this->setImageDepth(_imageDepthCv, _imageDepthConfidenceCv);
}
Q_EMIT configChanged(); Q_EMIT configChanged();
} }
} }
@@ -1047,7 +1111,7 @@ void ImageView::contextMenuEvent(QContextMenuEvent * e)
} }
} }
if(action == _showImage || action ==_showImageDepth) if(action == _showImage || action ==_showImageDepth || action ==_showImageDepthConfidence)
{ {
this->updateOpacity(); this->updateOpacity();
Q_EMIT configChanged(); Q_EMIT configChanged();
@@ -1059,17 +1123,16 @@ void ImageView::mouseMoveEvent(QMouseEvent * event)
if(_mouseTracking->isChecked() && if(_mouseTracking->isChecked() &&
!_graphicsView->scene()->sceneRect().isNull() && !_graphicsView->scene()->sceneRect().isNull() &&
!_image.isNull() && !_image.isNull() &&
!_imageDepthCv.empty() && !_imageDepthCv.empty() &&(_imageDepthCv.type() == CV_16UC1 || _imageDepthCv.type() == CV_32FC1))
(_imageDepthCv.type() == CV_16UC1 || _imageDepthCv.type() == CV_32FC1))
{ {
float scale, offsetX, offsetY; float scale, offsetX, offsetY;
computeScaleOffsets(this->rect(), scale, offsetX, offsetY); computeScaleOffsets(this->rect(), scale, offsetX, offsetY);
float u = (event->pos().x() - offsetX) / scale; float u = (event->pos().x() - offsetX) / scale;
float v = (event->pos().y() - offsetY) / scale; float v = (event->pos().y() - offsetY) / scale;
float depthScale = 1; float depthScale = 1;
if(_image.width() > _imageDepth.width()) if(_image.width() > _imageDepthCv.cols)
{ {
depthScale = _imageDepth.width() / _image.width(); depthScale = float(_imageDepthCv.cols) / float(_image.width());
} }
int ud = int(u*depthScale); int ud = int(u*depthScale);
int vd = int(v*depthScale); int vd = int(v*depthScale);
@@ -1077,33 +1140,47 @@ void ImageView::mouseMoveEvent(QMouseEvent * event)
ud < _imageDepthCv.cols && ud < _imageDepthCv.cols &&
vd < _imageDepthCv.rows) vd < _imageDepthCv.rows)
{ {
float depth = 0; if( _showImageDepthConfidence->isChecked() &&
if(_imageDepthCv.type() == CV_32FC1) !_imageDepthConfidenceCv.empty() &&
_imageDepthCv.size() == _imageDepthConfidenceCv.size())
{ {
depth = _imageDepthCv.at<float>(vd, ud); unsigned char confidence = _imageDepthConfidenceCv.at<unsigned char>(vd, ud);
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
QToolTip::showText(event->globalPosition().toPoint(), tr("Confidence=%1%").arg(confidence));
#else
QToolTip::showText(event->globalPos(), tr("Confidence=%1%").arg(confidence));
#endif
} }
else else
{ {
depth = float(_imageDepthCv.at<unsigned short>(vd, ud)) / 1000.0f; float depth = 0;
} if(_imageDepthCv.type() == CV_32FC1)
{
depth = _imageDepthCv.at<float>(vd, ud);
}
else
{
depth = float(_imageDepthCv.at<unsigned short>(vd, ud)) / 1000.0f;
}
cv::Point3f pt(0,0,0); cv::Point3f pt(0,0,0);
if(depth>0 && !_models.empty() && !_pose.isNull()) if(depth>0 && !_models.empty() && !_pose.isNull())
{ {
int subImageWidth = _imageDepthCv.cols / _models.size(); int subImageWidth = _imageDepthCv.cols / _models.size();
int subImageIndex = ud / subImageWidth; int subImageIndex = ud / subImageWidth;
UASSERT(subImageIndex < (int)_models.size()); UASSERT(subImageIndex < (int)_models.size());
float x,y,z; float x,y,z;
_models[subImageIndex].project(u, v, depth, x, y, z); _models[subImageIndex].project(u, v, depth, x, y, z);
pt = cv::Point3f(x,y,z); pt = cv::Point3f(x,y,z);
pt = util3d::transformPoint(pt, _pose*_models[subImageIndex].localTransform()); pt = util3d::transformPoint(pt, _pose*_models[subImageIndex].localTransform());
} }
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
QToolTip::showText(event->globalPosition().toPoint(), pt.x!=0?tr("Depth=%1m Map=(%2,%3,%4)").arg(depth).arg(pt.x).arg(pt.y).arg(pt.z):depth > 0?tr("Depth=%1m").arg(depth):tr("Depth=NA")); QToolTip::showText(event->globalPosition().toPoint(), pt.x!=0?tr("Depth=%1m Map=(%2,%3,%4)").arg(depth).arg(pt.x).arg(pt.y).arg(pt.z):depth > 0?tr("Depth=%1m").arg(depth):tr("Depth=NA"));
#else #else
QToolTip::showText(event->globalPos(), pt.x!=0?tr("Depth=%1m Map=(%2,%3,%4)").arg(depth).arg(pt.x).arg(pt.y).arg(pt.z):depth > 0?tr("Depth=%1m").arg(depth):tr("Depth=NA")); QToolTip::showText(event->globalPos(), pt.x!=0?tr("Depth=%1m Map=(%2,%3,%4)").arg(depth).arg(pt.x).arg(pt.y).arg(pt.z):depth > 0?tr("Depth=%1m").arg(depth):tr("Depth=NA"));
#endif #endif
}
} }
else else
{ {
@@ -1115,23 +1192,31 @@ void ImageView::mouseMoveEvent(QMouseEvent * event)
void ImageView::updateOpacity() void ImageView::updateOpacity()
{ {
if(_imageItem && _imageDepthItem) if(_imageItem && (_imageDepthItem || _imageDepthConfidenceItem))
{ {
if(_imageItem->isVisible() && _imageDepthItem->isVisible()) if(_imageItem->isVisible() &&
((_imageDepthItem && _imageDepthItem->isVisible()) ||
(_imageDepthConfidenceItem && _imageDepthConfidenceItem->isVisible())))
{ {
QGraphicsOpacityEffect * effect = new QGraphicsOpacityEffect(); if(_imageDepthItem) {
effect->setOpacity(0.5); QGraphicsOpacityEffect * effect = new QGraphicsOpacityEffect();
_imageDepthItem->setGraphicsEffect(effect); effect->setOpacity(0.5);
} _imageDepthItem->setGraphicsEffect(effect);
else }
{ if(_imageDepthConfidenceItem) {
_imageDepthItem->setGraphicsEffect(0); QGraphicsOpacityEffect * effect = new QGraphicsOpacityEffect();
effect->setOpacity(0.5);
_imageDepthConfidenceItem->setGraphicsEffect(effect);
}
return;
} }
} }
else if(_imageDepthItem) if(_imageDepthItem) {
{
_imageDepthItem->setGraphicsEffect(0); _imageDepthItem->setGraphicsEffect(0);
} }
if(_imageDepthConfidenceItem) {
_imageDepthConfidenceItem->setGraphicsEffect(0);
}
} }
void ImageView::setFeatures(const std::multimap<int, cv::KeyPoint> & refWords, const cv::Mat & depth, const QColor & color) void ImageView::setFeatures(const std::multimap<int, cv::KeyPoint> & refWords, const cv::Mat & depth, const QColor & color)
@@ -1261,15 +1346,23 @@ void ImageView::setImage(const QImage & image, const std::vector<CameraModel> &
} }
} }
void ImageView::setImageDepth(const cv::Mat & imageDepth) void ImageView::setImageDepth(const cv::Mat & imageDepth, const cv::Mat & imageDepthConfidence)
{ {
_imageDepthCv = imageDepth; _imageDepthCv = imageDepth;
setImageDepth(uCvMat2QImage(_imageDepthCv, true, getDepthColorMap(), _depthColorMapMinRange, _depthColorMapMaxRange)); _imageDepthConfidenceCv = imageDepthConfidence;
setImageDepth(
uCvMat2QImage(_imageDepthCv, true, getDepthColorMap(), _depthColorMapMinRange, _depthColorMapMaxRange),
uCvMat2QImage(_imageDepthConfidenceCv, true, getDepthColorMap()));
} }
void ImageView::setImageDepth(const QImage & imageDepth) void ImageView::setImageDepth(const QImage & imageDepth, const QImage & imageDepthConfidence)
{ {
_imageDepth = QPixmap::fromImage(imageDepth); _imageDepth = QPixmap::fromImage(imageDepth);
if(!imageDepthConfidence.isNull()) {
_imageDepthConfidence = QPixmap::fromImage(imageDepthConfidence);
} else {
_showImageDepthConfidence->setChecked(false);
}
UASSERT(_imageDepth.width() && _imageDepth.height()); UASSERT(_imageDepth.width() && _imageDepth.height());
@@ -1279,6 +1372,9 @@ void ImageView::setImageDepth(const QImage & imageDepth)
{ {
// scale depth to rgb // scale depth to rgb
_imageDepth = _imageDepth.scaled(_image.size()); _imageDepth = _imageDepth.scaled(_image.size());
if(!_imageDepthConfidence.isNull()) {
_imageDepthConfidence = _imageDepthConfidence.scaled(_image.size());
}
} }
if(_graphicsView->isVisible()) if(_graphicsView->isVisible())
@@ -1286,11 +1382,18 @@ void ImageView::setImageDepth(const QImage & imageDepth)
if(_imageDepthItem) if(_imageDepthItem)
{ {
_imageDepthItem->setPixmap(_imageDepth); _imageDepthItem->setPixmap(_imageDepth);
if(_imageDepthConfidenceItem) {
_imageDepthConfidenceItem->setPixmap(_imageDepthConfidence);
}
} }
else else
{ {
_imageDepthItem = _graphicsView->scene()->addPixmap(_imageDepth); _imageDepthItem = _graphicsView->scene()->addPixmap(_imageDepth);
_imageDepthItem->setVisible(_showImageDepth->isChecked()); _imageDepthItem->setVisible(_showImageDepth->isChecked());
if(!_imageDepthConfidence.isNull()) {
_imageDepthConfidenceItem = _graphicsView->scene()->addPixmap(_imageDepthConfidence);
_imageDepthConfidenceItem->setVisible(_showImageDepthConfidence->isChecked());
}
this->updateOpacity(); this->updateOpacity();
} }
} }
@@ -1471,6 +1574,12 @@ void ImageView::clear()
delete _imageDepthItem; delete _imageDepthItem;
_imageDepthItem = 0; _imageDepthItem = 0;
} }
if(_imageDepthConfidenceItem)
{
_graphicsView->scene()->removeItem(_imageDepthConfidenceItem);
delete _imageDepthConfidenceItem;
_imageDepthConfidenceItem = 0;
}
_imageDepth = QPixmap(); _imageDepth = QPixmap();
_graphicsView->scene()->setSceneRect(QRectF()); _graphicsView->scene()->setSceneRect(QRectF());
+34 -13
View File
@@ -1225,13 +1225,15 @@ void MainWindow::processOdometry(const rtabmap::OdometryEvent & odom, bool dataI
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud; pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud;
pcl::IndicesPtr indices(new std::vector<int>); pcl::IndicesPtr indices(new std::vector<int>);
cloud = util3d::cloudRGBFromSensorData(*data, cloud = util3d::cloudRGBFromSensorData(
*data,
_preferencesDialog->getCloudDecimation(1), _preferencesDialog->getCloudDecimation(1),
_preferencesDialog->getCloudMaxDepth(1), _preferencesDialog->getCloudMaxDepth(1),
_preferencesDialog->getCloudMinDepth(1), _preferencesDialog->getCloudMinDepth(1),
indices.get(), indices.get(),
_preferencesDialog->getAllParameters(), _preferencesDialog->getAllParameters(),
_preferencesDialog->getCloudRoiRatios(1)); _preferencesDialog->getCloudRoiRatios(1),
_preferencesDialog->getCloudConfidenceThr(1));
if(indices->size()) if(indices->size())
{ {
cloud = util3d::transformPointCloud(cloud, pose); cloud = util3d::transformPointCloud(cloud, pose);
@@ -1717,7 +1719,7 @@ void MainWindow::processOdometry(const rtabmap::OdometryEvent & odom, bool dataI
_ui->imageView_odometry->setImage(uCvMat2QImage(data->imageRaw())); _ui->imageView_odometry->setImage(uCvMat2QImage(data->imageRaw()));
if(_ui->imageView_odometry->isImageDepthShown() && !data->depthOrRightRaw().empty()) if(_ui->imageView_odometry->isImageDepthShown() && !data->depthOrRightRaw().empty())
{ {
_ui->imageView_odometry->setImageDepth(data->depthOrRightRaw()); _ui->imageView_odometry->setImageDepth(data->depthOrRightRaw(), data->depthConfidenceRaw());
} }
if( odom.info().type == (int)Odometry::kTypeF2M || if( odom.info().type == (int)Odometry::kTypeF2M ||
@@ -1908,9 +1910,8 @@ void MainWindow::processOdometry(const rtabmap::OdometryEvent & odom, bool dataI
{ {
if(!odomT.isNull()) if(!odomT.isNull())
{ {
rtabmap::Transform diff = odom.info().transformGroundTruth.inverse()*odomT; _ui->statsToolBox->updateStat("Odometry/TG_error_lin/m", _preferencesDialog->isTimeUsedInFigures()?data->stamp()-_firstStamp:(float)data->id(), odom.info().transformGroundTruth.getDistance(odomT), _preferencesDialog->isCacheSavedInFigures());
_ui->statsToolBox->updateStat("Odometry/TG_error_lin/m", _preferencesDialog->isTimeUsedInFigures()?data->stamp()-_firstStamp:(float)data->id(), diff.getNorm(), _preferencesDialog->isCacheSavedInFigures()); _ui->statsToolBox->updateStat("Odometry/TG_error_ang/deg", _preferencesDialog->isTimeUsedInFigures()?data->stamp()-_firstStamp:(float)data->id(), odom.info().transformGroundTruth.getAngle(odomT)*180.0/CV_PI, _preferencesDialog->isCacheSavedInFigures());
_ui->statsToolBox->updateStat("Odometry/TG_error_ang/deg", _preferencesDialog->isTimeUsedInFigures()?data->stamp()-_firstStamp:(float)data->id(), diff.getAngle()*180.0/CV_PI, _preferencesDialog->isCacheSavedInFigures());
} }
odom.info().transformGroundTruth.getTranslationAndEulerAngles(x,y,z,roll,pitch,yaw); odom.info().transformGroundTruth.getTranslationAndEulerAngles(x,y,z,roll,pitch,yaw);
@@ -2343,7 +2344,7 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
} }
if(!signature.sensorData().depthOrRightRaw().empty()) if(!signature.sensorData().depthOrRightRaw().empty())
{ {
_ui->imageView_source->setImageDepth(signature.sensorData().depthOrRightRaw()); _ui->imageView_source->setImageDepth(signature.sensorData().depthOrRightRaw(), signature.sensorData().depthConfidenceRaw());
} }
if(img.isNull() && signature.sensorData().depthOrRightRaw().empty()) if(img.isNull() && signature.sensorData().depthOrRightRaw().empty())
{ {
@@ -2375,7 +2376,7 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
} }
if(!loopSignature.sensorData().depthOrRightRaw().empty()) if(!loopSignature.sensorData().depthOrRightRaw().empty())
{ {
_ui->imageView_loopClosure->setImageDepth(loopSignature.sensorData().depthOrRightRaw()); _ui->imageView_loopClosure->setImageDepth(loopSignature.sensorData().depthOrRightRaw(), loopSignature.sensorData().depthConfidenceRaw());
} }
if(_ui->imageView_loopClosure->sceneRect().isNull()) if(_ui->imageView_loopClosure->sceneRect().isNull())
{ {
@@ -3718,7 +3719,8 @@ std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> MainWindow::c
_preferencesDialog->getCloudMinDepth(0), _preferencesDialog->getCloudMinDepth(0),
indices.get(), indices.get(),
allParameters, allParameters,
_preferencesDialog->getCloudRoiRatios(0)); _preferencesDialog->getCloudRoiRatios(0),
_preferencesDialog->getCloudConfidenceThr(0));
// view point // view point
Eigen::Vector3f viewPoint(0.0f,0.0f,0.0f); Eigen::Vector3f viewPoint(0.0f,0.0f,0.0f);
@@ -6623,6 +6625,8 @@ void MainWindow::postProcessing(
odomMaxInf = graph::getMaxOdomInf(_currentLinksMap); odomMaxInf = graph::getMaxOdomInf(_currentLinksMap);
} }
std::shared_ptr<Registration> registration(Registration::create(parameters));
UASSERT(iterations>0); UASSERT(iterations>0);
for(int n=0; n<iterations && !_progressCanceled; ++n) for(int n=0; n<iterations && !_progressCanceled; ++n)
{ {
@@ -6703,7 +6707,6 @@ void MainWindow::postProcessing(
{ {
uInsert(parameters, ParametersPair(Parameters::kRegStrategy(), "2")); uInsert(parameters, ParametersPair(Parameters::kRegStrategy(), "2"));
} }
Registration * registration = Registration::create(parameters);
if(reextractFeatures) if(reextractFeatures)
{ {
@@ -6735,7 +6738,6 @@ void MainWindow::postProcessing(
Parameters::kRGBDLoopClosureReextractFeatures().c_str()); Parameters::kRGBDLoopClosureReextractFeatures().c_str());
} }
transform = registration->computeTransformation(signatureFrom, signatureTo, Transform(), &info); transform = registration->computeTransformation(signatureFrom, signatureTo, Transform(), &info);
delete registration;
if(!transform.isNull()) if(!transform.isNull())
{ {
//optimize the graph to see if the new constraint is globally valid //optimize the graph to see if the new constraint is globally valid
@@ -7023,7 +7025,13 @@ void MainWindow::postProcessing(
uInsert(parametersSBA, std::make_pair(Parameters::kOptimizerIterations(), uNumber2Str(sbaIterations))); uInsert(parametersSBA, std::make_pair(Parameters::kOptimizerIterations(), uNumber2Str(sbaIterations)));
uInsert(parametersSBA, std::make_pair(Parameters::kg2oPixelVariance(), uNumber2Str(sbaVariance))); uInsert(parametersSBA, std::make_pair(Parameters::kg2oPixelVariance(), uNumber2Str(sbaVariance)));
Optimizer * sbaOptimizer = Optimizer::create(sbaType, parametersSBA); Optimizer * sbaOptimizer = Optimizer::create(sbaType, parametersSBA);
std::map<int, Transform> newPoses = sbaOptimizer->optimizeBA(optimizedPoses.begin()->first, optimizedPoses, linksOut, _cachedSignatures.toStdMap(), sbaRematchFeatures); std::map<int, Transform> newPoses = sbaOptimizer->optimizeBA(
optimizedPoses.begin()->first,
optimizedPoses,
linksOut,
_cachedSignatures.toStdMap(),
sbaRematchFeatures,
parametersSBA);
delete sbaOptimizer; delete sbaOptimizer;
if(newPoses.size()) if(newPoses.size())
{ {
@@ -8181,6 +8189,12 @@ void MainWindow::exportImages()
QDir dir; QDir dir;
dir.mkdir(QString("%1/rgb").arg(path)); dir.mkdir(QString("%1/rgb").arg(path));
dir.mkdir(QString("%1/depth").arg(path)); dir.mkdir(QString("%1/depth").arg(path));
if(!data.depthConfidenceRaw().empty())
{
QDir dir;
dir.mkdir(QString("%1/confidence").arg(path));
}
} }
if(data.cameraModels().size() > 1) if(data.cameraModels().size() > 1)
@@ -8239,7 +8253,14 @@ void MainWindow::exportImages()
UWARN("Failed saving \"%s\"", QString("%1/rgb/%2.%3").arg(path).arg(id).arg(ext).toStdString().c_str()); UWARN("Failed saving \"%s\"", QString("%1/rgb/%2.%3").arg(path).arg(id).arg(ext).toStdString().c_str());
if(!cv::imwrite(QString("%1/depth/%2.png").arg(path).arg(id).toStdString(), data.depthRaw().type()==CV_32FC1?util2d::cvtDepthFromFloat(data.depthRaw()):data.depthRaw())) if(!cv::imwrite(QString("%1/depth/%2.png").arg(path).arg(id).toStdString(), data.depthRaw().type()==CV_32FC1?util2d::cvtDepthFromFloat(data.depthRaw()):data.depthRaw()))
UWARN("Failed saving \"%s\"", QString("%1/depth/%2.png").arg(path).arg(id).toStdString().c_str()); UWARN("Failed saving \"%s\"", QString("%1/depth/%2.png").arg(path).arg(id).toStdString().c_str());
info = tr("Saved rgb/%1.%2 and depth/%1.png.").arg(id).arg(ext); if(data.depthConfidenceRaw().empty()) {
info = tr("Saved rgb/%1.%2 and depth/%1.png.").arg(id).arg(ext);
}
else {
if(!cv::imwrite(QString("%1/confidence/%2.png").arg(path).arg(id).toStdString(), data.depthConfidenceRaw()))
UWARN("Failed saving \"%s\"", QString("%1/confidence/%2.png").arg(path).arg(id).toStdString().c_str());
info = tr("Saved rgb/%1.%2, depth/%1.png and confidence/%1.png.").arg(id).arg(ext);
}
} }
else if(!data.imageRaw().empty()) else if(!data.imageRaw().empty())
{ {
+14
View File
@@ -551,6 +551,10 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
_3dRenderingRoiRatios[0] = _ui->lineEdit_roiRatios; _3dRenderingRoiRatios[0] = _ui->lineEdit_roiRatios;
_3dRenderingRoiRatios[1] = _ui->lineEdit_roiRatios_odom; _3dRenderingRoiRatios[1] = _ui->lineEdit_roiRatios_odom;
_3dRenderingDepthConfidenceThr.resize(2);
_3dRenderingDepthConfidenceThr[0] = _ui->spinBox_depthConf;
_3dRenderingDepthConfidenceThr[1] = _ui->spinBox_depthConf_odom;
_3dRenderingColorScheme.resize(2); _3dRenderingColorScheme.resize(2);
_3dRenderingColorScheme[0] = _ui->spinBox_colorScheme; _3dRenderingColorScheme[0] = _ui->spinBox_colorScheme;
_3dRenderingColorScheme[1] = _ui->spinBox_colorScheme_odom; _3dRenderingColorScheme[1] = _ui->spinBox_colorScheme_odom;
@@ -622,6 +626,7 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
connect(_3dRenderingMaxDepth[i], SIGNAL(valueChanged(double)), this, SLOT(makeObsoleteCloudRenderingPanel())); connect(_3dRenderingMaxDepth[i], SIGNAL(valueChanged(double)), this, SLOT(makeObsoleteCloudRenderingPanel()));
connect(_3dRenderingMinDepth[i], SIGNAL(valueChanged(double)), this, SLOT(makeObsoleteCloudRenderingPanel())); connect(_3dRenderingMinDepth[i], SIGNAL(valueChanged(double)), this, SLOT(makeObsoleteCloudRenderingPanel()));
connect(_3dRenderingRoiRatios[i], SIGNAL(textChanged(const QString &)), this, SLOT(makeObsoleteCloudRenderingPanel())); connect(_3dRenderingRoiRatios[i], SIGNAL(textChanged(const QString &)), this, SLOT(makeObsoleteCloudRenderingPanel()));
connect(_3dRenderingDepthConfidenceThr[i], SIGNAL(valueChanged(int)), this, SLOT(makeObsoleteCloudRenderingPanel()));
connect(_3dRenderingShowScans[i], SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteCloudRenderingPanel())); connect(_3dRenderingShowScans[i], SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteCloudRenderingPanel()));
connect(_3dRenderingShowFeatures[i], SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteCloudRenderingPanel())); connect(_3dRenderingShowFeatures[i], SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteCloudRenderingPanel()));
connect(_3dRenderingShowFrustums[i], SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteCloudRenderingPanel())); connect(_3dRenderingShowFrustums[i], SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteCloudRenderingPanel()));
@@ -1256,6 +1261,7 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
_ui->spinBox_maxOdomCacheSize->setObjectName(Parameters::kRGBDMaxOdomCacheSize().c_str()); _ui->spinBox_maxOdomCacheSize->setObjectName(Parameters::kRGBDMaxOdomCacheSize().c_str());
_ui->checkbox_localizationSmoothing->setObjectName(Parameters::kRGBDLocalizationSmoothing().c_str()); _ui->checkbox_localizationSmoothing->setObjectName(Parameters::kRGBDLocalizationSmoothing().c_str());
_ui->doubleSpinBox_localizationPriorError->setObjectName(Parameters::kRGBDLocalizationPriorError().c_str()); _ui->doubleSpinBox_localizationPriorError->setObjectName(Parameters::kRGBDLocalizationPriorError().c_str());
_ui->checkbox_localizationSecondTryWithoutProximityLinks->setObjectName(Parameters::kRGBDLocalizationSecondTryWithoutProximityLinks().c_str());
// Registration // Registration
_ui->reg_repeatOnce->setObjectName(Parameters::kRegRepeatOnce().c_str()); _ui->reg_repeatOnce->setObjectName(Parameters::kRegRepeatOnce().c_str());
@@ -2029,6 +2035,7 @@ void PreferencesDialog::resetSettings(QGroupBox * groupBox)
_3dRenderingMaxDepth[i]->setValue(0.0); _3dRenderingMaxDepth[i]->setValue(0.0);
_3dRenderingMinDepth[i]->setValue(0.0); _3dRenderingMinDepth[i]->setValue(0.0);
_3dRenderingRoiRatios[i]->setText("0.0 0.0 0.0 0.0"); _3dRenderingRoiRatios[i]->setText("0.0 0.0 0.0 0.0");
_3dRenderingDepthConfidenceThr[i]->setValue(0);
_3dRenderingShowScans[i]->setChecked(true); _3dRenderingShowScans[i]->setChecked(true);
_3dRenderingShowFeatures[i]->setChecked(i==0?false:true); _3dRenderingShowFeatures[i]->setChecked(i==0?false:true);
_3dRenderingShowFrustums[i]->setChecked(false); _3dRenderingShowFrustums[i]->setChecked(false);
@@ -2547,6 +2554,7 @@ void PreferencesDialog::readGuiSettings(const QString & filePath)
_3dRenderingMaxDepth[i]->setValue(settings.value(QString("maxDepth%1").arg(i), _3dRenderingMaxDepth[i]->value()).toDouble()); _3dRenderingMaxDepth[i]->setValue(settings.value(QString("maxDepth%1").arg(i), _3dRenderingMaxDepth[i]->value()).toDouble());
_3dRenderingMinDepth[i]->setValue(settings.value(QString("minDepth%1").arg(i), _3dRenderingMinDepth[i]->value()).toDouble()); _3dRenderingMinDepth[i]->setValue(settings.value(QString("minDepth%1").arg(i), _3dRenderingMinDepth[i]->value()).toDouble());
_3dRenderingRoiRatios[i]->setText(settings.value(QString("roiRatios%1").arg(i), _3dRenderingRoiRatios[i]->text()).toString()); _3dRenderingRoiRatios[i]->setText(settings.value(QString("roiRatios%1").arg(i), _3dRenderingRoiRatios[i]->text()).toString());
_3dRenderingDepthConfidenceThr[i]->setValue(settings.value(QString("depthConf%1").arg(i), _3dRenderingDepthConfidenceThr[i]->value()).toInt());
_3dRenderingShowScans[i]->setChecked(settings.value(QString("showScans%1").arg(i), _3dRenderingShowScans[i]->isChecked()).toBool()); _3dRenderingShowScans[i]->setChecked(settings.value(QString("showScans%1").arg(i), _3dRenderingShowScans[i]->isChecked()).toBool());
_3dRenderingShowFeatures[i]->setChecked(settings.value(QString("showFeatures%1").arg(i), _3dRenderingShowFeatures[i]->isChecked()).toBool()); _3dRenderingShowFeatures[i]->setChecked(settings.value(QString("showFeatures%1").arg(i), _3dRenderingShowFeatures[i]->isChecked()).toBool());
_3dRenderingShowFrustums[i]->setChecked(settings.value(QString("showFrustums%1").arg(i), _3dRenderingShowFrustums[i]->isChecked()).toBool()); _3dRenderingShowFrustums[i]->setChecked(settings.value(QString("showFrustums%1").arg(i), _3dRenderingShowFrustums[i]->isChecked()).toBool());
@@ -3155,6 +3163,7 @@ void PreferencesDialog::writeGuiSettings(const QString & filePath) const
settings.setValue(QString("maxDepth%1").arg(i), _3dRenderingMaxDepth[i]->value()); settings.setValue(QString("maxDepth%1").arg(i), _3dRenderingMaxDepth[i]->value());
settings.setValue(QString("minDepth%1").arg(i), _3dRenderingMinDepth[i]->value()); settings.setValue(QString("minDepth%1").arg(i), _3dRenderingMinDepth[i]->value());
settings.setValue(QString("roiRatios%1").arg(i), _3dRenderingRoiRatios[i]->text()); settings.setValue(QString("roiRatios%1").arg(i), _3dRenderingRoiRatios[i]->text());
settings.setValue(QString("depthConf%1").arg(i), _3dRenderingDepthConfidenceThr[i]->value());
settings.setValue(QString("showScans%1").arg(i), _3dRenderingShowScans[i]->isChecked()); settings.setValue(QString("showScans%1").arg(i), _3dRenderingShowScans[i]->isChecked());
settings.setValue(QString("showFeatures%1").arg(i), _3dRenderingShowFeatures[i]->isChecked()); settings.setValue(QString("showFeatures%1").arg(i), _3dRenderingShowFeatures[i]->isChecked());
settings.setValue(QString("showFrustums%1").arg(i), _3dRenderingShowFrustums[i]->isChecked()); settings.setValue(QString("showFrustums%1").arg(i), _3dRenderingShowFrustums[i]->isChecked());
@@ -6104,6 +6113,11 @@ std::vector<float> PreferencesDialog::getCloudRoiRatios(int index) const
} }
return roiRatios; return roiRatios;
} }
unsigned char PreferencesDialog::getCloudConfidenceThr(int index) const
{
UASSERT(index >= 0 && index <= 1);
return (unsigned char)_3dRenderingDepthConfidenceThr[index]->value();
}
int PreferencesDialog::getCloudColorScheme(int index) const int PreferencesDialog::getCloudColorScheme(int index) const
{ {
UASSERT(index >= 0 && index <= 1); UASSERT(index >= 0 && index <= 1);
+261 -203
View File
@@ -61,7 +61,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>419</width> <width>307</width>
<height>389</height> <height>389</height>
</rect> </rect>
</property> </property>
@@ -392,7 +392,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>418</width> <width>306</width>
<height>389</height> <height>389</height>
</rect> </rect>
</property> </property>
@@ -1643,7 +1643,7 @@
<item> <item>
<widget class="QToolBox" name="toolBox"> <widget class="QToolBox" name="toolBox">
<property name="currentIndex"> <property name="currentIndex">
<number>2</number> <number>1</number>
</property> </property>
<widget class="QWidget" name="page_3"> <widget class="QWidget" name="page_3">
<property name="geometry"> <property name="geometry">
@@ -1805,9 +1805,9 @@
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>-316</y>
<width>276</width> <width>518</width>
<height>1201</height> <height>1071</height>
</rect> </rect>
</property> </property>
<attribute name="label"> <attribute name="label">
@@ -1816,24 +1816,57 @@
<layout class="QVBoxLayout" name="verticalLayout_16"> <layout class="QVBoxLayout" name="verticalLayout_16">
<item> <item>
<layout class="QGridLayout" name="gridLayout_9" columnstretch="0,0"> <layout class="QGridLayout" name="gridLayout_9" columnstretch="0,0">
<item row="6" column="1"> <item row="3" column="1">
<widget class="QLabel" name="label_53"> <widget class="QLabel" name="label_octomap_empty_3">
<property name="text"> <property name="text">
<string>OctoMap</string> <string>Ground cell color</string>
</property>
</widget>
</item>
<item row="15" column="1">
<widget class="QLabel" name="label_57">
<property name="text">
<string>Crop radius when filtering empty space from 2d occupancy grid.</string>
</property> </property>
<property name="wordWrap"> <property name="wordWrap">
<bool>true</bool> <bool>true</bool>
</property> </property>
</widget> </widget>
</item> </item>
<item row="15" column="0"> <item row="14" column="1">
<widget class="QLabel" name="label_61">
<property name="text">
<string>Minimum depth confidence.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="18" column="1">
<widget class="QLabel" name="label_59">
<property name="text">
<string>Show probabilistic occupancy grid in Graph View.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="11" column="0">
<widget class="QCheckBox" name="checkBox_grid_regenerateFromSavedGrid">
<property name="text">
<string/>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="checkBox_grid_empty">
<property name="text">
<string/>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="17" column="0">
<widget class="QSpinBox" name="spinBox_cropRadius"> <widget class="QSpinBox" name="spinBox_cropRadius">
<property name="suffix"> <property name="suffix">
<string> pixels</string> <string> pixels</string>
@@ -1843,13 +1876,13 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="16" column="0"> <item row="20" column="1">
<widget class="QCheckBox" name="checkBox_grid_showProbMap"> <widget class="QLabel" name="label_logger_level_2">
<property name="text"> <property name="text">
<string/> <string>For stereo data, show disparity instead of right image in main views.</string>
</property> </property>
<property name="checked"> <property name="wordWrap">
<bool>false</bool> <bool>true</bool>
</property> </property>
</widget> </widget>
</item> </item>
@@ -1869,33 +1902,17 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="10" column="0"> <item row="5" column="0">
<widget class="QSpinBox" name="spinBox_grid_depth"> <layout class="QHBoxLayout" name="horizontalLayout_17">
<property name="prefix">
<string/>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>16</number>
</property>
<property name="value">
<number>16</number>
</property>
</widget>
</item>
<item row="3" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_9">
<item> <item>
<widget class="QToolButton" name="toolButton_groundColor"> <widget class="QToolButton" name="toolButton_frontierColor">
<property name="text"> <property name="text">
<string>...</string> <string>...</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QLineEdit" name="lineEdit_groundColor"> <widget class="QLineEdit" name="lineEdit_frontierColor">
<property name="readOnly"> <property name="readOnly">
<bool>true</bool> <bool>true</bool>
</property> </property>
@@ -1903,18 +1920,18 @@
</item> </item>
</layout> </layout>
</item> </item>
<item row="9" column="1"> <item row="17" column="1">
<widget class="QLabel" name="label_octomap_cubes"> <widget class="QLabel" name="label_57">
<property name="text"> <property name="text">
<string>OctoMap: Rendering type</string> <string>Crop radius when filtering empty space from 2d occupancy grid.</string>
</property> </property>
<property name="wordWrap"> <property name="wordWrap">
<bool>true</bool> <bool>true</bool>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="0"> <item row="18" column="0">
<widget class="QCheckBox" name="checkBox_grid_frontiers"> <widget class="QCheckBox" name="checkBox_grid_showProbMap">
<property name="text"> <property name="text">
<string/> <string/>
</property> </property>
@@ -1923,10 +1940,20 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="14" column="1"> <item row="19" column="1">
<widget class="QLabel" name="label_54"> <widget class="QLabel" name="label_60">
<property name="text"> <property name="text">
<string>Voxel size (for clouds and scans)</string> <string>Create RGB-D cloud from RGB projection on scan.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="11" column="1">
<widget class="QLabel" name="label_55">
<property name="text">
<string>Local grid: regenerate from saved grid instead of sensors</string>
</property> </property>
<property name="wordWrap"> <property name="wordWrap">
<bool>true</bool> <bool>true</bool>
@@ -1943,20 +1970,13 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="11" column="0"> <item row="9" column="1">
<widget class="QCheckBox" name="checkBox_grid_regenerateFromSavedGrid"> <widget class="QLabel" name="label_octomap_cubes">
<property name="text"> <property name="text">
<string/> <string>OctoMap: Rendering type</string>
</property> </property>
<property name="checked"> <property name="wordWrap">
<bool>false</bool> <bool>true</bool>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QCheckBox" name="checkBox_octomap">
<property name="text">
<string/>
</property> </property>
</widget> </widget>
</item> </item>
@@ -1980,8 +2000,8 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="18" column="0"> <item row="1" column="0">
<widget class="QCheckBox" name="checkBox_showDisparityInsteadOfRight"> <widget class="QCheckBox" name="checkBox_grid_frontiers">
<property name="text"> <property name="text">
<string/> <string/>
</property> </property>
@@ -1990,105 +2010,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="16" column="1"> <item row="19" column="0">
<widget class="QLabel" name="label_59">
<property name="text">
<string>Show probabilistic occupancy grid in Graph View.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="18" column="1">
<widget class="QLabel" name="label_logger_level_2">
<property name="text">
<string>For stereo data, show disparity instead of right image in main views.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="label_octomap_empty_3">
<property name="text">
<string>Ground cell color</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="12" column="0">
<widget class="QDoubleSpinBox" name="doubleSpinBox_gainCompensationRadius">
<property name="suffix">
<string> m</string>
</property>
<property name="decimals">
<number>2</number>
</property>
<property name="minimum">
<double>0.000000000000000</double>
</property>
<property name="maximum">
<double>10.000000000000000</double>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLabel" name="label_octomap_empty_4">
<property name="text">
<string>Empty cell color</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_12">
<item>
<widget class="QToolButton" name="toolButton_emptyColor">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit_emptyColor">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_11">
<item>
<widget class="QToolButton" name="toolButton_obstacleColor">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit_obstacleColor">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="17" column="0">
<widget class="QCheckBox" name="checkBox_cameraProjection"> <widget class="QCheckBox" name="checkBox_cameraProjection">
<property name="text"> <property name="text">
<string/> <string/>
@@ -2098,20 +2020,10 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="0"> <item row="0" column="1">
<widget class="QCheckBox" name="checkBox_grid_empty"> <widget class="QLabel" name="label_octomap_empty">
<property name="text"> <property name="text">
<string/> <string>Show empty space</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="11" column="1">
<widget class="QLabel" name="label_55">
<property name="text">
<string>Local grid: regenerate from saved grid instead of sensors</string>
</property> </property>
<property name="wordWrap"> <property name="wordWrap">
<bool>true</bool> <bool>true</bool>
@@ -2128,20 +2040,17 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="17" column="1"> <item row="6" column="1">
<widget class="QLabel" name="label_60"> <widget class="QLabel" name="label_53">
<property name="text"> <property name="text">
<string>Create RGB-D cloud from RGB projection on scan.</string> <string>OctoMap</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="1"> <item row="16" column="1">
<widget class="QLabel" name="label_octomap_empty"> <widget class="QLabel" name="label_54">
<property name="text"> <property name="text">
<string>Show empty space</string> <string>Voxel size (for clouds and scans)</string>
</property> </property>
<property name="wordWrap"> <property name="wordWrap">
<bool>true</bool> <bool>true</bool>
@@ -2167,6 +2076,64 @@
</item> </item>
</widget> </widget>
</item> </item>
<item row="10" column="0">
<widget class="QSpinBox" name="spinBox_grid_depth">
<property name="prefix">
<string/>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>16</number>
</property>
<property name="value">
<number>16</number>
</property>
</widget>
</item>
<item row="12" column="0">
<widget class="QDoubleSpinBox" name="doubleSpinBox_gainCompensationRadius">
<property name="suffix">
<string> m</string>
</property>
<property name="decimals">
<number>2</number>
</property>
<property name="minimum">
<double>0.000000000000000</double>
</property>
<property name="maximum">
<double>10.000000000000000</double>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLabel" name="label_octomap_frontiers_3">
<property name="text">
<string>Frontier cell color</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLabel" name="label_octomap_empty_4">
<property name="text">
<string>Empty cell color</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="13" column="1"> <item row="13" column="1">
<widget class="QLabel" name="label_56"> <widget class="QLabel" name="label_56">
<property name="text"> <property name="text">
@@ -2177,7 +2144,32 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="14" column="0"> <item row="6" column="0">
<widget class="QCheckBox" name="checkBox_octomap">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="3" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_9">
<item>
<widget class="QToolButton" name="toolButton_groundColor">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit_groundColor">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="16" column="0">
<widget class="QDoubleSpinBox" name="doubleSpinBox_voxelSize"> <widget class="QDoubleSpinBox" name="doubleSpinBox_voxelSize">
<property name="suffix"> <property name="suffix">
<string> m</string> <string> m</string>
@@ -2199,27 +2191,17 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="5" column="1"> <item row="2" column="0">
<widget class="QLabel" name="label_octomap_frontiers_3"> <layout class="QHBoxLayout" name="horizontalLayout_11">
<property name="text">
<string>Frontier cell color</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="5" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_17">
<item> <item>
<widget class="QToolButton" name="toolButton_frontierColor"> <widget class="QToolButton" name="toolButton_obstacleColor">
<property name="text"> <property name="text">
<string>...</string> <string>...</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QLineEdit" name="lineEdit_frontierColor"> <widget class="QLineEdit" name="lineEdit_obstacleColor">
<property name="readOnly"> <property name="readOnly">
<bool>true</bool> <bool>true</bool>
</property> </property>
@@ -2227,6 +2209,82 @@
</item> </item>
</layout> </layout>
</item> </item>
<item row="20" column="0">
<widget class="QCheckBox" name="checkBox_showDisparityInsteadOfRight">
<property name="text">
<string/>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item row="4" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_12">
<item>
<widget class="QToolButton" name="toolButton_emptyColor">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit_emptyColor">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="15" column="1">
<widget class="QLabel" name="label_62">
<property name="text">
<string>Depth's edge bleeding filtering error.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="15" column="0">
<widget class="QDoubleSpinBox" name="doubleSpinBox_depthEdgeBleedingError">
<property name="suffix">
<string> m</string>
</property>
<property name="decimals">
<number>2</number>
</property>
<property name="minimum">
<double>0.000000000000000</double>
</property>
<property name="maximum">
<double>10.000000000000000</double>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
</widget>
</item>
<item row="14" column="0">
<widget class="QSpinBox" name="spinBox_depthConfidence">
<property name="suffix">
<string> %</string>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="value">
<number>0</number>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
<item> <item>
@@ -2468,7 +2526,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>294</width> <width>296</width>
<height>272</height> <height>272</height>
</rect> </rect>
</property> </property>
@@ -2642,8 +2700,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>181</width> <width>428</width>
<height>485</height> <height>196</height>
</rect> </rect>
</property> </property>
<attribute name="label"> <attribute name="label">
+1 -1
View File
@@ -141,7 +141,7 @@
<item row="1" column="0"> <item row="1" column="0">
<widget class="QSpinBox" name="sba_iterations"> <widget class="QSpinBox" name="sba_iterations">
<property name="minimum"> <property name="minimum">
<number>1</number> <number>0</number>
</property> </property>
<property name="maximum"> <property name="maximum">
<number>999999</number> <number>999999</number>
+267 -186
View File
@@ -6,7 +6,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>919</width> <width>895</width>
<height>869</height> <height>869</height>
</rect> </rect>
</property> </property>
@@ -23,9 +23,9 @@
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>
<y>-3199</y> <y>-654</y>
<width>885</width> <width>861</width>
<height>6183</height> <height>6498</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_13"> <layout class="QVBoxLayout" name="verticalLayout_13">
@@ -710,6 +710,26 @@
<layout class="QVBoxLayout" name="verticalLayout_14"> <layout class="QVBoxLayout" name="verticalLayout_14">
<item> <item>
<layout class="QGridLayout" name="gridLayout" columnstretch="0,0,1"> <layout class="QGridLayout" name="gridLayout" columnstretch="0,0,1">
<item row="3" column="1">
<widget class="QLineEdit" name="lineEdit_roiRatios"/>
</item>
<item row="2" column="2">
<widget class="QLabel" name="label_133">
<property name="text">
<string>3D cloud minimum depth.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QSpinBox" name="spinBox_fillDepthHolesError">
<property name="suffix">
<string> %</string>
</property>
</widget>
</item>
<item row="6" column="2"> <item row="6" column="2">
<widget class="QLabel" name="label_134"> <widget class="QLabel" name="label_134">
<property name="text"> <property name="text">
@@ -720,13 +740,10 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="2"> <item row="4" column="1">
<widget class="QLabel" name="label_135"> <widget class="QSpinBox" name="spinBox_fillDepthHoles">
<property name="text"> <property name="suffix">
<string>ROI ratios [left, right, top, bottom] between 0 and 1. Only generate 3D points for pixels inside the region of interest (RGB image).</string> <string> pixels</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property> </property>
</widget> </widget>
</item> </item>
@@ -749,21 +766,18 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="5" column="2"> <item row="3" column="2">
<widget class="QLabel" name="label_198"> <widget class="QLabel" name="label_135">
<property name="text"> <property name="text">
<string>Fill depth hole error.</string> <string>ROI ratios [left, right, top, bottom] between 0 and 1. Only generate 3D points for pixels inside the region of interest (RGB image).</string>
</property> </property>
<property name="wordWrap"> <property name="wordWrap">
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget> </widget>
</item> </item>
<item row="3" column="1"> <item row="6" column="1">
<widget class="QLineEdit" name="lineEdit_roiRatios"/> <widget class="QLineEdit" name="lineEdit_distortionModel"/>
</item> </item>
<item row="2" column="1"> <item row="2" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBox_minDepth"> <widget class="QDoubleSpinBox" name="doubleSpinBox_minDepth">
@@ -794,39 +808,6 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="8" column="1">
<widget class="QCheckBox" name="checkBox_subtraction">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QLineEdit" name="lineEdit_distortionModel"/>
</item>
<item row="8" column="2">
<widget class="QLabel" name="label_137">
<property name="text">
<string>Cloud subtraction. Superposed points from different nodes are filtered.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="QLabel" name="label_197">
<property name="text">
<string>Fill depth hole size (0 means no fill).</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="1" column="2"> <item row="1" column="2">
<widget class="QLabel" name="label_132"> <widget class="QLabel" name="label_132">
<property name="text"> <property name="text">
@@ -850,13 +831,6 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="5" column="1">
<widget class="QSpinBox" name="spinBox_fillDepthHolesError">
<property name="suffix">
<string> %</string>
</property>
</widget>
</item>
<item row="6" column="0"> <item row="6" column="0">
<widget class="QToolButton" name="toolButton_distortionModel"> <widget class="QToolButton" name="toolButton_distortionModel">
<property name="text"> <property name="text">
@@ -864,24 +838,57 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="7" column="1"> <item row="10" column="2">
<widget class="QCheckBox" name="checkBox_bilateral"> <widget class="QLabel" name="label_137">
<property name="text"> <property name="text">
<string/> <string>Cloud subtraction. Superposed points from different nodes are filtered.</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QLabel" name="label_133">
<property name="text">
<string>3D cloud minimum depth.</string>
</property> </property>
<property name="wordWrap"> <property name="wordWrap">
<bool>true</bool> <bool>true</bool>
</property> </property>
</widget> </widget>
</item> </item>
<item row="7" column="2"> <item row="5" column="2">
<widget class="QLabel" name="label_198">
<property name="text">
<string>Fill depth hole error.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="10" column="1">
<widget class="QCheckBox" name="checkBox_subtraction">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QCheckBox" name="checkBox_bilateral">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="QLabel" name="label_197">
<property name="text">
<string>Fill depth hole size (0 means no fill).</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="8" column="2">
<widget class="QLabel" name="label_136"> <widget class="QLabel" name="label_136">
<property name="text"> <property name="text">
<string>Bilateral filtering of the depth image. Reduce noise in depth images.</string> <string>Bilateral filtering of the depth image. Reduce noise in depth images.</string>
@@ -891,10 +898,52 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="1"> <item row="7" column="2">
<widget class="QSpinBox" name="spinBox_fillDepthHoles"> <widget class="QLabel" name="label_147">
<property name="text">
<string>Depth's edge bleeding filter error (0 means disabled). Reduce depth noise around edges.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBox_depthEdgeFiltering">
<property name="suffix"> <property name="suffix">
<string> pixels</string> <string> m</string>
</property>
<property name="decimals">
<number>2</number>
</property>
<property name="maximum">
<double>100.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>4.000000000000000</double>
</property>
</widget>
</item>
<item row="9" column="2">
<widget class="QLabel" name="label_149">
<property name="text">
<string>Minimum depth confidence: 0% is low confidence, 100% is high confidence. Ignored if no depth confidence images were recorded or if set to 0%.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QSpinBox" name="spinBox_depthConfidence">
<property name="suffix">
<string> %</string>
</property>
<property name="maximum">
<number>100</number>
</property> </property>
</widget> </widget>
</item> </item>
@@ -2012,100 +2061,30 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
<bool>false</bool> <bool>false</bool>
</property> </property>
<layout class="QGridLayout" name="gridLayout_20" columnstretch="0,0,0,1"> <layout class="QGridLayout" name="gridLayout_20" columnstretch="0,0,0,1">
<item row="7" column="2" colspan="2">
<widget class="QLabel" name="label_meshingTextureSize_14">
<property name="text">
<string>Distance to camera policy. The closest camera from a point is used to colorize the point. If disabled, the camera for which the point projection is the closest of the image center is used to colorize the point.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="9" column="2">
<widget class="QLabel" name="label_meshingTextureSize_18">
<property name="text">
<string>Recolor points from camera projection. This would be used to color laser scans with the cameras.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="6" column="1"> <item row="6" column="1">
<widget class="QCheckBox" name="checkBox_camProjDistanceToCamPolicy">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="4" column="2" colspan="2">
<widget class="QLabel" name="label_meshingTextureSize_16">
<property name="text">
<string>Decimation of camera resolution before projection. This can help to correctly estimate points hidden by other points, in case the point cloud is sparse.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="9" column="2" colspan="2">
<widget class="QLabel" name="label_camProjExportCamera">
<property name="text">
<string>ID format of the camera selected for each point.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="2" colspan="2">
<widget class="QLabel" name="label_meshingTextureSize_13">
<property name="text">
<string>Maximum distance from the camera for points to be colorized by this camera (0 means infinite).</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QSpinBox" name="spinBox_camProjDecimation">
<property name="suffix">
<string/>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>9999</number>
</property>
<property name="singleStep">
<number>1</number>
</property>
<property name="value">
<number>1</number>
</property>
</widget>
</item>
<item row="1" column="2" colspan="2">
<widget class="QLabel" name="label_meshingTextureSize_17">
<property name="text">
<string>ROI ratios [left right top bottom] between 0 and 1. This can be used to ignore black borders of RGB images caused by calibration. </string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="2" colspan="2">
<widget class="QLabel" name="label_meshingTextureSize_12">
<property name="text">
<string>Maximum angle between camera and point's normal to apply color (0 means disabled).</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QCheckBox" name="checkBox_camProjRecolorPoints">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLineEdit" name="lineEdit_camProjMaskFilePath"/> <widget class="QLineEdit" name="lineEdit_camProjMaskFilePath"/>
</item> </item>
<item row="7" column="1"> <item row="10" column="1">
<widget class="QCheckBox" name="checkBox_camProjKeepPointsNotSeenByCameras">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QComboBox" name="comboBox_camProjExportCamera"> <widget class="QComboBox" name="comboBox_camProjExportCamera">
<property name="toolTip"> <property name="toolTip">
<string>By Node ID: cameras of same node have same ID <string>By Node ID: cameras of same node have same ID
@@ -2134,18 +2113,56 @@ By Node ID and Camera Index: NodeID*10+CameraIndex</string>
</item> </item>
</widget> </widget>
</item> </item>
<item row="6" column="2" colspan="2"> <item row="9" column="1">
<widget class="QLabel" name="label_meshingTextureSize_14"> <widget class="QCheckBox" name="checkBox_camProjRecolorPoints">
<property name="text"> <property name="text">
<string>Distance to camera policy. The closest camera from a point is used to colorize the point. If disabled, the camera for which the point projection is the closest of the image center is used to colorize the point.</string> <string/>
</property>
</widget>
</item>
<item row="2" column="2" colspan="2">
<widget class="QLabel" name="label_meshingTextureSize_13">
<property name="text">
<string>Maximum distance from the camera for points to be colorized by this camera (0 means infinite).</string>
</property> </property>
<property name="wordWrap"> <property name="wordWrap">
<bool>true</bool> <bool>true</bool>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item row="8" column="1">
<widget class="QLineEdit" name="lineEdit_camProjRoiRatios"/> <widget class="QCheckBox" name="checkBox_camProjKeepPointsNotSeenByCameras">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="2" colspan="2">
<widget class="QLabel" name="label_meshingTextureSize_17">
<property name="text">
<string>ROI ratios [left right top bottom] between 0 and 1. This can be used to ignore black borders of RGB images caused by calibration. </string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QToolButton" name="toolButton_camProjMaskFilePath">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item row="5" column="2" colspan="2">
<widget class="QLabel" name="label_meshingTextureSize_16">
<property name="text">
<string>Decimation of camera resolution before projection. This can help to correctly estimate points hidden by other points, in case the point cloud is sparse.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item> </item>
<item row="3" column="1"> <item row="3" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBox_camProjMaxAngle"> <widget class="QDoubleSpinBox" name="doubleSpinBox_camProjMaxAngle">
@@ -2169,6 +2186,65 @@ By Node ID and Camera Index: NodeID*10+CameraIndex</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="1">
<widget class="QLineEdit" name="lineEdit_camProjRoiRatios"/>
</item>
<item row="5" column="1">
<widget class="QSpinBox" name="spinBox_camProjDecimation">
<property name="suffix">
<string/>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>9999</number>
</property>
<property name="singleStep">
<number>1</number>
</property>
<property name="value">
<number>1</number>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QCheckBox" name="checkBox_camProjDistanceToCamPolicy">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="6" column="2" colspan="2">
<widget class="QLabel" name="label_meshingTextureSize_19">
<property name="text">
<string>File path for a mask. Format should be 8-bits grayscale. The mask should cover all cameras in case multi-camera is used and have the same resolution.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="2" colspan="2">
<widget class="QLabel" name="label_meshingTextureSize_12">
<property name="text">
<string>Maximum angle between camera and point's normal to apply color (0 means disabled).</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="10" column="2" colspan="2">
<widget class="QLabel" name="label_camProjExportCamera">
<property name="text">
<string>ID format of the camera selected for each point.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="1"> <item row="2" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBox_camProjMaxDistance"> <widget class="QDoubleSpinBox" name="doubleSpinBox_camProjMaxDistance">
<property name="suffix"> <property name="suffix">
@@ -2191,7 +2267,7 @@ By Node ID and Camera Index: NodeID*10+CameraIndex</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="7" column="2" colspan="2"> <item row="8" column="2" colspan="2">
<widget class="QLabel" name="label_meshingTextureSize_15"> <widget class="QLabel" name="label_meshingTextureSize_15">
<property name="text"> <property name="text">
<string>Keep points not seen by the cameras. These points will be set with a pure red color (255,0,0) if the cloud was created from laser scans.</string> <string>Keep points not seen by the cameras. These points will be set with a pure red color (255,0,0) if the cloud was created from laser scans.</string>
@@ -2201,33 +2277,38 @@ By Node ID and Camera Index: NodeID*10+CameraIndex</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="8" column="2"> <item row="4" column="1">
<widget class="QLabel" name="label_meshingTextureSize_18"> <widget class="QDoubleSpinBox" name="doubleSpinBox_camProjMaxDepthError">
<property name="text"> <property name="suffix">
<string>Recolor points from camera projection. This would be used to color laser scans with the cameras.</string> <string> m</string>
</property> </property>
<property name="wordWrap"> <property name="decimals">
<bool>true</bool> <number>2</number>
</property>
<property name="minimum">
<double>0.000000000000000</double>
</property>
<property name="maximum">
<double>9.990000000000000</double>
</property>
<property name="singleStep">
<double>0.050000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property> </property>
</widget> </widget>
</item> </item>
<item row="5" column="2" colspan="2"> <item row="4" column="2" colspan="2">
<widget class="QLabel" name="label_meshingTextureSize_19"> <widget class="QLabel" name="label_meshingTextureSize_20">
<property name="text"> <property name="text">
<string>File path for a mask. Format should be 8-bits grayscale. The mask should cover all cameras in case multi-camera is used and have the same resolution.</string> <string>For all points registered to same pixel, only those close enough to the closest point will be colored with same color (0 means only the closest point of all points registered in same pixel is colored).</string>
</property> </property>
<property name="wordWrap"> <property name="wordWrap">
<bool>true</bool> <bool>true</bool>
</property> </property>
</widget> </widget>
</item> </item>
<item row="5" column="0">
<widget class="QToolButton" name="toolButton_camProjMaskFilePath">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -1,7 +1,7 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<package format="2"> <package format="2">
<name>rtabmap</name> <name>rtabmap</name>
<version>0.21.13</version> <version>0.22.0</version>
<description>RTAB-Map's standalone library. RTAB-Map is a RGB-D SLAM approach with real-time constraints.</description> <description>RTAB-Map's standalone library. RTAB-Map is a RGB-D SLAM approach with real-time constraints.</description>
<maintainer email="matlabbe@gmail.com">Mathieu Labbe</maintainer> <maintainer email="matlabbe@gmail.com">Mathieu Labbe</maintainer>
<author>Mathieu Labbe</author> <author>Mathieu Labbe</author>
@@ -16,6 +16,7 @@
<depend>cv_bridge</depend> <depend>cv_bridge</depend>
<depend>libg2o</depend> <depend>libg2o</depend>
<depend>gtsam</depend> <depend>gtsam</depend>
<depend>tbb</depend> <!-- till tbb is added to gtsam dependencies https://github.com/borglab/gtsam/issues/1759 -->
<!-- <depend>libopenni2-dev</depend> --> <!-- not available on Jessie --> <!-- <depend>libopenni2-dev</depend> --> <!-- not available on Jessie -->
<depend>libpcl-all-dev</depend> <!-- include libvtk-qt --> <depend>libpcl-all-dev</depend> <!-- include libvtk-qt -->
<depend>libpointmatcher</depend> <!-- optional but recommended if lidar is used, also not available on 32 bits system, but rtabmap can be built without it --> <depend>libpointmatcher</depend> <!-- optional but recommended if lidar is used, also not available on 32 bits system, but rtabmap can be built without it -->
+30
View File
@@ -31,6 +31,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <rtabmap/core/CameraRGBD.h> #include <rtabmap/core/CameraRGBD.h>
#include <rtabmap/core/CameraStereo.h> #include <rtabmap/core/CameraStereo.h>
#include <rtabmap/core/Camera.h> #include <rtabmap/core/Camera.h>
#include <rtabmap/core/SensorEvent.h>
#include <rtabmap/core/DBReader.h> #include <rtabmap/core/DBReader.h>
#include <rtabmap/core/SensorCaptureThread.h> #include <rtabmap/core/SensorCaptureThread.h>
#include <rtabmap/core/SensorCaptureThread.h> #include <rtabmap/core/SensorCaptureThread.h>
@@ -71,6 +72,31 @@ void sighandler(int sig)
} }
} }
// Detect when we reached end-of-files
class StatusHandler: public UEventsHandler{
protected:
virtual bool handleEvent(UEvent * event)
{
if(event->getClassName().compare("SensorEvent") == 0)
{
SensorEvent * camEvent = (SensorEvent*)event;
if(camEvent->getCode() == SensorEvent::kCodeNoMoreImages)
{
printf("End of stream reached...\n");
if(cam)
{
cam->join(true);
}
if(app)
{
QMetaObject::invokeMethod(app, "quit");
}
}
}
return false;
}
};
int main (int argc, char * argv[]) int main (int argc, char * argv[])
{ {
ULogger::setType(ULogger::kTypeConsole); ULogger::setType(ULogger::kTypeConsole);
@@ -138,6 +164,10 @@ int main (int argc, char * argv[])
signal(SIGTERM, &sighandler); signal(SIGTERM, &sighandler);
signal(SIGINT, &sighandler); signal(SIGINT, &sighandler);
// Catch end of stream to close the gui
StatusHandler statusHandler;
statusHandler.registerToEventsManager();
rtabmap::Camera * camera = dialog.createCamera(); rtabmap::Camera * camera = dialog.createCamera();
if(camera == 0) if(camera == 0)
{ {
+107 -15
View File
@@ -97,7 +97,7 @@ void showUsage()
" considered blurred. 0 means disabled. 50 can be good default.\n" " considered blurred. 0 means disabled. 50 can be good default.\n"
" --cam_projection Camera projection on assembled cloud and export node ID on each point (in PointSourceId field).\n" " --cam_projection Camera projection on assembled cloud and export node ID on each point (in PointSourceId field).\n"
" --cam_projection_keep_all Keep not colored points from cameras (node ID will be 0 and color will be red).\n" " --cam_projection_keep_all Keep not colored points from cameras (node ID will be 0 and color will be red).\n"
" --cam_projection_decimation Decimate images before projecting the points.\n" " --cam_projection_decimation # Decimate images before projecting the points.\n"
" --cam_projection_mask \"\" File path for a mask. Format should be 8-bits grayscale. The mask should\n" " --cam_projection_mask \"\" File path for a mask. Format should be 8-bits grayscale. The mask should\n"
" cover all cameras in case multi-camera is used and have the same resolution.\n" " cover all cameras in case multi-camera is used and have the same resolution.\n"
" --opt # Optimization approach:\n" " --opt # Optimization approach:\n"
@@ -106,9 +106,10 @@ void showUsage()
" 2=Use optimized poses already computed in the database instead\n" " 2=Use optimized poses already computed in the database instead\n"
" of re-computing them (fallback to default if optimized poses don't exist).\n" " of re-computing them (fallback to default if optimized poses don't exist).\n"
" 3=No optimization, use odometry poses directly.\n" " 3=No optimization, use odometry poses directly.\n"
" --poses Export optimized poses of the robot frame (e.g., base_link).\n" " --poses Export optimized poses of the robot frame (e.g., base_link), including landmarks.\n"
" --poses_camera Export optimized poses of the camera frame (e.g., optical frame).\n" " --poses_camera Export optimized poses of the camera frame (e.g., optical frame).\n"
" --poses_scan Export optimized poses of the scan frame.\n" " --poses_scan Export optimized poses of the scan frame.\n"
" --poses_landmark Export optimized poses of landmarks.\n"
" --poses_gt Export ground truth poses of the robot frame (e.g., base_link).\n" " --poses_gt Export ground truth poses of the robot frame (e.g., base_link).\n"
" --poses_gps Export GPS poses of the GPS frame in local coordinates.\n" " --poses_gps Export GPS poses of the GPS frame in local coordinates.\n"
" --poses_format # Format used for exported poses (default is 11):\n" " --poses_format # Format used for exported poses (default is 11):\n"
@@ -152,6 +153,8 @@ void showUsage()
" --min_range # Minimum range of the created clouds (default 0 m).\n" " --min_range # Minimum range of the created clouds (default 0 m).\n"
" --max_range # Maximum range of the created clouds (default 4 m, 0 m with --scan).\n" " --max_range # Maximum range of the created clouds (default 4 m, 0 m with --scan).\n"
" --decimation # Depth image decimation before creating the clouds (default 4, 1 with --scan).\n" " --decimation # Depth image decimation before creating the clouds (default 4, 1 with --scan).\n"
" --edge_bleeding_error # Depth's edge bleeding filtering error (default 0 m).\n"
" --depth_confidence # Depth confidence threshold (should be in [0,100]) (default 0=Low).\n"
" --voxel # Voxel size of the created clouds (default 0.01 m, 0 m with --scan).\n" " --voxel # Voxel size of the created clouds (default 0.01 m, 0 m with --scan).\n"
" --ground_normals_up # Flip ground normals up if close to -z axis (default 0, 0=disabled, value should be >0 and <1, typical 0.9).\n" " --ground_normals_up # Flip ground normals up if close to -z axis (default 0, 0=disabled, value should be >0 and <1, typical 0.9).\n"
" --noise_radius # Noise filtering search radius (default 0, 0=disabled).\n" " --noise_radius # Noise filtering search radius (default 0, 0=disabled).\n"
@@ -213,6 +216,8 @@ int main(int argc, char * argv[])
float poissonSize = 0.03; float poissonSize = 0.03;
int maxPolygons = 300000; int maxPolygons = 300000;
int decimation = -1; int decimation = -1;
float depthEdgeBleedingFilterError = 0.0f;
unsigned char depthConfidenceThr = 0;
float minRange = 0.0f; float minRange = 0.0f;
float maxRange = -1.0f; float maxRange = -1.0f;
float voxelSize = -1.0f; float voxelSize = -1.0f;
@@ -252,6 +257,7 @@ int main(int argc, char * argv[])
bool exportPoses = false; bool exportPoses = false;
bool exportPosesCamera = false; bool exportPosesCamera = false;
bool exportPosesScan = false; bool exportPosesScan = false;
bool exportPosesLandmarks = false;
bool exportPosesGt = false; bool exportPosesGt = false;
bool exportPosesGps = false; bool exportPosesGps = false;
int exportPosesFormat = 11; int exportPosesFormat = 11;
@@ -498,6 +504,10 @@ int main(int argc, char * argv[])
{ {
exportPosesScan = true; exportPosesScan = true;
} }
else if(std::strcmp(argv[i], "--poses_landmark") == 0)
{
exportPosesLandmarks = true;
}
else if(std::strcmp(argv[i], "--poses_gt") == 0) else if(std::strcmp(argv[i], "--poses_gt") == 0)
{ {
exportPosesGt = true; exportPosesGt = true;
@@ -767,6 +777,30 @@ int main(int argc, char * argv[])
showUsage(); showUsage();
} }
} }
else if(std::strcmp(argv[i], "--edge_bleeding_error") == 0)
{
++i;
if(i<argc-1)
{
depthEdgeBleedingFilterError = uStr2Float(argv[i]);
}
else
{
showUsage();
}
}
else if(std::strcmp(argv[i], "--depth_confidence") == 0)
{
++i;
if(i<argc-1)
{
depthConfidenceThr = (unsigned char)uStr2Int(argv[i]);
}
else
{
showUsage();
}
}
else if(std::strcmp(argv[i], "--voxel") == 0) else if(std::strcmp(argv[i], "--voxel") == 0)
{ {
++i; ++i;
@@ -1079,6 +1113,7 @@ int main(int argc, char * argv[])
exportPoses || exportPoses ||
exportPosesScan || exportPosesScan ||
exportPosesCamera || exportPosesCamera ||
exportPosesLandmarks ||
exportPosesGt || exportPosesGt ||
exportPosesGps || exportPosesGps ||
exportGps>=0 || exportGps>=0 ||
@@ -1142,7 +1177,7 @@ int main(int argc, char * argv[])
std::multimap<int, Link> links; std::multimap<int, Link> links;
dbDriver->getAllOdomPoses(odomPoses, true); dbDriver->getAllOdomPoses(odomPoses, true);
dbDriver->getAllLinks(links, true, true); dbDriver->getAllLinks(links, true, true);
if(optimizationApproach == 3 || !(exportCloud || exportMesh || exportPoses || exportPosesCamera || exportPosesScan)) if(optimizationApproach == 3 || !(exportCloud || exportMesh || exportPoses || exportPosesCamera || exportPosesScan || exportPosesLandmarks))
{ {
// Just use odometry poses when exporting only images // Just use odometry poses when exporting only images
optimizedPoses = odomPoses; optimizedPoses = odomPoses;
@@ -1346,13 +1381,18 @@ int main(int argc, char * argv[])
pcl::PointCloud<pcl::PointXYZI>::Ptr assembledCloudI(new pcl::PointCloud<pcl::PointXYZI>); pcl::PointCloud<pcl::PointXYZI>::Ptr assembledCloudI(new pcl::PointCloud<pcl::PointXYZI>);
std::map<int, rtabmap::Transform> robotPoses; std::map<int, rtabmap::Transform> robotPoses;
std::vector<std::map<int, rtabmap::Transform> > cameraPoses; std::vector<std::map<int, rtabmap::Transform> > cameraPoses;
std::vector<std::map<int, double> > cameraStamps;
std::map<int, rtabmap::Transform> scanPoses; std::map<int, rtabmap::Transform> scanPoses;
std::map<int, double> scanStamps;
std::map<int, rtabmap::Transform> landmarkPoses;
std::map<int, double> landmarkStamps;
std::map<int, rtabmap::Transform> gtPoses; std::map<int, rtabmap::Transform> gtPoses;
std::map<int, double> gtStamps;
std::map<int, rtabmap::Transform> gpsPoses; std::map<int, rtabmap::Transform> gpsPoses;
std::map<int, double> gpsStamps; std::map<int, double> gpsStamps;
GPS gpsOrigin; GPS gpsOrigin;
std::map<int, rtabmap::GPS> gpsValues; std::map<int, rtabmap::GPS> gpsValues;
std::map<int, double> cameraStamps; std::map<int, double> robotStamps;
std::map<int, std::vector<rtabmap::CameraModel> > cameraModels; std::map<int, std::vector<rtabmap::CameraModel> > cameraModels;
std::map<int, cv::Mat> cameraDepths; std::map<int, cv::Mat> cameraDepths;
int imagesExported = 0; int imagesExported = 0;
@@ -1376,7 +1416,10 @@ int main(int argc, char * argv[])
{ {
// landmark, just add to list of poses // landmark, just add to list of poses
robotPoses.insert(*iter); robotPoses.insert(*iter);
cameraStamps.insert(std::make_pair(iter->first, 0)); robotStamps.insert(std::make_pair(iter->first, 0));
landmarkPoses.insert(*iter);
landmarkStamps.insert(std::make_pair(iter->first, 0));
continue; continue;
} }
@@ -1417,6 +1460,7 @@ int main(int argc, char * argv[])
bool densityFiltered = !densityPoses.empty() && densityPoses.find(iter->first) == densityPoses.end(); bool densityFiltered = !densityPoses.empty() && densityPoses.find(iter->first) == densityPoses.end();
cv::Mat rgb; cv::Mat rgb;
cv::Mat depth; cv::Mat depth;
cv::Mat confidence;
pcl::IndicesPtr indices(new std::vector<int>); pcl::IndicesPtr indices(new std::vector<int>);
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud; pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud;
pcl::PointCloud<pcl::PointXYZI>::Ptr cloudI; pcl::PointCloud<pcl::PointXYZI>::Ptr cloudI;
@@ -1425,7 +1469,7 @@ int main(int argc, char * argv[])
if(!densityFiltered && cloudFromScan && (exportCloud || exportMesh)) if(!densityFiltered && cloudFromScan && (exportCloud || exportMesh))
{ {
LaserScan scan; LaserScan scan;
data.uncompressData(exportImages?&rgb:0, (texture||exportImages)&&!data.depthOrRightCompressed().empty()?&depth:0, &scan); data.uncompressData(exportImages?&rgb:0, (texture||exportImages)&&!data.depthOrRightCompressed().empty()?&depth:0, &scan, 0, 0, 0, 0, exportImages?&confidence:0);
if(scan.empty()) if(scan.empty())
{ {
printf("Node %d doesn't have scan data, empty cloud is created.\n", iter->first); printf("Node %d doesn't have scan data, empty cloud is created.\n", iter->first);
@@ -1453,7 +1497,7 @@ int main(int argc, char * argv[])
} }
else else
{ {
data.uncompressData(&rgb, &depth); data.uncompressData(&rgb, &depth, 0, 0, 0, 0, 0, &confidence);
if(!densityFiltered && (exportCloud || exportMesh)) if(!densityFiltered && (exportCloud || exportMesh))
{ {
if(depth.empty()) if(depth.empty())
@@ -1461,12 +1505,20 @@ int main(int argc, char * argv[])
printf("Node %d doesn't have depth or stereo data, empty cloud is " printf("Node %d doesn't have depth or stereo data, empty cloud is "
"created (if you want to create point cloud from scan, use --scan option).\n", iter->first); "created (if you want to create point cloud from scan, use --scan option).\n", iter->first);
} }
else if(!data.depthRaw().empty() && depthEdgeBleedingFilterError>0.0f)
{
util2d::depthBleedingFiltering(depth, depthEdgeBleedingFilterError);
data.setRGBDImage(data.imageRaw(), depth, data.depthConfidenceRaw(), data.cameraModels());
}
cloud = util3d::cloudRGBFromSensorData( cloud = util3d::cloudRGBFromSensorData(
data, data,
decimation, // image decimation before creating the clouds decimation, // image decimation before creating the clouds
maxRange, // maximum depth of the cloud maxRange, // maximum depth of the cloud
minRange, minRange,
indices.get()); indices.get(),
ParametersMap(),
std::vector<float>(),
depthConfidenceThr);
if(noiseRadius>0.0f && noiseMinNeighbors>0) if(noiseRadius>0.0f && noiseMinNeighbors>0)
{ {
indices = util3d::radiusFiltering(cloud, indices, noiseRadius, noiseMinNeighbors); indices = util3d::radiusFiltering(cloud, indices, noiseRadius, noiseMinNeighbors);
@@ -1510,6 +1562,16 @@ int main(int argc, char * argv[])
outputPath=dir+"/"+(exportImagesId?uNumber2Str(iter->first):uFormat("%f", stamp))+ext; outputPath=dir+"/"+(exportImagesId?uNumber2Str(iter->first):uFormat("%f", stamp))+ext;
cv::imwrite(outputPath, depthExported); cv::imwrite(outputPath, depthExported);
} }
if(!confidence.empty())
{
dir = outputDirectory+"/"+baseName+"_confidence";
if(!UDirectory::exists(dir)) {
UDirectory::makeDir(dir);
}
outputPath=dir+"/"+(exportImagesId?uNumber2Str(iter->first):uFormat("%f", stamp))+".png";
cv::imwrite(outputPath, confidence);
}
// save calibration per image (calibration can change over time, e.g. camera has auto focus) // save calibration per image (calibration can change over time, e.g. camera has auto focus)
for(size_t i=0; i<models.size(); ++i) for(size_t i=0; i<models.size(); ++i)
@@ -1628,7 +1690,7 @@ int main(int argc, char * argv[])
} }
robotPoses.insert(std::make_pair(iter->first, iter->second)); robotPoses.insert(std::make_pair(iter->first, iter->second));
cameraStamps.insert(std::make_pair(iter->first, stamp)); robotStamps.insert(std::make_pair(iter->first, stamp));
if(models.empty() && weight == -1 && !cameraModels.empty()) if(models.empty() && weight == -1 && !cameraModels.empty())
{ {
// For intermediate nodes, use latest models // For intermediate nodes, use latest models
@@ -1645,17 +1707,20 @@ int main(int argc, char * argv[])
if(cameraPoses.empty()) if(cameraPoses.empty())
{ {
cameraPoses.resize(models.size()); cameraPoses.resize(models.size());
cameraStamps.resize(models.size());
} }
UASSERT_MSG(models.size() == cameraPoses.size(), "Not all nodes have same number of cameras to export camera poses."); UASSERT_MSG(models.size() == cameraPoses.size(), "Not all nodes have same number of cameras to export camera poses.");
for(size_t i=0; i<models.size(); ++i) for(size_t i=0; i<models.size(); ++i)
{ {
cameraPoses[i].insert(std::make_pair(iter->first, iter->second*models[i].localTransform())); cameraPoses[i].insert(std::make_pair(iter->first, iter->second*models[i].localTransform()));
cameraStamps[i].insert(std::make_pair(iter->first, stamp));
} }
} }
} }
if(exportPosesScan && !data.laserScanCompressed().empty()) if(exportPosesScan && !data.laserScanCompressed().empty())
{ {
scanPoses.insert(std::make_pair(iter->first, iter->second*data.laserScanCompressed().localTransform())); scanPoses.insert(std::make_pair(iter->first, iter->second*data.laserScanCompressed().localTransform()));
scanStamps.insert(std::make_pair(iter->first, stamp));
} }
if(exportPosesGps || exportGps>=0) if(exportPosesGps || exportGps>=0)
@@ -1688,6 +1753,7 @@ int main(int argc, char * argv[])
if(exportPosesGt && !gt.isNull()) if(exportPosesGt && !gt.isNull())
{ {
gtPoses.insert(std::make_pair(iter->first, gt)); gtPoses.insert(std::make_pair(iter->first, gt));
gtStamps.insert(std::make_pair(iter->first, stamp));
} }
if(optimizedPoses.size() >= 500) if(optimizedPoses.size() >= 500)
@@ -1750,11 +1816,11 @@ int main(int argc, char * argv[])
exportPosesFormat, exportPosesFormat,
std::map<int, Transform>(robotPoses.lower_bound(1), robotPoses.end()), std::map<int, Transform>(robotPoses.lower_bound(1), robotPoses.end()),
links, links,
std::map<int, double>(cameraStamps.lower_bound(1), cameraStamps.end())); std::map<int, double>(robotStamps.lower_bound(1), robotStamps.end()));
} }
else else
{ {
rtabmap::graph::exportPoses(outputPath, exportPosesFormat, robotPoses, links, cameraStamps); rtabmap::graph::exportPoses(outputPath, exportPosesFormat, robotPoses, links, robotStamps);
} }
cv::Vec3f vmin, vmax; cv::Vec3f vmin, vmax;
graph::computeMinMax(robotPoses, vmin, vmax); graph::computeMinMax(robotPoses, vmin, vmax);
@@ -1773,7 +1839,7 @@ int main(int argc, char * argv[])
outputPath = outputDirectory+"/"+baseName+"_camera_poses." + posesExt; outputPath = outputDirectory+"/"+baseName+"_camera_poses." + posesExt;
else else
outputPath = outputDirectory+"/"+baseName+"_camera_poses_"+uNumber2Str((int)i)+"." + posesExt; outputPath = outputDirectory+"/"+baseName+"_camera_poses_"+uNumber2Str((int)i)+"." + posesExt;
rtabmap::graph::exportPoses(outputPath, exportPosesFormat, cameraPoses[i], std::multimap<int, Link>(), cameraStamps); rtabmap::graph::exportPoses(outputPath, exportPosesFormat, cameraPoses[i], std::multimap<int, Link>(), cameraStamps[i]);
cv::Vec3f vmin, vmax; cv::Vec3f vmin, vmax;
graph::computeMinMax(cameraPoses[i], vmin, vmax); graph::computeMinMax(cameraPoses[i], vmin, vmax);
printf("%d camera poses exported to \"%s\". (min=[%f,%f,%f] max=[%f,%f,%f])\n", printf("%d camera poses exported to \"%s\". (min=[%f,%f,%f] max=[%f,%f,%f])\n",
@@ -1786,7 +1852,7 @@ int main(int argc, char * argv[])
if(exportPosesScan) if(exportPosesScan)
{ {
std::string outputPath=outputDirectory+"/"+baseName+"_scan_poses." + posesExt; std::string outputPath=outputDirectory+"/"+baseName+"_scan_poses." + posesExt;
rtabmap::graph::exportPoses(outputPath, exportPosesFormat, scanPoses, std::multimap<int, Link>(), cameraStamps); rtabmap::graph::exportPoses(outputPath, exportPosesFormat, scanPoses, std::multimap<int, Link>(), scanStamps);
cv::Vec3f min, max; cv::Vec3f min, max;
graph::computeMinMax(scanPoses, min, max); graph::computeMinMax(scanPoses, min, max);
printf("%d scan poses exported to \"%s\". (min=[%f,%f,%f] max=[%f,%f,%f])\n", printf("%d scan poses exported to \"%s\". (min=[%f,%f,%f] max=[%f,%f,%f])\n",
@@ -1795,6 +1861,30 @@ int main(int argc, char * argv[])
min[0], min[1], min[2], min[0], min[1], min[2],
max[0], max[1], max[2]); max[0], max[1], max[2]);
} }
if(exportPosesScan)
{
std::string outputPath=outputDirectory+"/"+baseName+"_scan_poses." + posesExt;
rtabmap::graph::exportPoses(outputPath, exportPosesFormat, scanPoses, std::multimap<int, Link>(), scanStamps);
cv::Vec3f min, max;
graph::computeMinMax(scanPoses, min, max);
printf("%d scan poses exported to \"%s\". (min=[%f,%f,%f] max=[%f,%f,%f])\n",
(int)scanPoses.size(),
outputPath.c_str(),
min[0], min[1], min[2],
max[0], max[1], max[2]);
}
if(exportPosesLandmarks)
{
std::string outputPath=outputDirectory+"/"+baseName+"_landmark_poses." + posesExt;
rtabmap::graph::exportPoses(outputPath, exportPosesFormat, landmarkPoses, std::multimap<int, Link>(), landmarkStamps);
cv::Vec3f min, max;
graph::computeMinMax(landmarkPoses, min, max);
printf("%d landmark poses exported to \"%s\". (min=[%f,%f,%f] max=[%f,%f,%f])\n",
(int)landmarkPoses.size(),
outputPath.c_str(),
min[0], min[1], min[2],
max[0], max[1], max[2]);
}
if(exportPosesGps) if(exportPosesGps)
{ {
std::string outputPath=outputDirectory+"/"+baseName+"_gps_poses." + posesExt; std::string outputPath=outputDirectory+"/"+baseName+"_gps_poses." + posesExt;
@@ -1806,7 +1896,7 @@ int main(int argc, char * argv[])
if(exportPosesGt) if(exportPosesGt)
{ {
std::string outputPath=outputDirectory+"/"+baseName+"_gt_poses." + posesExt; std::string outputPath=outputDirectory+"/"+baseName+"_gt_poses." + posesExt;
rtabmap::graph::exportPoses(outputPath, exportPosesFormat, gtPoses, std::multimap<int, Link>(), cameraStamps); rtabmap::graph::exportPoses(outputPath, exportPosesFormat, gtPoses, std::multimap<int, Link>(), gtStamps);
printf("%d scan poses exported to \"%s\".\n", printf("%d scan poses exported to \"%s\".\n",
(int)gtPoses.size(), (int)gtPoses.size(),
outputPath.c_str()); outputPath.c_str());
@@ -1999,7 +2089,7 @@ int main(int argc, char * argv[])
} }
depth = rtabmap::util2d::cvtDepthFromFloat(depth); depth = rtabmap::util2d::cvtDepthFromFloat(depth);
std::string outputPath=dir+"/"+(exportImagesId?uNumber2Str(iter->first):uFormat("%f",cameraStamps.at(iter->first)))+".png"; std::string outputPath=dir+"/"+(exportImagesId?uNumber2Str(iter->first):uFormat("%f",robotStamps.at(iter->first)))+".png";
cv::imwrite(outputPath, depth); cv::imwrite(outputPath, depth);
} }
} }
@@ -2027,6 +2117,7 @@ int main(int argc, char * argv[])
cameraModelsProj, cameraModelsProj,
textureRange, textureRange,
textureAngle, textureAngle,
textureDepthError,
textureRoiRatios, textureRoiRatios,
projMask, projMask,
distanceToCamPolicy, distanceToCamPolicy,
@@ -2040,6 +2131,7 @@ int main(int argc, char * argv[])
cameraModelsProj, cameraModelsProj,
textureRange, textureRange,
textureAngle, textureAngle,
textureDepthError,
textureRoiRatios, textureRoiRatios,
projMask, projMask,
distanceToCamPolicy, distanceToCamPolicy,
+1 -1
View File
@@ -119,7 +119,7 @@ int main(int argc, char * argv[])
printf("Global bundle adjustment...\n"); printf("Global bundle adjustment...\n");
Optimizer * optimizer = Optimizer::create(Optimizer::kTypeG2O, parameters); Optimizer * optimizer = Optimizer::create(Optimizer::kTypeG2O, parameters);
optimizedPoses = optimizer->optimizeBA(optimizedPoses.lower_bound(1)->first, optimizedPoses, links, nodes, true); optimizedPoses = optimizer->optimizeBA(optimizedPoses.lower_bound(1)->first, optimizedPoses, links, nodes, true, parameters);
delete optimizer; delete optimizer;
printf("Global bundle adjustment... done (%fs).\n", timer.ticks()); printf("Global bundle adjustment... done (%fs).\n", timer.ticks());
+2 -3
View File
@@ -1255,9 +1255,8 @@ int main(int argc, char * argv[])
t.r11(), t.r12(), t.r13(), t.x()*bestScale, t.r11(), t.r12(), t.r13(), t.x()*bestScale,
t.r21(), t.r22(), t.r23(), t.y()*bestScale, t.r21(), t.r22(), t.r23(), t.y()*bestScale,
t.r31(), t.r32(), t.r33(), t.z()*bestScale); t.r31(), t.r32(), t.r33(), t.z()*bestScale);
Transform diff = gtLink.inverse()*scaledLink; sumDist += gtLink.getDistance(scaledLink);
sumDist += diff.getNorm(); sumAngle += gtLink.getAngle(scaledLink);
sumAngle += diff.getAngle();
++count; ++count;
} }
} }
+15 -8
View File
@@ -1024,7 +1024,7 @@ int main(int argc, char * argv[])
UTimer iterationTime; UTimer iterationTime;
std::string status; std::string status;
if(!odometryIgnored && info.odomPose.isNull()) if(!odometryIgnored && info.odomPose.isNull() && incrementalMemory)
{ {
printf("Skipping node %d as it doesn't have odometry pose set.\n", data.id()); printf("Skipping node %d as it doesn't have odometry pose set.\n", data.id());
} }
@@ -1235,15 +1235,22 @@ int main(int argc, char * argv[])
localizationAngleVariations.push_back(stats.data().at(Statistics::kLoopOdom_correction_angle())); localizationAngleVariations.push_back(stats.data().at(Statistics::kLoopOdom_correction_angle()));
} }
if(exportPoses && !info.odomPose.isNull()) if(exportPoses)
{ {
if(!odomTrajectoryPoses.empty()) if(!info.odomPose.isNull())
{ {
int previousId = odomTrajectoryPoses.rbegin()->first; if(!odomTrajectoryPoses.empty())
odomTrajectoryLinks.insert(std::make_pair(previousId, Link(previousId, refId, Link::kNeighbor, odomTrajectoryPoses.rbegin()->second.inverse()*info.odomPose, info.odomCovariance))); {
int previousId = odomTrajectoryPoses.rbegin()->first;
odomTrajectoryLinks.insert(std::make_pair(previousId, Link(previousId, refId, Link::kNeighbor, odomTrajectoryPoses.rbegin()->second.inverse()*info.odomPose, info.odomCovariance)));
}
odomTrajectoryPoses.insert(std::make_pair(refId, info.odomPose));
localizationPoses.insert(std::make_pair(refId, stats.mapCorrection()*info.odomPose));
}
else
{
localizationPoses.insert(std::make_pair(refId, rtabmap.getLastLocalizationPose()));
} }
odomTrajectoryPoses.insert(std::make_pair(refId, info.odomPose));
localizationPoses.insert(std::make_pair(refId, stats.mapCorrection()*info.odomPose));
} }
} }
@@ -1282,7 +1289,7 @@ int main(int argc, char * argv[])
!info.odomPose.isNull()) !info.odomPose.isNull())
{ {
float distance = odomPose.getDistance(info.odomPose); float distance = odomPose.getDistance(info.odomPose);
float angle = (odomPose.inverse()*info.odomPose).getAngle(); float angle = odomPose.getAngle(info.odomPose);
odomDistances.push_back(distance); odomDistances.push_back(distance);
if(distance < linearUpdate && angle <= angularUpdate) if(distance < linearUpdate && angle <= angularUpdate)
{ {
@@ -232,10 +232,10 @@ class UThreadC<void>
typedef THREAD_HANDLE Handle; typedef THREAD_HANDLE Handle;
typedef void ( *Handler)(); typedef void ( *Handler)();
virtual ~UThreadC<void>() {} virtual ~UThreadC() {}
protected: protected:
UThreadC<void>() {} UThreadC() {}
virtual void ThreadMain() = 0; virtual void ThreadMain() = 0;