PCL点云之旅08 - 两点之间距离计算

728 阅读1分钟

实现效果

image.png

实现思路

  1. 我们在选点的时候,将点注册到表格里面去。
  2. 表格里面添加一个操作按钮,每次当选中第三个点的时候,我们将所有选点的痕迹都给他清空
  3. 这样我们就实现了最多能够选择两个点,然后我们通过两个点的坐标
  4. 计算出两个点之间的距离。这里PCL官方提供了一个工具包来给我们算

代码实现

image.png

  • 选点实现
struct callback_args{
    // structure used to pass arguments to the callback function
    PointCloudT::Ptr clicked_points_3d;
    pcl::visualization::PCLVisualizer::Ptr viewer;
};
void pp_callback(const pcl::visualization::PointPickingEvent& event, void* args){
    MainWindow *p=(MainWindow *)args;
    pcl::PointXYZRGB current_point;
    event.getPoint(current_point.x, current_point.y, current_point.z);
    p->clicked_points_3d->points.push_back(current_point);
    if(p->clicked_points_3d->points.size()>2){
        // 重新开始选择
        p->resetViewer();
        p->clicked_points_3d->clear();
    }else if(p->clicked_points_3d->points.size()!=3){
        p->inittable(current_point);
    }
    for(int i=0;i<p->clicked_points_3d->points.size();i++){
        p->dis=pcl::euclideanDistance(p->clicked_points_3d->points[0],p->clicked_points_3d->points[1]);
    }
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZRGB> red(p->clicked_points_3d, 255, 0, 0);
    p->viewer->removePointCloud("clicked_points");
    p->viewer->addPointCloud(p->clicked_points_3d, red, "clicked_points");
    p->viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 10, "clicked_points");
}
void MainWindow::point_pick(){

    viewer->registerPointPickingCallback(pp_callback, this);
    pcl::PointCloud<pcl::PointXYZRGB>::Ptr clicked_points_3d_(new pcl::PointCloud<pcl::PointXYZRGB>);
    this->clicked_points_3d = clicked_points_3d_;
    ui->qvtkWidget->SetRenderWindow(viewer->getRenderWindow());
    viewer->setupInteractor(ui->qvtkWidget->GetInteractor(), ui->qvtkWidget->GetRenderWindow());
    ui->qvtkWidget->update();

}
  • 槽函数实现
void MainWindow::deletePoint(){
    std::cout<<"删除点操作"<<std::endl;
    qDebug() << "你好世界";
    QString point_x = QString::number(dis);
    QMessageBox::warning(this,"两点之间距离",point_x);
}

void MainWindow::inittable(pcl::PointXYZRGB current_point){
    std::cout<<current_point.x<<current_point.y<<current_point.z<<std::endl;
    int rowCount = ui->tableWidget->rowCount();
    point_pick_num++;
    QString kill_btn_name="killbtn"+QString::number(point_pick_num);
    QString point_x = QString::number(current_point.x);
    QString point_y = QString::number(current_point.y);
    QString point_z = QString::number(current_point.z);
    int curRow = ui->tableWidget->currentRow();
    qDebug() << curRow;
    int newRow = curRow + 1;
    ui->tableWidget->insertRow(newRow);
    int colCount = ui->tableWidget->columnCount();
    for(int col=0; col<colCount; col++){
        switch(col){
            // 插入ID属性
            case 0:{ QTableWidgetItem *it = new QTableWidgetItem(point_x);ui->tableWidget->setItem(newRow, col, it);break;}
            case 1:{ QTableWidgetItem *it = new QTableWidgetItem(point_y);ui->tableWidget->setItem(newRow, col, it);break;}
            case 2:{ QTableWidgetItem *it = new QTableWidgetItem(point_z);ui->tableWidget->setItem(newRow, col, it);break;}
            case 3:{
                QPushButton *killBtn=new QPushButton("距离");
                killBtn->setObjectName(kill_btn_name);
                ui->tableWidget->setCellWidget(newRow,col,killBtn);
                connect(killBtn,SIGNAL(clicked()),this,SLOT(deletePoint()));
                break;
            }
        }


    }
}