#include <iostream>
#include <vector>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/visualization/pcl_visualizer.h>
#include "region_growing.h"
boost::mutex mutex_;
using namespace std;
using namespace pcl;
typedef PointCloud<PointXYZ> PCT;
typedef PointXYZ PointT;
PCT::Ptr cloud(new PCT());
vector<int>idx_all;
struct callback_args
{
PCT::Ptr clicked_3d_data;
visualization::PCLVisualizer::Ptr view;
};
void point_picked(const visualization::PointPickingEvent&event, void *arge){
callback_args *data = (callback_args*)arge;
if (event.getPointIndex()==-1)
{
return;
}
idx_all.push_back(event.getPointIndex());
copyPointCloud(*cloud, idx_all, *data->clicked_3d_data);
visualization::PointCloudColorHandlerCustom<PointT>color(data->clicked_3d_data, 255, 0, 0);
data->view->removePointCloud("clicked_point");
data->view->addPointCloud(data->clicked_3d_data, color, "clicked_point");
data->view->setPointCloudRenderingProperties(visualization::PCL_VISUALIZER_POINT_SIZE, 5, "clicked_point");
}
int main()
{
io::loadPCDFile("C:\\Users\\admin\\Desktop\\test.pcd", *cloud);
mutex_.lock();
visualization::PCLVisualizer::Ptr viewer(new visualization::PCLVisualizer("点选"));
viewer->addPointCloud(cloud);
callback_args cb_args;
PCT::Ptr clicked_3d_data(new PCT);
cb_args.clicked_3d_data = clicked_3d_data;
cb_args.view = viewer;
viewer->registerPointPickingCallback(point_picked, (void*)&cb_args);
viewer->spin();
mutex_.unlock();
std::cout << "程序结束" << std::endl;
return 0;
}
点选+区域生长:
//主程序-------------------------
#include "region_growing.h"
#include <iostream>
#include <vector>
#include <ctime>
#include <string>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/visualization/pcl_visualizer.h>
boost::mutex mutex_;
using namespace std;
using namespace pcl;
typedef PointCloud<PointXYZ> PCT;
typedef PointXYZ PointT;
PCT::Ptr cloud(new PCT());
vector<int>idx_all;
region_growing reg_grow;
struct callback_args
{
PCT::Ptr clicked_3d_data;
visualization::PCLVisualizer::Ptr view;
};
void point_picked(const visualization::PointPickingEvent&event, void *arge){
callback_args *data = (callback_args*)arge;
if (event.getPointIndex() == -1)
{
return;
}
vector<int>tem_index;
idx_all.push_back(event.getPointIndex());
tem_index.push_back(event.getPointIndex());
copyPointCloud(*cloud, idx_all, *data->clicked_3d_data);
visualization::PointCloudColorHandlerCustom<PointT>color(data->clicked_3d_data, 255, 0, 0);
data->view->removePointCloud("clicked_point");
data->view->addPointCloud(data->clicked_3d_data, color, "clicked_point");
data->view->setPointCloudRenderingProperties(visualization::PCL_VISUALIZER_POINT_SIZE, 10, "clicked_point");
//区域生长********************
//srand(time(nullptr));
stringstream ss;
ss << "region_growing" << tem_index[0];
cout << ss.str() << endl;
PCT::Ptr region_growing_point(new PCT());
vector<int>index_reg_grow;
index_reg_grow = reg_grow.region_growing_one(tem_index[0]);
copyPointCloud(*cloud, index_reg_grow, *region_growing_point);
visualization::PointCloudColorHandlerRandom<PointT>region_growing_point_color(region_growing_point);
data->view->addPointCloud(region_growing_point, region_growing_point_color, ss.str());
data->view->setPointCloudRenderingProperties(visualization::PCL_VISUALIZER_POINT_SIZE, 3, ss.str());
}
int main()
{
io::loadPCDFile("C:\\Users\\admin\\Desktop\\test.pcd", *cloud);
reg_grow.set_normal_curvature(0.3, 10.0);
reg_grow.setinput_point(cloud);
reg_grow.normal_estimation(10);
mutex_.lock();
visualization::PCLVisualizer::Ptr viewer(new visualization::PCLVisualizer("点选"));
viewer->addPointCloud(cloud);
callback_args cb_args;
PCT::Ptr clicked_3d_data(new PCT);
cb_args.clicked_3d_data = clicked_3d_data;
cb_args.view = viewer;
viewer->registerPointPickingCallback(point_picked, (void*)&cb_args);
viewer->spin();
mutex_.unlock();
std::cout << "程序结束" << std::endl;
return 0;
}
//头文件
#include <pcl/io/pcd_io.h>
#include <pcl/search/kdtree.h>
#include <vector>
#include <pcl/features/normal_3d.h>
#include <Eigen/dense>
#include <cmath>
#include <ctime>
#include<pcl/visualization/pcl_visualizer.h>
using namespace pcl;
using namespace Eigen;
using namespace std;
typedef PointXYZ PointT;
class region_growing
{
public:
region_growing();
void setinput_point(PointCloud<PointT>::Ptr &point_cloud);
void set_normal_curvature(float , float );
void normal_estimation(int );
vector<int> region_growing_one(int index_point);
private:
PointCloud<PointT>::Ptr cloud;
float curvature_threshold;
float normal_threshold;
int K_nebor_size;
PointCloud<Normal>::Ptr normal_;
vector<int>all_index;
};
region_growing::region_growing(){
curvature_threshold = 0.2;
normal_threshold = 10.0;
K_nebor_size = 10;
}
inline void region_growing::set_normal_curvature(float curvature_threshold1, float normal_threshold1)
{
curvature_threshold = curvature_threshold1;
normal_threshold = normal_threshold1;
}
void region_growing::setinput_point(PointCloud<PointT>::Ptr &point_cloud){
cloud=point_cloud;
}
void region_growing::normal_estimation(int K_nebor_size){
PointCloud<Normal>::Ptr normal(new PointCloud<Normal>);
search::KdTree<PointT>::Ptr tree(new search::KdTree<PointT>);
tree->setInputCloud(cloud);
NormalEstimation<PointT, Normal>ne;
ne.setInputCloud(cloud);
ne.setSearchMethod(tree);
ne.setKSearch(K_nebor_size);
ne.compute(*normal);
normal_ = normal;
}
vector<int> region_growing::region_growing_one(int index_point){
search::KdTree<PointXYZ>::Ptr tree(new search::KdTree<PointXYZ>);
tree->setInputCloud(cloud);
float normal_threshold_real = cosf(normal_threshold / 180.0 * M_PI);
queue<int>seed;
seed.push(index_point);
vector<int>point_label;
vector<int>nebor_idx;
vector<float>nebor_distance;
point_label.resize(cloud->points.size(), -1);
point_label[index_point] = 0;
while (!seed.empty())
{
int curr_seed = seed.front();
seed.pop();
int K_nebor(0);
tree->nearestKSearch(cloud->points[curr_seed], K_nebor_size, nebor_idx, nebor_distance);
while (K_nebor < nebor_idx.size())
{
int index_nebor = nebor_idx[K_nebor];
if (point_label[index_nebor] != -1)
{
K_nebor++;
continue;
}
bool is_a_seed = false;
Map<Vector3f>curr_seed(static_cast<float*>(normal_->points[curr_seed].normal));
Map<Vector3f>seed_nebor(static_cast<float*>(normal_->points[index_nebor].normal));
float dot_normal = fabsf(curr_seed.dot(seed_nebor));
if (dot_normal<normal_threshold_real)
{
is_a_seed = false;
}
else if (normal_->points[index_nebor].curvature>curvature_threshold)
{
is_a_seed = false;
}
else
{
is_a_seed = true;
}
if (!is_a_seed)
{
K_nebor++;
continue;
}
all_index.push_back(index_nebor);
point_label[index_nebor] = 0;
if (is_a_seed)
{
seed.push(index_nebor);
}
K_nebor++;
}
}
return all_index;
}
根据拾取的种子点,进行法向量和曲率的区域生长