Increased database version to 0.10.7: added scan_max_range column. Create2DMap: updated unknown cells filling depending on max laser scan range. Added util3d::frustumFiltering() to filter points in a specified frustum.

This commit is contained in:
matlabbe
2015-09-17 22:55:45 -04:00
parent 007c192b6a
commit 55834644cf
14 changed files with 181 additions and 21 deletions

View File

@@ -20,7 +20,7 @@ SET(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake_modules")
####################### #######################
SET(RTABMAP_MAJOR_VERSION 0) SET(RTABMAP_MAJOR_VERSION 0)
SET(RTABMAP_MINOR_VERSION 10) SET(RTABMAP_MINOR_VERSION 10)
SET(RTABMAP_PATCH_VERSION 6) SET(RTABMAP_PATCH_VERSION 7)
SET(RTABMAP_VERSION SET(RTABMAP_VERSION
${RTABMAP_MAJOR_VERSION}.${RTABMAP_MINOR_VERSION}.${RTABMAP_PATCH_VERSION}) ${RTABMAP_MAJOR_VERSION}.${RTABMAP_MINOR_VERSION}.${RTABMAP_PATCH_VERSION})

View File

@@ -96,6 +96,7 @@ public:
void setLocalTransform(const Transform & transform) {localTransform_ = transform;} void setLocalTransform(const Transform & transform) {localTransform_ = transform;}
const Transform & localTransform() const {return localTransform_;} const Transform & localTransform() const {return localTransform_;}
void setImageSize(const cv::Size & size) {imageSize_ = size;}
const cv::Size & imageSize() const {return imageSize_;} const cv::Size & imageSize() const {return imageSize_;}
int imageWidth() const {return imageSize_.width;} int imageWidth() const {return imageSize_.width;}
int imageHeight() const {return imageSize_.height;} int imageHeight() const {return imageSize_.height;}
@@ -105,6 +106,9 @@ public:
void scale(double scale); void scale(double scale);
double horizontalFOV() const; // in degrees
double verticalFOV() const; // in degrees
// For depth images, your should use cv::INTER_NEAREST // For depth images, your should use cv::INTER_NEAREST
cv::Mat rectifyImage(const cv::Mat & raw, int interpolation = cv::INTER_LINEAR) const; cv::Mat rectifyImage(const cv::Mat & raw, int interpolation = cv::INTER_LINEAR) const;
cv::Mat rectifyDepth(const cv::Mat & raw) const; cv::Mat rectifyDepth(const cv::Mat & raw) const;

View File

@@ -75,6 +75,7 @@ public:
SensorData( SensorData(
const cv::Mat & laserScan, const cv::Mat & laserScan,
int laserScanMaxPts, int laserScanMaxPts,
float laserScanMaxRange,
const cv::Mat & rgb, const cv::Mat & rgb,
const cv::Mat & depth, const cv::Mat & depth,
const CameraModel & cameraModel, const CameraModel & cameraModel,
@@ -95,6 +96,7 @@ public:
SensorData( SensorData(
const cv::Mat & laserScan, const cv::Mat & laserScan,
int laserScanMaxPts, int laserScanMaxPts,
float laserScanMaxRange,
const cv::Mat & rgb, const cv::Mat & rgb,
const cv::Mat & depth, const cv::Mat & depth,
const std::vector<CameraModel> & cameraModels, const std::vector<CameraModel> & cameraModels,
@@ -115,6 +117,7 @@ public:
SensorData( SensorData(
const cv::Mat & laserScan, const cv::Mat & laserScan,
int laserScanMaxPts, int laserScanMaxPts,
float laserScanMaxRange,
const cv::Mat & left, const cv::Mat & left,
const cv::Mat & right, const cv::Mat & right,
const StereoCameraModel & cameraModel, const StereoCameraModel & cameraModel,
@@ -147,6 +150,7 @@ public:
double stamp() const {return _stamp;} double stamp() const {return _stamp;}
void setStamp(double stamp) {_stamp = stamp;} void setStamp(double stamp) {_stamp = stamp;}
int laserScanMaxPts() const {return _laserScanMaxPts;} int laserScanMaxPts() const {return _laserScanMaxPts;}
float laserScanMaxRange() const {return _laserScanMaxRange;}
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;}
@@ -157,7 +161,7 @@ public:
const cv::Mat & laserScanRaw() const {return _laserScanRaw;} const cv::Mat & laserScanRaw() const {return _laserScanRaw;}
void setImageRaw(const cv::Mat & imageRaw) {_imageRaw = imageRaw;} void setImageRaw(const cv::Mat & imageRaw) {_imageRaw = imageRaw;}
void setDepthOrRightRaw(const cv::Mat & depthOrImageRaw) {_depthOrRightRaw =depthOrImageRaw;} void setDepthOrRightRaw(const cv::Mat & depthOrImageRaw) {_depthOrRightRaw =depthOrImageRaw;}
void setLaserScanRaw(const cv::Mat & laserScanRaw, int laserScanMaxPts) {_laserScanRaw =laserScanRaw;_laserScanMaxPts = laserScanMaxPts;} void setLaserScanRaw(const cv::Mat & laserScanRaw, int maxPts, float maxRange) {_laserScanRaw =laserScanRaw;_laserScanMaxPts = maxPts;_laserScanMaxRange=maxRange;}
void setCameraModel(const CameraModel & model) {_cameraModels.clear(); _cameraModels.push_back(model);} void setCameraModel(const CameraModel & model) {_cameraModels.clear(); _cameraModels.push_back(model);}
void setCameraModels(const std::vector<CameraModel> & models) {_cameraModels = models;} void setCameraModels(const std::vector<CameraModel> & models) {_cameraModels = models;}
void setStereoCameraModel(const StereoCameraModel & stereoCameraModel) {_stereoCameraModel = stereoCameraModel;} void setStereoCameraModel(const StereoCameraModel & stereoCameraModel) {_stereoCameraModel = stereoCameraModel;}
@@ -190,6 +194,7 @@ private:
int _id; int _id;
double _stamp; double _stamp;
int _laserScanMaxPts; int _laserScanMaxPts;
float _laserScanMaxRange;
cv::Mat _imageCompressed; // compressed image cv::Mat _imageCompressed; // compressed image
cv::Mat _depthOrRightCompressed; // compressed image cv::Mat _depthOrRightCompressed; // compressed image

View File

@@ -29,6 +29,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define UTIL3D_FILTERING_H_ #define UTIL3D_FILTERING_H_
#include <rtabmap/core/RtabmapExp.h> #include <rtabmap/core/RtabmapExp.h>
#include <rtabmap/core/Transform.h>
#include <pcl/point_cloud.h> #include <pcl/point_cloud.h>
#include <pcl/point_types.h> #include <pcl/point_types.h>
@@ -63,12 +64,31 @@ pcl::PointCloud<pcl::PointXYZ>::Ptr RTABMAP_EXP passThrough(
const pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud, const pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud,
const std::string & axis, const std::string & axis,
float min, float min,
float max); float max,
bool negative = false);
pcl::PointCloud<pcl::PointXYZRGB>::Ptr RTABMAP_EXP passThrough( pcl::PointCloud<pcl::PointXYZRGB>::Ptr RTABMAP_EXP passThrough(
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud, const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
const std::string & axis, const std::string & axis,
float min, float min,
float max); float max,
bool negative = false);
pcl::PointCloud<pcl::PointXYZ>::Ptr RTABMAP_EXP frustumFiltering(
const pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud,
const Transform & cameraPose,
float horizontalFOV, // in degrees, xfov = atan((image_width/2)/fx)*2
float verticalFOV, // in degrees, yfov = atan((image_height/2)/fy)*2
float nearClipPlaneDistance,
float farClipPlaneDistance,
bool negative = false);
pcl::PointCloud<pcl::PointXYZRGB>::Ptr RTABMAP_EXP frustumFiltering(
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
const Transform & cameraPose,
float horizontalFOV, // in degrees, xfov = atan((image_width/2)/fx)*2
float verticalFOV, // in degrees, yfov = atan((image_height/2)/fy)*2
float nearClipPlaneDistance,
float farClipPlaneDistance,
bool negative = false);
pcl::PointCloud<pcl::PointXYZ>::Ptr RTABMAP_EXP removeNaNFromPointCloud( pcl::PointCloud<pcl::PointXYZ>::Ptr RTABMAP_EXP removeNaNFromPointCloud(

View File

@@ -48,7 +48,8 @@ void RTABMAP_EXP occupancy2DFromLaserScan(
cv::Mat & ground, cv::Mat & ground,
cv::Mat & obstacles, cv::Mat & obstacles,
float cellSize, float cellSize,
bool unknownSpaceFilled = false); bool unknownSpaceFilled = false,
float scanMaxRange = 0.0f); // would be set if unknownSpaceFilled=true
cv::Mat RTABMAP_EXP create2DMapFromOccupancyLocalMaps( cv::Mat RTABMAP_EXP create2DMapFromOccupancyLocalMaps(
const std::map<int, Transform> & poses, const std::map<int, Transform> & poses,
@@ -65,7 +66,8 @@ cv::Mat RTABMAP_EXP create2DMap(const std::map<int, Transform> & poses,
bool unknownSpaceFilled, bool unknownSpaceFilled,
float & xMin, float & xMin,
float & yMin, float & yMin,
float minMapSize = 0.0f); float minMapSize = 0.0f,
float scanMaxRange = 0.0f); // would be set if unknownSpaceFilled=true
void RTABMAP_EXP rayTrace(const cv::Point2i & start, void RTABMAP_EXP rayTrace(const cv::Point2i & start,
const cv::Point2i & end, const cv::Point2i & end,

View File

@@ -277,6 +277,24 @@ void CameraModel::scale(double scale)
P_.at<double>(1,2) *= scale; P_.at<double>(1,2) *= scale;
} }
double CameraModel::horizontalFOV() const
{
if(imageWidth() > 0 && fx() > 0.0)
{
return atan((double(imageWidth())/2.0)/fx())*2.0*180.0/CV_PI;
}
return 0.0;
}
double CameraModel::verticalFOV() const
{
if(imageHeight() > 0 && fy() > 0.0)
{
return atan((double(imageHeight())/2.0)/fy())*2.0*180.0/CV_PI;
}
return 0.0;
}
cv::Mat CameraModel::rectifyImage(const cv::Mat & raw, int interpolation) const cv::Mat CameraModel::rectifyImage(const cv::Mat & raw, int interpolation) const
{ {
if(!mapX_.empty() && !mapY_.empty()) if(!mapX_.empty() && !mapY_.empty())

View File

@@ -457,7 +457,14 @@ void DBDriverSqlite3::loadNodeDataQuery(std::list<Signature *> & signatures) con
sqlite3_stmt * ppStmt = 0; sqlite3_stmt * ppStmt = 0;
std::stringstream query; std::stringstream query;
if(uStrNumCmp(_version, "0.10.1") >= 0) if(uStrNumCmp(_version, "0.10.7") >= 0)
{
query << "SELECT image, depth, calibration, scan_max_pts, scan_max_range, scan, user_data "
<< "FROM Data "
<< "WHERE id = ?"
<<";";
}
else if(uStrNumCmp(_version, "0.10.1") >= 0)
{ {
query << "SELECT image, depth, calibration, scan_max_pts, scan, user_data " query << "SELECT image, depth, calibration, scan_max_pts, scan, user_data "
<< "FROM Data " << "FROM Data "
@@ -653,6 +660,12 @@ void DBDriverSqlite3::loadNodeDataQuery(std::list<Signature *> & signatures) con
laserScanMaxPts = sqlite3_column_int(ppStmt, index++); laserScanMaxPts = sqlite3_column_int(ppStmt, index++);
} }
float laserScanMaxRange = 0.0f;
if(uStrNumCmp(_version, "0.10.7") >= 0)
{
laserScanMaxRange = sqlite3_column_int(ppStmt, index++);
}
data = sqlite3_column_blob(ppStmt, index); data = sqlite3_column_blob(ppStmt, index);
dataSize = sqlite3_column_bytes(ppStmt, index++); dataSize = sqlite3_column_bytes(ppStmt, index++);
//Create the laserScan //Create the laserScan
@@ -685,6 +698,7 @@ void DBDriverSqlite3::loadNodeDataQuery(std::list<Signature *> & signatures) con
(*iter)->sensorData() = SensorData( (*iter)->sensorData() = SensorData(
scanCompressed, scanCompressed,
laserScanMaxPts, laserScanMaxPts,
laserScanMaxRange,
imageCompressed, imageCompressed,
depthOrRightCompressed, depthOrRightCompressed,
models, models,
@@ -697,6 +711,7 @@ void DBDriverSqlite3::loadNodeDataQuery(std::list<Signature *> & signatures) con
(*iter)->sensorData() = SensorData( (*iter)->sensorData() = SensorData(
scanCompressed, scanCompressed,
laserScanMaxPts, laserScanMaxPts,
laserScanMaxRange,
imageCompressed, imageCompressed,
depthOrRightCompressed, depthOrRightCompressed,
stereoModel, stereoModel,
@@ -2360,7 +2375,11 @@ void DBDriverSqlite3::stepDepth(sqlite3_stmt * ppStmt, const SensorData & sensor
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.10.1") >= 0) if(uStrNumCmp(_version, "0.10.7") >= 0)
{
return "INSERT INTO Data(id, image, depth, calibration, scan_max_pts, scan_max_range, scan, user_data) VALUES(?,?,?,?,?,?,?,?);";
}
else if(uStrNumCmp(_version, "0.10.1") >= 0)
{ {
return "INSERT INTO Data(id, image, depth, calibration, scan_max_pts, scan, user_data) VALUES(?,?,?,?,?,?,?);"; return "INSERT INTO Data(id, image, depth, calibration, scan_max_pts, scan, user_data) VALUES(?,?,?,?,?,?,?);";
} }
@@ -2455,6 +2474,13 @@ void DBDriverSqlite3::stepSensorData(sqlite3_stmt * ppStmt,
rc = sqlite3_bind_int(ppStmt, index++, sensorData.laserScanMaxPts()); rc = sqlite3_bind_int(ppStmt, index++, sensorData.laserScanMaxPts());
UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str()); UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
// scan_max_range
if(uStrNumCmp(_version, "0.10.7") >= 0)
{
rc = sqlite3_bind_double(ppStmt, index++, sensorData.laserScanMaxRange());
UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error: %s", sqlite3_errmsg(_ppDb)).c_str());
}
// scan // scan
if(!sensorData.laserScanCompressed().empty()) if(!sensorData.laserScanCompressed().empty())
{ {

View File

@@ -4302,6 +4302,7 @@ Signature * Memory::createSignature(const SensorData & data, const Transform & p
SensorData( SensorData(
ctDepth2d.getCompressedData(), ctDepth2d.getCompressedData(),
data.laserScanMaxPts(), data.laserScanMaxPts(),
data.laserScanMaxRange(),
ctImage.getCompressedData(), ctImage.getCompressedData(),
ctDepth.getCompressedData(), ctDepth.getCompressedData(),
stereoCameraModel, stereoCameraModel,
@@ -4311,6 +4312,7 @@ Signature * Memory::createSignature(const SensorData & data, const Transform & p
SensorData( SensorData(
ctDepth2d.getCompressedData(), ctDepth2d.getCompressedData(),
data.laserScanMaxPts(), data.laserScanMaxPts(),
data.laserScanMaxRange(),
ctImage.getCompressedData(), ctImage.getCompressedData(),
ctDepth.getCompressedData(), ctDepth.getCompressedData(),
cameraModels, cameraModels,
@@ -4337,6 +4339,7 @@ Signature * Memory::createSignature(const SensorData & data, const Transform & p
SensorData( SensorData(
ctDepth2d.getCompressedData(), ctDepth2d.getCompressedData(),
data.laserScanMaxPts(), data.laserScanMaxPts(),
data.laserScanMaxRange(),
cv::Mat(), cv::Mat(),
cv::Mat(), cv::Mat(),
stereoCameraModel, stereoCameraModel,
@@ -4346,6 +4349,7 @@ Signature * Memory::createSignature(const SensorData & data, const Transform & p
SensorData( SensorData(
ctDepth2d.getCompressedData(), ctDepth2d.getCompressedData(),
data.laserScanMaxPts(), data.laserScanMaxPts(),
data.laserScanMaxRange(),
cv::Mat(), cv::Mat(),
cv::Mat(), cv::Mat(),
cameraModels, cameraModels,
@@ -4359,7 +4363,7 @@ Signature * Memory::createSignature(const SensorData & data, const Transform & p
{ {
s->sensorData().setImageRaw(image); s->sensorData().setImageRaw(image);
s->sensorData().setDepthOrRightRaw(depthOrRightImage); s->sensorData().setDepthOrRightRaw(depthOrRightImage);
s->sensorData().setLaserScanRaw(laserScan, data.laserScanMaxPts()); s->sensorData().setLaserScanRaw(laserScan, data.laserScanMaxPts(), data.laserScanMaxRange());
s->sensorData().setUserDataRaw(data.userDataRaw()); s->sensorData().setUserDataRaw(data.userDataRaw());
} }

View File

@@ -38,7 +38,8 @@ namespace rtabmap
SensorData::SensorData() : SensorData::SensorData() :
_id(0), _id(0),
_stamp(0.0), _stamp(0.0),
_laserScanMaxPts(0) _laserScanMaxPts(0),
_laserScanMaxRange(0.0f)
{ {
} }
@@ -50,7 +51,8 @@ SensorData::SensorData(
const cv::Mat & userData) : const cv::Mat & userData) :
_id(id), _id(id),
_stamp(stamp), _stamp(stamp),
_laserScanMaxPts(0) _laserScanMaxPts(0),
_laserScanMaxRange(0.0f)
{ {
if(image.rows == 1) if(image.rows == 1)
{ {
@@ -84,6 +86,7 @@ SensorData::SensorData(
_id(id), _id(id),
_stamp(stamp), _stamp(stamp),
_laserScanMaxPts(0), _laserScanMaxPts(0),
_laserScanMaxRange(0.0f),
_cameraModels(std::vector<CameraModel>(1, cameraModel)) _cameraModels(std::vector<CameraModel>(1, cameraModel))
{ {
if(image.rows == 1) if(image.rows == 1)
@@ -119,6 +122,7 @@ SensorData::SensorData(
_id(id), _id(id),
_stamp(stamp), _stamp(stamp),
_laserScanMaxPts(0), _laserScanMaxPts(0),
_laserScanMaxRange(0.0f),
_cameraModels(std::vector<CameraModel>(1, cameraModel)) _cameraModels(std::vector<CameraModel>(1, cameraModel))
{ {
if(rgb.rows == 1) if(rgb.rows == 1)
@@ -159,6 +163,7 @@ SensorData::SensorData(
SensorData::SensorData( SensorData::SensorData(
const cv::Mat & laserScan, const cv::Mat & laserScan,
int laserScanMaxPts, int laserScanMaxPts,
float laserScanMaxRange,
const cv::Mat & rgb, const cv::Mat & rgb,
const cv::Mat & depth, const cv::Mat & depth,
const CameraModel & cameraModel, const CameraModel & cameraModel,
@@ -168,6 +173,7 @@ SensorData::SensorData(
_id(id), _id(id),
_stamp(stamp), _stamp(stamp),
_laserScanMaxPts(laserScanMaxPts), _laserScanMaxPts(laserScanMaxPts),
_laserScanMaxRange(laserScanMaxRange),
_cameraModels(std::vector<CameraModel>(1, cameraModel)) _cameraModels(std::vector<CameraModel>(1, cameraModel))
{ {
if(rgb.rows == 1) if(rgb.rows == 1)
@@ -224,6 +230,7 @@ SensorData::SensorData(
_id(id), _id(id),
_stamp(stamp), _stamp(stamp),
_laserScanMaxPts(0), _laserScanMaxPts(0),
_laserScanMaxRange(0.0f),
_cameraModels(cameraModels) _cameraModels(cameraModels)
{ {
if(rgb.rows == 1) if(rgb.rows == 1)
@@ -263,6 +270,7 @@ SensorData::SensorData(
SensorData::SensorData( SensorData::SensorData(
const cv::Mat & laserScan, const cv::Mat & laserScan,
int laserScanMaxPts, int laserScanMaxPts,
float laserScanMaxRange,
const cv::Mat & rgb, const cv::Mat & rgb,
const cv::Mat & depth, const cv::Mat & depth,
const std::vector<CameraModel> & cameraModels, const std::vector<CameraModel> & cameraModels,
@@ -272,6 +280,7 @@ SensorData::SensorData(
_id(id), _id(id),
_stamp(stamp), _stamp(stamp),
_laserScanMaxPts(laserScanMaxPts), _laserScanMaxPts(laserScanMaxPts),
_laserScanMaxRange(laserScanMaxRange),
_cameraModels(cameraModels) _cameraModels(cameraModels)
{ {
if(rgb.rows == 1) if(rgb.rows == 1)
@@ -328,6 +337,7 @@ SensorData::SensorData(
_id(id), _id(id),
_stamp(stamp), _stamp(stamp),
_laserScanMaxPts(0), _laserScanMaxPts(0),
_laserScanMaxRange(0.0f),
_stereoCameraModel(cameraModel) _stereoCameraModel(cameraModel)
{ {
if(left.rows == 1) if(left.rows == 1)
@@ -367,6 +377,7 @@ SensorData::SensorData(
SensorData::SensorData( SensorData::SensorData(
const cv::Mat & laserScan, const cv::Mat & laserScan,
int laserScanMaxPts, int laserScanMaxPts,
float laserScanMaxRange,
const cv::Mat & left, const cv::Mat & left,
const cv::Mat & right, const cv::Mat & right,
const StereoCameraModel & cameraModel, const StereoCameraModel & cameraModel,
@@ -376,6 +387,7 @@ SensorData::SensorData(
_id(id), _id(id),
_stamp(stamp), _stamp(stamp),
_laserScanMaxPts(laserScanMaxPts), _laserScanMaxPts(laserScanMaxPts),
_laserScanMaxRange(laserScanMaxRange),
_stereoCameraModel(cameraModel) _stereoCameraModel(cameraModel)
{ {
if(left.rows == 1) if(left.rows == 1)

View File

@@ -31,6 +31,7 @@ CREATE TABLE Data (
calibration BLOB, -- fx, fy, cx, cy [,baseline] local_transform calibration BLOB, -- fx, fy, cx, cy [,baseline] local_transform
scan BLOB, -- compressed data (Laser scan) scan BLOB, -- compressed data (Laser scan)
scan_max_pts INTEGER, -- Laser scan max points scan_max_pts INTEGER, -- Laser scan max points
scan_max_range FLOAT, -- Laser max range
user_data BLOB, -- compressed data (User data) user_data BLOB, -- compressed data (User data)
time_enter DATE, time_enter DATE,
PRIMARY KEY (id) PRIMARY KEY (id)

View File

@@ -29,6 +29,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <pcl/filters/extract_indices.h> #include <pcl/filters/extract_indices.h>
#include <pcl/filters/voxel_grid.h> #include <pcl/filters/voxel_grid.h>
#include <pcl/filters/frustum_culling.h>
#include <pcl/filters/random_sample.h> #include <pcl/filters/random_sample.h>
#include <pcl/filters/passthrough.h> #include <pcl/filters/passthrough.h>
@@ -114,13 +115,15 @@ pcl::PointCloud<pcl::PointXYZ>::Ptr passThrough(
const pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud, const pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud,
const std::string & axis, const std::string & axis,
float min, float min,
float max) float max,
bool negative)
{ {
UASSERT(max > min); UASSERT(max > min);
UASSERT(axis.compare("x") == 0 || axis.compare("y") == 0 || axis.compare("z") == 0); UASSERT(axis.compare("x") == 0 || axis.compare("y") == 0 || axis.compare("z") == 0);
pcl::PointCloud<pcl::PointXYZ>::Ptr output(new pcl::PointCloud<pcl::PointXYZ>); pcl::PointCloud<pcl::PointXYZ>::Ptr output(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PassThrough<pcl::PointXYZ> filter; pcl::PassThrough<pcl::PointXYZ> filter;
filter.setNegative(negative);
filter.setFilterFieldName(axis); filter.setFilterFieldName(axis);
filter.setFilterLimits(min, max); filter.setFilterLimits(min, max);
filter.setInputCloud(cloud); filter.setInputCloud(cloud);
@@ -132,13 +135,15 @@ pcl::PointCloud<pcl::PointXYZRGB>::Ptr passThrough(
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud, const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
const std::string & axis, const std::string & axis,
float min, float min,
float max) float max,
bool negative)
{ {
UASSERT(max > min); UASSERT(max > min);
UASSERT(axis.compare("x") == 0 || axis.compare("y") == 0 || axis.compare("z") == 0); UASSERT(axis.compare("x") == 0 || axis.compare("y") == 0 || axis.compare("z") == 0);
pcl::PointCloud<pcl::PointXYZRGB>::Ptr output(new pcl::PointCloud<pcl::PointXYZRGB>); pcl::PointCloud<pcl::PointXYZRGB>::Ptr output(new pcl::PointCloud<pcl::PointXYZRGB>);
pcl::PassThrough<pcl::PointXYZRGB> filter; pcl::PassThrough<pcl::PointXYZRGB> filter;
filter.setNegative(negative);
filter.setFilterFieldName(axis); filter.setFilterFieldName(axis);
filter.setFilterLimits(min, max); filter.setFilterLimits(min, max);
filter.setInputCloud(cloud); filter.setInputCloud(cloud);
@@ -146,6 +151,62 @@ pcl::PointCloud<pcl::PointXYZRGB>::Ptr passThrough(
return output; return output;
} }
pcl::PointCloud<pcl::PointXYZ>::Ptr frustumFiltering(
const pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud,
const Transform & cameraPose,
float horizontalFOV, // in degrees
float verticalFOV, // in degrees
float nearClipPlaneDistance,
float farClipPlaneDistance,
bool negative)
{
UASSERT(horizontalFOV > 0.0f && verticalFOV > 0.0f);
UASSERT(farClipPlaneDistance > nearClipPlaneDistance);
UASSERT(!cameraPose.isNull());
pcl::PointCloud<pcl::PointXYZ>::Ptr output(new pcl::PointCloud<pcl::PointXYZ>);
pcl::FrustumCulling<pcl::PointXYZ> fc;
fc.setNegative(negative);
fc.setInputCloud (cloud);
fc.setVerticalFOV (verticalFOV);
fc.setHorizontalFOV (horizontalFOV);
fc.setNearPlaneDistance (nearClipPlaneDistance);
fc.setFarPlaneDistance (farClipPlaneDistance);
fc.setCameraPose (cameraPose.toEigen4f());
fc.filter (*output);
return output;
}
pcl::PointCloud<pcl::PointXYZRGB>::Ptr frustumFiltering(
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
const Transform & cameraPose,
float horizontalFOV, // in degrees
float verticalFOV, // in degrees
float nearClipPlaneDistance,
float farClipPlaneDistance,
bool negative)
{
UASSERT(horizontalFOV > 0.0f && verticalFOV > 0.0f);
UASSERT(farClipPlaneDistance > nearClipPlaneDistance);
UASSERT(!cameraPose.isNull());
pcl::PointCloud<pcl::PointXYZRGB>::Ptr output(new pcl::PointCloud<pcl::PointXYZRGB>);
pcl::FrustumCulling<pcl::PointXYZRGB> fc;
fc.setNegative(negative);
fc.setInputCloud (cloud);
fc.setVerticalFOV (verticalFOV);
fc.setHorizontalFOV (horizontalFOV);
fc.setNearPlaneDistance (nearClipPlaneDistance);
fc.setFarPlaneDistance (farClipPlaneDistance);
fc.setCameraPose (cameraPose.toEigen4f());
fc.filter (*output);
return output;
}
pcl::PointCloud<pcl::PointXYZ>::Ptr removeNaNFromPointCloud( pcl::PointCloud<pcl::PointXYZ>::Ptr removeNaNFromPointCloud(
const pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud) const pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud)

View File

@@ -50,7 +50,8 @@ void occupancy2DFromLaserScan(
cv::Mat & ground, cv::Mat & ground,
cv::Mat & obstacles, cv::Mat & obstacles,
float cellSize, float cellSize,
bool unknownSpaceFilled) bool unknownSpaceFilled,
float scanMaxRange)
{ {
if(scan.empty()) if(scan.empty())
{ {
@@ -67,7 +68,7 @@ void occupancy2DFromLaserScan(
scans.insert(std::make_pair(1, obstaclesCloud)); scans.insert(std::make_pair(1, obstaclesCloud));
float xMin, yMin; float xMin, yMin;
cv::Mat map8S = create2DMap(poses, scans, cellSize, unknownSpaceFilled, xMin, yMin); cv::Mat map8S = create2DMap(poses, scans, cellSize, unknownSpaceFilled, xMin, yMin, 0.0f, scanMaxRange);
// find ground cells // find ground cells
std::list<int> groundIndices; std::list<int> groundIndices;
@@ -388,6 +389,8 @@ cv::Mat create2DMapFromOccupancyLocalMaps(
* @param unknownSpaceFilled if false no fill, otherwise a virtual laser sweeps the unknown space from each pose (stopping on detected obstacle) * @param unknownSpaceFilled if false no fill, otherwise a virtual laser sweeps the unknown space from each pose (stopping on detected obstacle)
* @param xMin * @param xMin
* @param yMin * @param yMin
* @param minMapSize minimum map size in meters
* @param scanMaxRange laser scan maximum range, would be set if unknownSpaceFilled=true
*/ */
cv::Mat create2DMap(const std::map<int, Transform> & poses, cv::Mat create2DMap(const std::map<int, Transform> & poses,
const std::map<int, pcl::PointCloud<pcl::PointXYZ>::Ptr > & scans, const std::map<int, pcl::PointCloud<pcl::PointXYZ>::Ptr > & scans,
@@ -395,7 +398,8 @@ cv::Mat create2DMap(const std::map<int, Transform> & poses,
bool unknownSpaceFilled, bool unknownSpaceFilled,
float & xMin, float & xMin,
float & yMin, float & yMin,
float minMapSize) float minMapSize,
float scanMaxRange)
{ {
UDEBUG("poses=%d, scans = %d", poses.size(), scans.size()); UDEBUG("poses=%d, scans = %d", poses.size(), scans.size());
std::map<int, pcl::PointCloud<pcl::PointXYZ>::Ptr > localScans; std::map<int, pcl::PointCloud<pcl::PointXYZ>::Ptr > localScans;
@@ -429,7 +433,7 @@ cv::Mat create2DMap(const std::map<int, Transform> & poses,
pcl::getMinMax3D(minMax, min, max); pcl::getMinMax3D(minMax, min, max);
// Added X2 to make sure that all points are inside the map (when rounded to integer) // Added X2 to make sure that all points are inside the map (when rounded to integer)
float marging = cellSize*10.0f; float marging = cellSize*10.0f + (scanMaxRange>0.0f?scanMaxRange/cellSize:0.0f);
xMin = min.x-marging; xMin = min.x-marging;
yMin = min.y-marging; yMin = min.y-marging;
float xMax = max.x+marging; float xMax = max.x+marging;
@@ -440,7 +444,7 @@ cv::Mat create2DMap(const std::map<int, Transform> & poses,
UTimer timer; UTimer timer;
map = cv::Mat::ones((yMax - yMin) / cellSize + 0.5f, (xMax - xMin) / cellSize + 0.5f, CV_8S)*-1; map = cv::Mat::ones((yMax - yMin) / cellSize + 0.5f, (xMax - xMin) / cellSize + 0.5f, CV_8S)*-1;
std::vector<float> maxSquaredLength(localScans.size(), 0.0f); std::vector<float> maxSquaredLength(localScans.size(), scanMaxRange*scanMaxRange);
int j=0; int j=0;
for(std::map<int, pcl::PointCloud<pcl::PointXYZ>::Ptr >::iterator iter = localScans.begin(); iter!=localScans.end(); ++iter) for(std::map<int, pcl::PointCloud<pcl::PointXYZ>::Ptr >::iterator iter = localScans.begin(); iter!=localScans.end(); ++iter)
{ {
@@ -510,7 +514,10 @@ cv::Mat create2DMap(const std::map<int, Transform> & poses,
endRotatedVector.at<float>(1) = endRotated.at<float>(1) - origin.at<float>(1); endRotatedVector.at<float>(1) = endRotated.at<float>(1) - origin.at<float>(1);
endRotatedVector.at<float>(2) = 0.0f; endRotatedVector.at<float>(2) = 0.0f;
//UWARN("endRotated = %f %f", endRotated.at<float>(0), endRotated.at<float>(1)); //UWARN("endRotated = %f %f", endRotated.at<float>(0), endRotated.at<float>(1));
while(endRotatedVector.cross(endLastVector).at<float>(2) > 0.0f) float CV_PI_2 = CV_PI/2.0f;
float normEndRotatedVector = cv::norm(endRotatedVector);
endLastVector = endLastVector / cv::norm(endLastVector);
while(acos((endRotatedVector/normEndRotatedVector).dot(endLastVector)) > CV_PI_2 || endRotatedVector.cross(endLastVector).at<float>(2) > 0.0f)
{ {
cv::Point2i end((endRotated.at<float>(0)-xMin)/cellSize + 0.5f, (endRotated.at<float>(1)-yMin)/cellSize + 0.5f); cv::Point2i end((endRotated.at<float>(0)-xMin)/cellSize + 0.5f, (endRotated.at<float>(1)-yMin)/cellSize + 0.5f);
//end must be inside the grid //end must be inside the grid
@@ -519,7 +526,6 @@ cv::Mat create2DMap(const std::map<int, Transform> & poses,
end.y = end.y < 0?0:end.y; end.y = end.y < 0?0:end.y;
end.y = end.y >= map.rows?map.rows-1:end.y; end.y = end.y >= map.rows?map.rows-1:end.y;
rayTrace(start, end, map, true); // trace free space rayTrace(start, end, map, true); // trace free space
// next point // next point
endRotated = rotation*(endRotated - origin) + origin; endRotated = rotation*(endRotated - origin) + origin;
endRotatedVector.at<float>(0) = endRotated.at<float>(0) - origin.at<float>(0); endRotatedVector.at<float>(0) = endRotated.at<float>(0) - origin.at<float>(0);

View File

@@ -33,7 +33,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <rtabmap/utilite/UConversion.h> #include <rtabmap/utilite/UConversion.h>
#include <rtabmap/core/util3d.h> #include <rtabmap/core/util3d.h>
#include <pcl/visualization/pcl_visualizer.h> #include <pcl/visualization/pcl_visualizer.h>
#include <pcl/filters/frustum_culling.h>
#include <QMenu> #include <QMenu>
#include <QAction> #include <QAction>
#include <QtGui/QContextMenuEvent> #include <QtGui/QContextMenuEvent>

View File

@@ -848,6 +848,7 @@ void DatabaseViewer::exportDatabase()
sensorData = rtabmap::SensorData( sensorData = rtabmap::SensorData(
dialog.isDepth2dExported()?data.laserScanRaw():cv::Mat(), dialog.isDepth2dExported()?data.laserScanRaw():cv::Mat(),
dialog.isDepth2dExported()?data.laserScanMaxPts():0, dialog.isDepth2dExported()?data.laserScanMaxPts():0,
dialog.isDepth2dExported()?data.laserScanMaxRange():0,
dialog.isRgbExported()?data.imageRaw():cv::Mat(), dialog.isRgbExported()?data.imageRaw():cv::Mat(),
dialog.isDepthExported()?data.depthOrRightRaw():cv::Mat(), dialog.isDepthExported()?data.depthOrRightRaw():cv::Mat(),
data.cameraModels(), data.cameraModels(),
@@ -860,6 +861,7 @@ void DatabaseViewer::exportDatabase()
sensorData = rtabmap::SensorData( sensorData = rtabmap::SensorData(
dialog.isDepth2dExported()?data.laserScanRaw():cv::Mat(), dialog.isDepth2dExported()?data.laserScanRaw():cv::Mat(),
dialog.isDepth2dExported()?data.laserScanMaxPts():0, dialog.isDepth2dExported()?data.laserScanMaxPts():0,
dialog.isDepth2dExported()?data.laserScanMaxRange():0,
dialog.isRgbExported()?data.imageRaw():cv::Mat(), dialog.isRgbExported()?data.imageRaw():cv::Mat(),
dialog.isDepthExported()?data.depthOrRightRaw():cv::Mat(), dialog.isDepthExported()?data.depthOrRightRaw():cv::Mat(),
data.stereoCameraModel(), data.stereoCameraModel(),