00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef UTIL3D_H_
00029 #define UTIL3D_H_
00030
00031 #include "rtabmap/core/RtabmapExp.h"
00032 #include <opencv2/core/core.hpp>
00033 #include <opencv2/calib3d/calib3d.hpp>
00034 #include <opencv2/features2d/features2d.hpp>
00035 #include <list>
00036 #include <string>
00037 #include <set>
00038
00039 #include <rtabmap/core/Link.h>
00040 #include <rtabmap/utilite/UThread.h>
00041 #include <pcl/common/eigen.h>
00042 #include <pcl/point_types.h>
00043 #include <pcl/point_cloud.h>
00044 #include <pcl/PolygonMesh.h>
00045 #include <pcl/pcl_base.h>
00046
00047 namespace rtabmap
00048 {
00049
00050 namespace util3d
00051 {
00052
00053 cv::Mat RTABMAP_EXP rgbFromCloud(const pcl::PointCloud<pcl::PointXYZRGBA> & cloud, bool bgrOrder = true);
00054 cv::Mat RTABMAP_EXP depthFromCloud(
00055 const pcl::PointCloud<pcl::PointXYZRGBA> & cloud,
00056 float & fx,
00057 float & fy,
00058 bool depth16U = true);
00059 void RTABMAP_EXP rgbdFromCloud(
00060 const pcl::PointCloud<pcl::PointXYZRGBA> & cloud,
00061 cv::Mat & rgb,
00062 cv::Mat & depth,
00063 float & fx,
00064 float & fy,
00065 bool bgrOrder = true,
00066 bool depth16U = true);
00067
00068 cv::Mat RTABMAP_EXP cvtDepthFromFloat(const cv::Mat & depth32F);
00069 cv::Mat RTABMAP_EXP cvtDepthToFloat(const cv::Mat & depth16U);
00070
00071 pcl::PointCloud<pcl::PointXYZ>::Ptr RTABMAP_EXP generateKeypoints3DDepth(
00072 const std::vector<cv::KeyPoint> & keypoints,
00073 const cv::Mat & depth,
00074 float fx,
00075 float fy,
00076 float cx,
00077 float cy,
00078 const Transform & transform);
00079
00080 pcl::PointCloud<pcl::PointXYZ>::Ptr RTABMAP_EXP generateKeypoints3DDisparity(
00081 const std::vector<cv::KeyPoint> & keypoints,
00082 const cv::Mat & disparity,
00083 float fx,
00084 float baseline,
00085 float cx,
00086 float cy,
00087 const Transform & transform);
00088
00089 pcl::PointCloud<pcl::PointXYZ>::Ptr RTABMAP_EXP generateKeypoints3DStereo(
00090 const std::vector<cv::KeyPoint> & keypoints,
00091 const cv::Mat & leftImage,
00092 const cv::Mat & rightImage,
00093 float fx,
00094 float baseline,
00095 float cx,
00096 float cy,
00097 const Transform & transform = Transform::getIdentity(),
00098 int flowWinSize = 9,
00099 int flowMaxLevel = 4,
00100 int flowIterations = 20,
00101 double flowEps = 0.02);
00102
00103 std::multimap<int, pcl::PointXYZ> RTABMAP_EXP generateWords3DMono(
00104 const std::multimap<int, cv::KeyPoint> & kpts,
00105 const std::multimap<int, cv::KeyPoint> & previousKpts,
00106 float fx,
00107 float fy,
00108 float cx,
00109 float cy,
00110 const Transform & localTransform,
00111 Transform & cameraTransform,
00112 int pnpIterations = 100,
00113 float pnpReprojError = 8.0f,
00114 int pnpFlags = cv::ITERATIVE,
00115 float ransacParam1 = 3.0f,
00116 float ransacParam2 = 0.99f,
00117 const std::multimap<int, pcl::PointXYZ> & refGuess3D = std::multimap<int, pcl::PointXYZ>(),
00118 double * variance = 0);
00119
00120 std::multimap<int, cv::KeyPoint> RTABMAP_EXP aggregate(
00121 const std::list<int> & wordIds,
00122 const std::vector<cv::KeyPoint> & keypoints);
00123
00124 float RTABMAP_EXP getDepth(
00125 const cv::Mat & depthImage,
00126 float x, float y,
00127 bool smoothing,
00128 float maxZError = 0.02f);
00129
00130 pcl::PointXYZ RTABMAP_EXP projectDepthTo3D(
00131 const cv::Mat & depthImage,
00132 float x, float y,
00133 float cx, float cy,
00134 float fx, float fy,
00135 bool smoothing,
00136 float maxZError = 0.02f);
00137
00138 pcl::PointCloud<pcl::PointXYZ>::Ptr RTABMAP_EXP cloudFromDepth(
00139 const cv::Mat & imageDepth,
00140 float cx, float cy,
00141 float fx, float fy,
00142 int decimation = 1);
00143
00144 pcl::PointCloud<pcl::PointXYZRGB>::Ptr RTABMAP_EXP cloudFromDepthRGB(
00145 const cv::Mat & imageRgb,
00146 const cv::Mat & imageDepth,
00147 float cx, float cy,
00148 float fx, float fy,
00149 int decimation = 1);
00150
00151 pcl::PointCloud<pcl::PointXYZ>::Ptr RTABMAP_EXP cloudFromDisparity(
00152 const cv::Mat & imageDisparity,
00153 float cx, float cy,
00154 float fx, float baseline,
00155 int decimation = 1);
00156
00157 pcl::PointCloud<pcl::PointXYZRGB>::Ptr RTABMAP_EXP cloudFromDisparityRGB(
00158 const cv::Mat & imageRgb,
00159 const cv::Mat & imageDisparity,
00160 float cx, float cy,
00161 float fx, float baseline,
00162 int decimation = 1);
00163
00164 pcl::PointCloud<pcl::PointXYZRGB>::Ptr RTABMAP_EXP cloudFromStereoImages(
00165 const cv::Mat & imageLeft,
00166 const cv::Mat & imageRight,
00167 float cx, float cy,
00168 float fx, float baseline,
00169 int decimation = 1);
00170
00171 cv::Mat RTABMAP_EXP disparityFromStereoImages(
00172 const cv::Mat & leftImage,
00173 const cv::Mat & rightImage);
00174
00175 cv::Mat RTABMAP_EXP disparityFromStereoImages(
00176 const cv::Mat & leftImage,
00177 const cv::Mat & rightImage,
00178 const std::vector<cv::Point2f> & leftCorners,
00179 int flowWinSize = 9,
00180 int flowMaxLevel = 4,
00181 int flowIterations = 20,
00182 double flowEps = 0.02,
00183 float maxCorrespondencesSlope = 0.1f);
00184
00185 cv::Mat RTABMAP_EXP depthFromStereoImages(
00186 const cv::Mat & leftImage,
00187 const cv::Mat & rightImage,
00188 const std::vector<cv::Point2f> & leftCorners,
00189 float fx,
00190 float baseline,
00191 int flowWinSize = 9,
00192 int flowMaxLevel = 4,
00193 int flowIterations = 20,
00194 double flowEps = 0.02);
00195
00196 cv::Mat RTABMAP_EXP disparityFromStereoCorrespondences(
00197 const cv::Mat & leftImage,
00198 const std::vector<cv::Point2f> & leftCorners,
00199 const std::vector<cv::Point2f> & rightCorners,
00200 const std::vector<unsigned char> & mask,
00201 float maxSlope = 0.1f);
00202
00203 cv::Mat RTABMAP_EXP depthFromStereoCorrespondences(
00204 const cv::Mat & leftImage,
00205 const std::vector<cv::Point2f> & leftCorners,
00206 const std::vector<cv::Point2f> & rightCorners,
00207 const std::vector<unsigned char> & mask,
00208 float fx, float baseline);
00209
00210 pcl::PointXYZ RTABMAP_EXP projectDisparityTo3D(
00211 const cv::Point2f & pt,
00212 float disparity,
00213 float cx, float cy, float fx, float baseline);
00214
00215 pcl::PointXYZ RTABMAP_EXP projectDisparityTo3D(
00216 const cv::Point2f & pt,
00217 const cv::Mat & disparity,
00218 float cx, float cy, float fx, float baseline);
00219
00220 cv::Mat RTABMAP_EXP depthFromDisparity(const cv::Mat & disparity,
00221 float fx, float baseline,
00222 int type = CV_32FC1);
00223
00224 cv::Mat RTABMAP_EXP registerDepth(
00225 const cv::Mat & depth,
00226 const cv::Mat & depthK,
00227 const cv::Mat & colorK,
00228 const rtabmap::Transform & transform);
00229
00230 void RTABMAP_EXP fillRegisteredDepthHoles(cv::Mat & depth, bool vertical, bool horizontal, bool fillDoubleHoles = false);
00231
00232 cv::Mat RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZ> & cloud);
00233 pcl::PointCloud<pcl::PointXYZ>::Ptr RTABMAP_EXP laserScanToPointCloud(const cv::Mat & laserScan);
00234
00235
00236 void RTABMAP_EXP extractXYZCorrespondences(const std::multimap<int, pcl::PointXYZ> & words1,
00237 const std::multimap<int, pcl::PointXYZ> & words2,
00238 pcl::PointCloud<pcl::PointXYZ> & cloud1,
00239 pcl::PointCloud<pcl::PointXYZ> & cloud2);
00240
00241 void RTABMAP_EXP extractXYZCorrespondencesRANSAC(const std::multimap<int, pcl::PointXYZ> & words1,
00242 const std::multimap<int, pcl::PointXYZ> & words2,
00243 pcl::PointCloud<pcl::PointXYZ> & cloud1,
00244 pcl::PointCloud<pcl::PointXYZ> & cloud2);
00245
00246 void RTABMAP_EXP extractXYZCorrespondences(const std::list<std::pair<cv::Point2f, cv::Point2f> > & correspondences,
00247 const cv::Mat & depthImage1,
00248 const cv::Mat & depthImage2,
00249 float cx, float cy,
00250 float fx, float fy,
00251 float maxDepth,
00252 pcl::PointCloud<pcl::PointXYZ> & cloud1,
00253 pcl::PointCloud<pcl::PointXYZ> & cloud2);
00254
00255 void RTABMAP_EXP extractXYZCorrespondences(const std::list<std::pair<cv::Point2f, cv::Point2f> > & correspondences,
00256 const pcl::PointCloud<pcl::PointXYZ> & cloud1,
00257 const pcl::PointCloud<pcl::PointXYZ> & cloud2,
00258 pcl::PointCloud<pcl::PointXYZ> & inliers1,
00259 pcl::PointCloud<pcl::PointXYZ> & inliers2,
00260 char depthAxis);
00261 void RTABMAP_EXP extractXYZCorrespondences(const std::list<std::pair<cv::Point2f, cv::Point2f> > & correspondences,
00262 const pcl::PointCloud<pcl::PointXYZRGB> & cloud1,
00263 const pcl::PointCloud<pcl::PointXYZRGB> & cloud2,
00264 pcl::PointCloud<pcl::PointXYZ> & inliers1,
00265 pcl::PointCloud<pcl::PointXYZ> & inliers2,
00266 char depthAxis);
00267
00268 int RTABMAP_EXP countUniquePairs(const std::multimap<int, pcl::PointXYZ> & wordsA,
00269 const std::multimap<int, pcl::PointXYZ> & wordsB);
00270
00271 void RTABMAP_EXP filterMaxDepth(pcl::PointCloud<pcl::PointXYZ> & inliers1,
00272 pcl::PointCloud<pcl::PointXYZ> & inliers2,
00273 float maxDepth,
00274 char depthAxis,
00275 bool removeDuplicates);
00276
00277 Transform RTABMAP_EXP transformFromXYZCorrespondences(
00278 const pcl::PointCloud<pcl::PointXYZ>::ConstPtr & cloud1,
00279 const pcl::PointCloud<pcl::PointXYZ>::ConstPtr & cloud2,
00280 double inlierThreshold = 0.02,
00281 int iterations = 100,
00282 bool refineModel = false,
00283 double refineModelSigma = 3.0,
00284 int refineModelIterations = 10,
00285 std::vector<int> * inliers = 0,
00286 double * variance = 0);
00287
00288 Transform RTABMAP_EXP icp(
00289 const pcl::PointCloud<pcl::PointXYZ>::ConstPtr & cloud_source,
00290 const pcl::PointCloud<pcl::PointXYZ>::ConstPtr & cloud_target,
00291 double maxCorrespondenceDistance,
00292 int maximumIterations,
00293 bool * hasConverged = 0,
00294 double * variance = 0,
00295 int * correspondences = 0);
00296
00297 Transform RTABMAP_EXP icpPointToPlane(
00298 const pcl::PointCloud<pcl::PointNormal>::ConstPtr & cloud_source,
00299 const pcl::PointCloud<pcl::PointNormal>::ConstPtr & cloud_target,
00300 double maxCorrespondenceDistance,
00301 int maximumIterations,
00302 bool * hasConverged = 0,
00303 double * variance = 0,
00304 int * correspondences = 0);
00305
00306 Transform RTABMAP_EXP icp2D(
00307 const pcl::PointCloud<pcl::PointXYZ>::ConstPtr & cloud_source,
00308 const pcl::PointCloud<pcl::PointXYZ>::ConstPtr & cloud_target,
00309 double maxCorrespondenceDistance,
00310 int maximumIterations,
00311 bool * hasConverged = 0,
00312 double * variance = 0,
00313 int * correspondences = 0);
00314
00315 pcl::PointCloud<pcl::PointNormal>::Ptr RTABMAP_EXP computeNormals(
00316 const pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud,
00317 int normalKSearch = 20);
00318
00319 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr RTABMAP_EXP computeNormals(
00320 const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
00321 int normalKSearch = 20);
00322
00323 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr RTABMAP_EXP computeNormalsSmoothed(
00324 const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
00325 float smoothingSearchRadius = 0.025,
00326 bool smoothingPolynomialFit = true);
00327
00328 int RTABMAP_EXP getCorrespondencesCount(const pcl::PointCloud<pcl::PointXYZ>::ConstPtr & cloud_source,
00329 const pcl::PointCloud<pcl::PointXYZ>::ConstPtr & cloud_target,
00330 float maxDistance);
00331
00332 void RTABMAP_EXP findCorrespondences(
00333 const std::multimap<int, cv::KeyPoint> & wordsA,
00334 const std::multimap<int, cv::KeyPoint> & wordsB,
00335 std::list<std::pair<cv::Point2f, cv::Point2f> > & pairs);
00336
00337 void RTABMAP_EXP findCorrespondences(
00338 const std::multimap<int, pcl::PointXYZ> & words1,
00339 const std::multimap<int, pcl::PointXYZ> & words2,
00340 pcl::PointCloud<pcl::PointXYZ> & inliers1,
00341 pcl::PointCloud<pcl::PointXYZ> & inliers2,
00342 float maxDepth,
00343 std::set<int> * uniqueCorrespondences = 0);
00344
00345 pcl::PointCloud<pcl::PointXYZ>::Ptr RTABMAP_EXP cvMat2Cloud(
00346 const cv::Mat & matrix,
00347 const Transform & tranform = Transform::getIdentity());
00348
00349 pcl::PointCloud<pcl::PointXYZ>::Ptr RTABMAP_EXP getICPReadyCloud(
00350 const cv::Mat & depth,
00351 float fx,
00352 float fy,
00353 float cx,
00354 float cy,
00355 int decimation,
00356 double maxDepth,
00357 float voxel,
00358 int samples,
00359 const Transform & transform = Transform::getIdentity());
00360
00361 pcl::PointCloud<pcl::PointXYZ>::Ptr RTABMAP_EXP concatenateClouds(const std::list<pcl::PointCloud<pcl::PointXYZ>::Ptr> & clouds);
00362 pcl::PointCloud<pcl::PointXYZRGB>::Ptr RTABMAP_EXP concatenateClouds(const std::list<pcl::PointCloud<pcl::PointXYZRGB>::Ptr> & clouds);
00363 pcl::PointCloud<pcl::PointXYZ>::Ptr RTABMAP_EXP get3DFASTKpts(
00364 const cv::Mat & image,
00365 const cv::Mat & imageDepth,
00366 float constant,
00367 int fastThreshold=50,
00368 bool fastNonmaxSuppression=true,
00369 float maxDepth = 5.0f);
00370
00371 pcl::PolygonMesh::Ptr RTABMAP_EXP createMesh(
00372 const pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr & cloudWithNormals,
00373 float gp3SearchRadius = 0.025,
00374 float gp3Mu = 2.5,
00375 int gp3MaximumNearestNeighbors = 100,
00376 float gp3MaximumSurfaceAngle = M_PI/4,
00377 float gp3MinimumAngle = M_PI/18,
00378 float gp3MaximumAngle = 2*M_PI/3,
00379 bool gp3NormalConsistency = false);
00380
00381 void RTABMAP_EXP occupancy2DFromLaserScan(
00382 const cv::Mat & scan,
00383 cv::Mat & ground,
00384 cv::Mat & obstacles,
00385 float cellSize);
00386
00387 cv::Mat RTABMAP_EXP create2DMapFromOccupancyLocalMaps(
00388 const std::map<int, Transform> & poses,
00389 const std::map<int, std::pair<cv::Mat, cv::Mat> > & occupancy,
00390 float cellSize,
00391 float & xMin,
00392 float & yMin,
00393 float minMapSize = 0.0f,
00394 bool erode = false);
00395
00396 cv::Mat RTABMAP_EXP create2DMap(const std::map<int, Transform> & poses,
00397 const std::map<int, pcl::PointCloud<pcl::PointXYZ>::Ptr > & scans,
00398 float cellSize,
00399 bool unknownSpaceFilled,
00400 float & xMin,
00401 float & yMin,
00402 float minMapSize = 0.0f);
00403
00404 void RTABMAP_EXP rayTrace(const cv::Point2i & start,
00405 const cv::Point2i & end,
00406 cv::Mat & grid,
00407 bool stopOnObstacle);
00408
00409 cv::Mat RTABMAP_EXP convertMap2Image8U(const cv::Mat & map8S);
00410
00420 pcl::IndicesPtr RTABMAP_EXP concatenate(
00421 const std::vector<pcl::IndicesPtr> & indices);
00422
00433 pcl::IndicesPtr RTABMAP_EXP concatenate(
00434 const pcl::IndicesPtr & indicesA,
00435 const pcl::IndicesPtr & indicesB);
00436
00437 cv::Mat RTABMAP_EXP decimate(const cv::Mat & image, int d);
00438
00439 void RTABMAP_EXP savePCDWords(
00440 const std::string & fileName,
00441 const std::multimap<int, pcl::PointXYZ> & words,
00442 const Transform & transform = Transform::getIdentity());
00443
00445
00447
00448 template<typename PointT>
00449 typename pcl::PointCloud<PointT>::Ptr voxelize(
00450 const typename pcl::PointCloud<PointT>::Ptr & cloud,
00451 float voxelSize);
00452
00453 template<typename PointT>
00454 typename pcl::PointCloud<PointT>::Ptr sampling(
00455 const typename pcl::PointCloud<PointT>::Ptr & cloud,
00456 int samples);
00457
00458 template<typename PointT>
00459 typename pcl::PointCloud<PointT>::Ptr passThrough(
00460 const typename pcl::PointCloud<PointT>::Ptr & cloud,
00461 const std::string & axis,
00462 float min,
00463 float max);
00464
00465 template<typename PointT>
00466 typename pcl::PointCloud<PointT>::Ptr removeNaNFromPointCloud(
00467 const typename pcl::PointCloud<PointT>::Ptr & cloud);
00468
00469 template<typename PointT>
00470 typename pcl::PointCloud<PointT>::Ptr removeNaNNormalsFromPointCloud(
00471 const typename pcl::PointCloud<PointT>::Ptr & cloud);
00472
00473 template<typename PointT>
00474 typename pcl::PointCloud<PointT>::Ptr transformPointCloud(
00475 const typename pcl::PointCloud<PointT>::Ptr & cloud,
00476 const Transform & transform);
00477
00478 template<typename PointT>
00479 PointT transformPoint(
00480 const PointT & pt,
00481 const Transform & transform);
00482
00483 template<typename PointT>
00484 void segmentObstaclesFromGround(
00485 const typename pcl::PointCloud<PointT>::Ptr & cloud,
00486 pcl::IndicesPtr & ground,
00487 pcl::IndicesPtr & obstacles,
00488 float normalRadiusSearch,
00489 float groundNormalAngle,
00490 int minClusterSize,
00491 bool segmentFlatObstacles = false);
00492
00493 template<typename PointT>
00494 void projectCloudOnXYPlane(
00495 typename pcl::PointCloud<PointT>::Ptr & cloud);
00496
00500 template<typename PointT>
00501 pcl::IndicesPtr radiusFiltering(
00502 const typename pcl::PointCloud<PointT>::Ptr & cloud,
00503 float radiusSearch,
00504 int minNeighborsInRadius);
00505
00517 template<typename PointT>
00518 pcl::IndicesPtr radiusFiltering(
00519 const typename pcl::PointCloud<PointT>::Ptr & cloud,
00520 const pcl::IndicesPtr & indices,
00521 float radiusSearch,
00522 int minNeighborsInRadius);
00523
00527 template<typename PointT>
00528 pcl::IndicesPtr normalFiltering(
00529 const typename pcl::PointCloud<PointT>::Ptr & cloud,
00530 float angleMax,
00531 const Eigen::Vector4f & normal,
00532 float radiusSearch,
00533 const Eigen::Vector4f & viewpoint);
00534
00551 template<typename PointT>
00552 pcl::IndicesPtr normalFiltering(
00553 const typename pcl::PointCloud<PointT>::Ptr & cloud,
00554 const pcl::IndicesPtr & indices,
00555 float angleMax,
00556 const Eigen::Vector4f & normal,
00557 float radiusSearch,
00558 const Eigen::Vector4f & viewpoint);
00559
00563 template<typename PointT>
00564 std::vector<pcl::IndicesPtr> extractClusters(
00565 const typename pcl::PointCloud<PointT>::Ptr & cloud,
00566 float clusterTolerance,
00567 int minClusterSize,
00568 int maxClusterSize = std::numeric_limits<int>::max(),
00569 int * biggestClusterIndex = 0);
00570
00583 template<typename PointT>
00584 std::vector<pcl::IndicesPtr> extractClusters(
00585 const typename pcl::PointCloud<PointT>::Ptr & cloud,
00586 const pcl::IndicesPtr & indices,
00587 float clusterTolerance,
00588 int minClusterSize,
00589 int maxClusterSize = std::numeric_limits<int>::max(),
00590 int * biggestClusterIndex = 0);
00591
00592 template<typename PointT>
00593 pcl::IndicesPtr extractNegativeIndices(
00594 const typename pcl::PointCloud<PointT>::Ptr & cloud,
00595 const pcl::IndicesPtr & indices);
00596
00597 template<typename PointT>
00598 void occupancy2DFromCloud3D(
00599 const typename pcl::PointCloud<PointT>::Ptr & cloud,
00600 cv::Mat & ground,
00601 cv::Mat & obstacles,
00602 float cellSize = 0.05f,
00603 float groundNormalAngle = M_PI_4,
00604 int minClusterSize = 20);
00605
00606 }
00607 }
00608
00609 #include "rtabmap/core/impl/util3d.hpp"
00610
00611 #endif