2016-02-21 4 views
1

У меня есть данные облака точек, где, щелкнув точку, я хочу извлечь точки вокруг точки щелчка в радиусе. Я хочу также вытащить извлеченные точки в новое облако. Используя Pointpickingevent, я могу щелкнуть одну точку и вставить ее в облако. Как извлечь набор точек, например, точки вокруг радиуса 0,02 см от точки щелчка и вставить их в новое облако?Как извлечь набор точек в данных облачных точек с помощью PCL?

ответ

1

Учитывая облако точек:

pcl::PointCloud<pcl::PointXYZ>::Ptr cloud

Kdtree Затем генерируется для выполнения эффективного поиска диапазон:

pcl::KdTreeFLANN<pcl::PointXYZ> kdtree; 
kdtree.setInputCloud (cloud); 

Тогда, учитывая точку и радиус:

pcl::PointXYZ searchPoint(1,2,3); 
float radius = 4; 

Вы можете получить все очки, которые находятся на расстоянии радиус от точки Searchpoint:

std::vector<int> pointIdxRadiusSearch; //to store index of surrounding points 
std::vector<float> pointRadiusSquaredDistance; // to store distance to surrounding points 

if (kdtree.radiusSearch (searchPoint, radius, pointIdxRadiusSearch, pointRadiusSquaredDistance) > 0) 
{ 
    for (size_t i = 0; i < pointIdxRadiusSearch.size(); ++i) 
     std::cout << " " << cloud->points[ pointIdxRadiusSearch[i] ].x 
       << " " << cloud->points[ pointIdxRadiusSearch[i] ].y 
       << " " << cloud->points[ pointIdxRadiusSearch[i] ].z 
       << " (squared distance: " << pointRadiusSquaredDistance[i] << ")" << std::endl; 
} 

Вы можете напечатать все окружающие точки и их расстояние до Searchpoint проверить функциональную правильность кода.

Наконец, создать облако с найденными точками:

pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_cluster (new pcl::PointCloud<pcl::PointXYZ>); 
for (size_t i = 0; i < pointIdxRadiusSearch.size(); ++i) 
    cloud_cluster->points.push_back(cloud->points[ pointIdxRadiusSearch[i] ]); 
cloud_cluster->width = cloud_cluster->points.size(); 
cloud_cluster->height = 1; 
cloud_cluster->is_dense = true; 
0

Для того, чтобы иметь возможность выбрать точку, которую вы можете использовать PointPickingEvent аналогично this answer.

Декларация класса в вашем .h,

class PCLViewer : public QMainWindow 
{ 
    Q_OBJECT 

public: 
    explicit PCLViewer (QWidget *parent = 0); 
    ~PCLViewer(); 
    void pointPickCallback (const pcl::visualization::PointPickingEvent& event, void*); 

public slots: 

protected: 
    boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer; 
    pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud; 
    pcl::PointXYZ src_point_; 
    bool src_point_selected_; 

private: 
    Ui::PCLViewer *ui; 

}; 

В вашем .cpp,

PCLViewer::PCLViewer (QWidget *parent) : 
    QMainWindow (parent), 
    ui (new Ui::PCLViewer) 
{ 
    ui->setupUi (this); 

    [...] 

    viewer.reset (new pcl::visualization::PCLVisualizer ("viewer", false)); 
    viewer->registerPointPickingCallback (&PCLViewer::pointPickCallback, *this); 

    [...] 
} 

и дополнительные функции,

void 
PCLViewer::pointPickCallback (const pcl::visualization::PointPickingEvent& event, void*) 
{ 
    // Check to see if we got a valid point. Early exit. 
    int idx = event.getPointIndex(); 
    if (idx == -1) 
    return; 

    // Get the point that was picked 
    event.getPoint (src_point_.x, src_point_.y, src_point_.z); 
    PCL_INFO ("Src Window: Clicked point %d with X:%f Y:%f Z:%f\n", idx, src_point_.x, src_point_.y, src_point_.z); 
    src_point_selected_ = true; 
} 

Существует более подробный пример использование его в приложении для регистрации вручную: pcl/apps/src/manual_registration/manual_registration.cpp pcl/apps/include/pcl/apps/manual_registration.h

Смежные вопросы