-
-
Notifications
You must be signed in to change notification settings - Fork 4.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b268d07
commit d7da661
Showing
3 changed files
with
221 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
.. _BoxClipper3D: | ||
|
||
Extracting points inside a box | ||
------------------------------------ | ||
|
||
In this tutorial we will learn how to use the BoxClipper3D filter to extract a subset of | ||
points from a point cloud. In this example we will create a point cloud and some points will be inside the box and some on the outside. The way the BoxClipper3D works is counter intuitive. Instead of having to put the box somewhere and have the right inclination to fit the points we want to extract, we have to do the reverse operation on the cloud so the points we want to extract move inside the box. We will se how this works in this example. | ||
|
||
The code | ||
-------- | ||
|
||
|
||
Then, create a file, let's say, ``extract_points.cpp`` in your favorite | ||
editor, and place the following inside it: | ||
|
||
.. literalinclude:: sources/boxClipper3D/boxClipper3D_example.cpp | ||
:language: cpp | ||
:linenos: | ||
|
||
|
||
The explanation | ||
--------------- | ||
|
||
Here we define our simple point cloud with its inliers and outliers and we rotate the cloud 45 degree on its Z axis; | ||
|
||
.. literalinclude:: sources/boxClipper3D/boxClipper3D_example.cpp | ||
:language: cpp | ||
:lines: 133-145 | ||
|
||
Now lets look at the magic. | ||
|
||
.. literalinclude:: sources/boxClipper3D/boxClipper3D_example.cpp | ||
:language: cpp | ||
:lines: 23-46 | ||
|
||
We have to define three transformation: a translation, a rotation and a scaling factor; | ||
.. literalinclude:: sources/boxClipper3D/boxClipper3D_example.cpp | ||
:language: cpp | ||
:lines: 27-31 | ||
|
||
If we think about the intuitive way: We have a point cloud that is rotated 45 degree on its Z axis. | ||
Lets picture our self creating a box starting at (0,0,0). Then, we want to fit our inliers inside the box. So we have to translate the box by a vector of (1,1,1) and then rotate it of 45 degree on its Z axis and than scale the box to only fit the points we want. | ||
|
||
But as mentioned earlier the way the boxClipper3D works is the opposite. Therefore, we have to translate the cloud by a vector of (-1,-1,-1) and then rotate it of -45 degree on its Z axis so the points we want to extract fits inside the box. The box is 2x2x2 and it starts at (-1,-1,-1) and it ends at (1,1,1). | ||
|
||
Compiling and running the program | ||
--------------------------------- | ||
|
||
Add the following lines to your CMakeLists.txt file: | ||
|
||
.. literalinclude:: sources/boxClipper3D/CMakeLists.txt | ||
:language: cmake | ||
:linenos: | ||
|
||
After you have made the executable, you can run it. Simply do:: | ||
|
||
$ ./extract_points | ||
|
||
You will see something similar to:: | ||
|
||
nb inliers: 3 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
cmake_minimum_required(VERSION 2.6 FATAL_ERROR) | ||
project(boxClipper3D_example) | ||
|
||
add_definitions(-std=c++17 -Wall -g) | ||
find_package (Eigen3 3.3 REQUIRED NO_MODULE) | ||
find_package(PCL 1.10 REQUIRED) | ||
|
||
include_directories( ${PCL_INCLUDE_DIRS} ) | ||
link_directories(${PCL_LIBRARY_DIRS}) | ||
add_definitions(${PCL_DEFINITIONS}) | ||
|
||
add_executable(extract_points example_boxClipper3D.cpp) | ||
target_link_libraries(extract_points ${PCL_LIBRARIES}) |
146 changes: 146 additions & 0 deletions
146
doc/tutorials/content/sources/boxClipper3D/example_boxClipper3D.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
/*! | ||
* \Author: Patrick Charron-Morneau | ||
* \Interdisciplinary Centre for the Development of Ocean Mapping (CIDCO) | ||
*/ | ||
|
||
#include <iostream> | ||
#include <pcl/point_cloud.h> | ||
#include <pcl/visualization/cloud_viewer.h> | ||
#include <pcl/filters/box_clipper3D.h> | ||
#include <pcl/filters/extract_indices.h> | ||
#include <pcl/common/transforms.h> | ||
|
||
|
||
class pointExtractor{ | ||
|
||
public: | ||
pointExtractor(){ | ||
this->cloud = pcl::PointCloud<pcl::PointXYZRGB>::Ptr (new pcl::PointCloud<pcl::PointXYZRGB>); | ||
} | ||
|
||
~pointExtractor(){} | ||
|
||
|
||
void extractPoints(pcl::Indices & windowPoints){ | ||
|
||
this->inliers = pcl::PointCloud<pcl::PointXYZRGB>::Ptr (new pcl::PointCloud<pcl::PointXYZRGB>); | ||
|
||
Eigen::Vector3f rodrigues(0, 0, -0.7853982); // Eigen::Vector3f rodrigues(x,y,z) in radians | ||
Eigen::Vector3f translation(-1 ,-1 ,-1); | ||
Eigen::Vector3f box_size (1/1, 1/1, 1/1); | ||
|
||
pcl::BoxClipper3D<pcl::PointXYZRGB> boxClipper(rodrigues, translation, box_size); | ||
boxClipper.clipPointCloud3D (*this->cloud, windowPoints); | ||
std::cerr<<"nb inliers: " << windowPoints.size()<<"\n"; | ||
|
||
pcl::IndicesPtr idxPtr = std::make_shared<pcl::Indices>(windowPoints); | ||
|
||
pcl::ExtractIndices<pcl::PointXYZRGB> extract; | ||
extract.setInputCloud (this->cloud); | ||
extract.setIndices (idxPtr); | ||
extract.setNegative (false); | ||
extract.filter (*this->inliers); | ||
|
||
//showPointCloud(this->inliers, "box clipper"); | ||
} | ||
|
||
void setInlier(){ | ||
pcl::PointXYZRGB pt; | ||
uint8_t r = 0, g = 255, b = 0; | ||
uint32_t rgb = ((uint32_t)r << 16 | (uint32_t)g << 8 | (uint32_t)b); | ||
pt.x = 1.1; | ||
pt.y = 1.1; | ||
pt.z = 1.1; | ||
pt.rgba = rgb; | ||
this->cloud->push_back(pt); | ||
|
||
pcl::PointXYZRGB pt1; | ||
pt1.x = 1.4; | ||
pt1.y = 1.4; | ||
pt1.z = 1.4; | ||
pt1.rgba = rgb; | ||
this->cloud->push_back(pt1); | ||
|
||
pcl::PointXYZRGB pt8; | ||
pt8.x = 0.1; | ||
pt8.y = 0.1; | ||
pt8.z = 0.1; | ||
pt8.rgba = rgb; | ||
this->cloud->push_back(pt8); | ||
} | ||
|
||
void setOutlier(){ | ||
pcl::PointXYZRGB pt; | ||
uint8_t r = 255, g = 0, b = 0; | ||
uint32_t rgb = ((uint32_t)r << 16 | (uint32_t)g << 8 | (uint32_t)b); | ||
pt.x = 2.1; | ||
pt.y = 2.1; | ||
pt.z = 2.1; | ||
pt.rgba = rgb; | ||
this->cloud->push_back(pt); | ||
|
||
pcl::PointXYZRGB pt9; | ||
pt9.x = 2.5; | ||
pt9.y = 2.5; | ||
pt9.z = 2.5; | ||
pt9.rgba = rgb; | ||
this->cloud->push_back(pt9); | ||
|
||
pcl::PointXYZRGB pt11; | ||
pt11.x = -2.7; | ||
pt11.y = -2.7; | ||
pt11.z = -2.7; | ||
pt11.rgba = rgb; | ||
this->cloud->push_back(pt11); | ||
} | ||
|
||
void rotateCloud(){ | ||
Eigen::Affine3f transform = Eigen::Affine3f::Identity(); | ||
|
||
// 45 deg | ||
transform.rotate (Eigen::AngleAxisf (0.7853982, Eigen::Vector3f::UnitZ())); | ||
|
||
// Executing the transformation | ||
this->transformed_cloud = pcl::PointCloud<pcl::PointXYZRGB>::Ptr (new pcl::PointCloud<pcl::PointXYZRGB>); | ||
pcl::transformPointCloud (*this->cloud, *transformed_cloud, transform); | ||
|
||
//showPointCloud(this->cloud, "original cloud"); | ||
this->cloud->swap(*transformed_cloud); | ||
//showPointCloud(this->cloud, "rotated cloud"); | ||
} | ||
|
||
|
||
void showPointCloud(pcl::PointCloud<pcl::PointXYZRGB>::Ptr pointCloud, std::string windowName){ | ||
pcl::visualization::CloudViewer viewer (windowName); | ||
|
||
viewer.showCloud (pointCloud); | ||
|
||
while (!viewer.wasStopped ()){ | ||
|
||
} | ||
} | ||
|
||
private: | ||
|
||
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud; | ||
pcl::PointCloud<pcl::PointXYZRGB>::Ptr inliers; | ||
pcl::PointCloud<pcl::PointXYZRGB>::Ptr transformed_cloud; | ||
|
||
}; | ||
|
||
|
||
int main(int argc,char** argv){ | ||
|
||
pointExtractor pe; | ||
|
||
pe.setInlier(); | ||
|
||
pe.setOutlier(); | ||
|
||
pe.rotateCloud(); | ||
|
||
pcl::Indices indexes; | ||
|
||
pe.extractPoints(indexes); | ||
} | ||
|