Extraire la plus petite boîte englobante (AABB, OBB)
Présentation de la zone de délimitation minimale
Le rectangle englobant est également appelé rectangle minimal circonscrit. Il s'agit d'un algorithme permettant de résoudre l'espace de délimitation optimal de l'ensemble de points discrets. L'idée de base est d'utiliser un volume légèrement plus grand et une géométrie plus simple (appelée rectangle englobant) pour remplacer approximativement des objets géométriques complexes.
Les algorithmes communs de boîte englobante incluent la boîte englobante AABB, la boule englobante, la boîte englobante directionnelle OBB et la coque convexe à direction fixe FDH. Le problème de la détection des collisions a un large éventail d'applications dans les domaines de la réalité virtuelle, de la conception et de la fabrication assistées par ordinateur, des jeux et des robots, et devient même une technologie clé. L'algorithme de la boîte englobante est l'une des méthodes importantes pour la détection préliminaire des interférences de collision.
Extraction des boîtes englobantes AABB et OBB
#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL);
VTK_MODULE_INIT(vtkInteractionStyle);
#include <pcl/features/moment_of_inertia_estimation.h>
#include <vector>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/visualization/cloud_viewer.h>
#include <boost/thread/thread.hpp>
#include <pcl/visualization/cloud_viewer.h>
int main(int argc, char** argv)
{
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>());
if (pcl::io::loadPCDFile("test.pcd", *cloud) == -1)
{
PCL_ERROR("Cloudn't read file!");
system("pause");
return -1;
}
pcl::MomentOfInertiaEstimation <pcl::PointXYZ> feature_extractor;
feature_extractor.setInputCloud(cloud);
feature_extractor.compute();
std::vector <float> moment_of_inertia;
std::vector <float> eccentricity;
pcl::PointXYZ min_point_AABB;
pcl::PointXYZ max_point_AABB;
pcl::PointXYZ min_point_OBB;
pcl::PointXYZ max_point_OBB;
pcl::PointXYZ position_OBB;
Eigen::Matrix3f rotational_matrix_OBB;
float major_value, middle_value, minor_value;
Eigen::Vector3f major_vector, middle_vector, minor_vector;
Eigen::Vector3f mass_center;
feature_extractor.getMomentOfInertia(moment_of_inertia);
feature_extractor.getEccentricity(eccentricity);
feature_extractor.getAABB(min_point_AABB,max_point_AABB);
feature_extractor.getOBB(min_point_OBB,max_point_OBB, position_OBB, rotational_matrix_OBB);
feature_extractor.getEigenValues(major_value,middle_value, minor_value);
feature_extractor.getEigenVectors(major_vector,middle_vector, minor_vector);
feature_extractor.getMassCenter(mass_center);
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));
viewer->setBackgroundColor(1,1, 1);
viewer->addCoordinateSystem(1.0);
viewer->initCameraParameters();
viewer->addPointCloud<pcl::PointXYZ>(cloud,pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ>(cloud, 0,255, 0), "sample cloud");
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE,
5, "sample cloud");
viewer->addCube(min_point_AABB.x,max_point_AABB.x,min_point_AABB.y,max_point_AABB.y,min_point_AABB.z,max_point_AABB.z, 1.0, 0.0, 0.0, "AABB");
viewer->setShapeRenderingProperties(pcl::visualization::PCL_VISUALIZER_OPACITY,
0.1, "AABB");
viewer->setShapeRenderingProperties(pcl::visualization::PCL_VISUALIZER_LINE_WIDTH,
4, "AABB");
Eigen::Vector3f position(position_OBB.x, position_OBB.y, position_OBB.z);
std::cout<< "position_OBB: " << position_OBB << endl;
std::cout<< "mass_center: " << mass_center << endl;
Eigen::Quaternionf quat(rotational_matrix_OBB);
viewer->addCube(position,quat, max_point_OBB.x - min_point_OBB.x, max_point_OBB.y - min_point_OBB.y,max_point_OBB.z - min_point_OBB.z, "OBB");
viewer->setShapeRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR,
0, 0, 1, "OBB");
viewer->setShapeRenderingProperties(pcl::visualization::PCL_VISUALIZER_OPACITY,
0.1, "OBB");
viewer>setShapeRenderingProperties(pcl::visualization::PCL_VISUALIZER_LINE_WIDTH,
4, "OBB");
viewer->setRepresentationToWireframeForAllActors();
pcl::PointXYZ center(mass_center(0), mass_center(1), mass_center(2));
pcl::PointXYZ x_axis(major_vector(0) + mass_center(0), major_vector(1) + mass_center(1), major_vector(2) + mass_center(2));
pcl::PointXYZ y_axis(middle_vector(0) + mass_center(0), middle_vector(1) +mass_center(1),middle_vector(2) + mass_center(2));
pcl::PointXYZ z_axis(minor_vector(0) + mass_center(0), minor_vector(1) +mass_center(1),minor_vector(2) + mass_center(2));
viewer->addLine(center,x_axis, 1.0f, 0.0f, 0.0f, "major eigen vector");
viewer->addLine(center,y_axis, 0.0f, 1.0f, 0.0f, "middle eigen vector");
viewer->addLine(center,z_axis, 0.0f, 0.0f, 1.0f, "minor eigen vector");
std::cout<< "size of cloud :" << cloud->points.size() <<endl;
std::cout << "moment_of_inertia :" << moment_of_inertia.size() << endl;
std::cout<< "eccentricity :" << eccentricity.size() << endl;
viewer->setCameraPosition(0,0, 0, 0, 156, -20, 0, 0, 1, 0);//设置相机位置,焦点,方向
while (!viewer->wasStopped())
{
viewer->spinOnce(100);
boost::this_thread::sleep(boost::posix_time::microseconds(100000));
}
system("pause");
return (0);
}