principle
Octree is a tree structure for managing sparse 3D data. Octree is used to detect the spatial change between multiple disordered point clouds, which may be in size. There are differences in resolution, density, and point order. By recursively comparing the tree structure of octree, the spatial changes represented by the differences in voxel composition generated by octree can be identified, and the differences in spatial composition among multiple point clouds can be detected in real time through octree's "double buffer" technology.
The detection of the spatial change of disordered point clouds is actually the difference detection of the front and rear point clouds under the octree structure. Therefore, we should first load an original point cloud and generate the first octree structure; Then cut the buffer, load the second point cloud and generate the second octree structure; Finally, for comparison, if some leaf nodes are on the second octree, but not on the first octree, then the points in these leaf nodes are considered to be the points with more spatial changes.
Code
=====================================================
#include <pcl/point_cloud.h> #include <pcl/octree/octree.h> #include <iostream> #include <vector> #include <ctime>
Included header file
=====================================================
//It is used to create time random seeds and take random numbers srand ((unsigned int) time (NULL)); //Declare A point cloud A pointer and allocate space pcl::PointCloud<pcl::PointXYZ>::Ptr cloudA (new pcl::PointCloud<pcl::PointXYZ> ); //Define the point cloud size, 128 point clouds, out of order cloudA->width =128; cloudA->height =1; cloudA->points.resize (cloudA->width *cloudA->height); //Circularly assign a value to the point cloud through the coordinates 0-64 of the random number point cloud for (size_t i=0; i<cloudA->points.size (); ++i) { cloudA->points[i].x =64.0f* rand () / (RAND_MAX +1.0f); cloudA->points[i].y =64.0f* rand () / (RAND_MAX +1.0f); cloudA->points[i].z =64.0f* rand () / (RAND_MAX +1.0f); }
Create a point cloud cloudA
The number is 128, and the coordinates 0-64 of x, y and z take random values
=====================================================
/* Setting the resolution describes the size of the smallest voxel of the lowest level octree*/ float resolution =32.0f; /* Build the class of octree change detection and set the resolution */ pcl::octree::OctreePointCloudChangeDetector<pcl::PointXYZ>octree (resolution);
Build the class of octree change detection and set the resolution
=====================================================
/* Point cloud of assignment octree */ octree.setInputCloud (cloudA);//Set the imported point cloud octree.addPointsFromInputCloud ();//Add the imported point cloud to the octree
Input cloudA into octree, build its data structure and use it as base point cloud
Later, more points than its point cloud can be detected. However, you cannot detect points that are less than the second point cloud
=====================================================
/*Swap the octree cache, but the octree corresponding to cloudA is still in memory*/ octree.switchBuffers ();
Point cloud cloudA is a reference point cloud, and its octree object is used to describe its spatial distribution
OctreePointCloudChangeDetector inherits from the Octree2BufBase class, which allows two octrees to be saved and managed in memory at the same time
It applies the memory pool, reuses the allocated node objects, and reduces memory allocation and release operations
By visiting octree Switchbuffers () resets the cache of octree objects, but keeps the previous octree in the cache
=====================================================
//Declare a point cloud B pointer and allocate space pcl::PointCloud<pcl::PointXYZ>::Ptr cloudB (new pcl::PointCloud<pcl::PointXYZ> ); //Define the point cloud size, 128 point clouds, out of order cloudB->width =128; cloudB->height =1; cloudB->points.resize (cloudB->width *cloudB->height); //Circularly assign a value to the point cloud through the coordinates 0-64 of the random number point cloud for (size_t i=0; i<cloudB->points.size (); ++i) { cloudB->points[i].x =90.0f* rand () / (RAND_MAX +1.0f); cloudB->points[i].y =90.0f* rand () / (RAND_MAX +1.0f); cloudB->points[i].z =90.0f* rand () / (RAND_MAX +1.0f); }
Declare a point cloud B pointer and allocate space
The number is 128, and the coordinates 0-90 of x, y and z take random values
The range is A little larger than A, which is easy to be effective
=====================================================
/*Declare the index value save vector of point cloud with more B than A*/ std::vector<int>newPointIdxVector; /* Get the index value that B is more than A. note that the index value that B is less than a will not be obtained */ octree.getPointIndicesFromNewVoxels (newPointIdxVector);
Get more index values of B than A through the function getpointindexfromnewvoxels
=====================================================
// The terminal prints more point clouds from B than A std::cout<<"Output from getPointIndicesFromNewVoxels:"<<std::endl; for (size_t i=0; i<newPointIdxVector.size (); ++i) std::cout<<i<<"# Index:"<<newPointIdxVector[i] <<" Point:"<<cloudB->points[newPointIdxVector[i]].x <<" " <<cloudB->points[newPointIdxVector[i]].y <<" " <<cloudB->points[newPointIdxVector[i]].z <<std::endl;
The terminal prints more point clouds from B than A
=====================================================
//Declare a point cloud C pointer and allocate space pcl::PointCloud<pcl::PointXYZ>::Ptr cloudC (new pcl::PointCloud<pcl::PointXYZ> ); //Define the size of the point cloud and the number of point clouds. The number of B calculated above is more than A, which is out of order cloudC->width =newPointIdxVector.size (); cloudC->height =1; cloudC->points.resize (cloudC->width *cloudC->height); for(size_t i=0;i<newPointIdxVector.size ();++i) { cloudC->points[i]=cloudB->points[newPointIdxVector[i]]; }
Create A new point cloud C to save more points from B than A
=====================================================
//Visualization module pcl::visualization::PCLVisualizer::Ptr viewer (new pcl::visualization::PCLVisualizer ("3D Viewwe"));//Create pointer viewer viewer->initCameraParameters();//Initialize camera parameters
Add a visual module to display the point cloud
=====================================================
int v1(0);//Parameters of the first window viewer->createViewPort(0.0,0.0,0.33,1,v1); //Sets the size of the first window, located on the left side of the screen viewer->setBackgroundColor(0,0,0,v1);//background of first port viewer->addText("cloudA",10,10,"cloudA",v1);//It's like a note pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color1(cloudA,255,0,0);//Sets the color of the first point cloud viewer->addPointCloud<pcl::PointXYZ>(cloudA,single_color1,"cloudA",v1);//Show first point cloud
Display point cloud A in red
=====================================================
int v2(0);//Parameters of the first window viewer->createViewPort(0.33,0,0.66,1,v2);//Sets the size of the second window, located on the right side of the screen viewer->setBackgroundColor(0,0,0,v2);//background of second port viewer->addText("cloudB",10,9,"cloudB",v2);//Output a line of text pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color2(cloudB,0,255,0);//Sets the color of the second point cloud viewer->addPointCloud<pcl::PointXYZ>(cloudB,single_color2,"simple_cloud2",v2);//Displays the second point cloud
The second window Point Cloud B is displayed in green
=====================================================
//Third point cloud window int v3(0);//Parameters of the third window viewer->createViewPort(0.66,0,1,1,v3);//Window size viewer->setBackgroundColor(0,0,0,v3);//background color viewer->addText("cloud_result",10,8,"cloud_result",v3);//It's like a note pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color3(cloudC,255,255,255);//Point cloud color viewer->addPointCloud<pcl::PointXYZ>(cloudA,single_color1,"cloud1",v3);//Show point cloud viewer->addPointCloud<pcl::PointXYZ>(cloudB,single_color2,"cloud2",v3);//Show point cloud viewer->addPointCloud<pcl::PointXYZ>(cloudC,single_color3,"cloud3",v3);//Show point cloud viewer->addCoordinateSystem(2);//Add coordinate system viewer->spin();
The third window displays point clouds A, B, and C together. Let's see the overall effect
=====================================================
Result
The terminal prints more point clouds of B than A
Point cloud display
Point cloud A is on the left and point cloud B is in the middle
On the right is the combination of three point clouds;
The red ones are those that point cloud A has and point cloud B does not have; Green is shared by A and B; White is more B than A.