直线生成以及pcl直线拟合

article/2025/11/8 4:56:19

目录

  • 写在前面
  • code
    • compile&run
  • result
  • 参考

写在前面

1、本文内容
pcl直线拟合,生成带噪声的直线并进行直线拟合的demo

2、平台
windows, pcl1.10.0
3、转载请注明出处:
https://blog.csdn.net/qq_41102371/article/details/127147223

code

line_seg.cpp

#include <pcl/io/pcd_io.h>
#include <pcl/io/ply_io.h>
#include <pcl/sample_consensus/ransac.h>
#include <pcl/sample_consensus/sac_model_line.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/segmentation/sac_segmentation.h>using namespace std::chrono_literals;pcl::visualization::PCLVisualizer::Ptr
simpleVis(pcl::PointCloud<pcl::PointXYZ>::ConstPtr cloud)
{// --------------------------------------------// -----Open 3D viewer and add point cloud-----// --------------------------------------------pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));viewer->setBackgroundColor(0, 0, 0);viewer->addPointCloud<pcl::PointXYZ>(cloud, "sample cloud");viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "sample cloud");// viewer->addCoordinateSystem (1.0, "global");//viewer->initCameraParameters();return (viewer);
}pcl::PointCloud<pcl::PointXYZ>::Ptr
create_line(double x0,double y0,double z0,double a,double b,double c,double point_size = 1000,double step = 0.1)
{pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_line(new pcl::PointCloud<pcl::PointXYZ>);cloud_line->width = point_size;cloud_line->height = 1;cloud_line->resize(cloud_line->width * cloud_line->height);for (std::size_t i = 0; i < cloud_line->points.size(); ++i) {cloud_line->points[i].x =x0 + a / std::pow(a * a + b * b + c * c, 0.5) * i * 0.1;cloud_line->points[i].y =y0 + b / std::pow(a * a + b * b + c * c, 0.5) * i * 0.1;cloud_line->points[i].z =z0 + c / std::pow(a * a + b * b + c * c, 0.5) * i * 0.1;}return cloud_line;
}void
fit_line(pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud, double distance_threshold)
{// fit line from a point cloudpcl::ModelCoefficients::Ptr coefficients1(new pcl::ModelCoefficients);pcl::PointIndices::Ptr inliers1(new pcl::PointIndices);pcl::SACSegmentation<pcl::PointXYZ> seg;seg.setOptimizeCoefficients(true);seg.setModelType(pcl::SACMODEL_LINE);seg.setMethodType(pcl::SAC_RANSAC);seg.setMaxIterations(1000);seg.setDistanceThreshold(distance_threshold);seg.setInputCloud(cloud);seg.segment(*inliers1, *coefficients1);// line parametersdouble x0, y0, z0, a, b, c;x0 = coefficients1->values[0];y0 = coefficients1->values[1];z0 = coefficients1->values[2];a = coefficients1->values[3];b = coefficients1->values[4];c = coefficients1->values[5];std::cout << "model parameters1:"<< "   (x - " << x0 << ") / " << a << " = (y - " << y0 << ") / " << b<< " = (z - " << z0 << ") / " << c << std::endl;// extract segmentation partpcl::PointCloud<pcl::PointXYZ>::Ptr cloud_line1(new pcl::PointCloud<pcl::PointXYZ>);pcl::ExtractIndices<pcl::PointXYZ> extract;extract.setInputCloud(cloud);extract.setIndices(inliers1);extract.setNegative(false);extract.filter(*cloud_line1);// extract remain pointcloudpcl::PointCloud<pcl::PointXYZ>::Ptr cloud_remain(new pcl::PointCloud<pcl::PointXYZ>);extract.setNegative(true);extract.filter(*cloud_remain);//显示原始点云pcl::visualization::PCLVisualizer::Ptr viewer_ori;viewer_ori = simpleVis(cloud);while (!viewer_ori->wasStopped()) {viewer_ori->spinOnce(100);std::this_thread::sleep_for(100ms);}pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));viewer->setBackgroundColor(0, 0, 0);viewer->addPointCloud<pcl::PointXYZ>(cloud_remain, "cloud_remain");viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "cloud_remain");viewer->addPointCloud<pcl::PointXYZ>(cloud_line1, "cloud_line1");viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 5, "cloud_line1");viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 1.0, 0.5, 0.5, "cloud_line1");// auto cloud_parameter_line1 = create_line(x0, y0, z0, a, b, c);//viewer->addPointCloud<pcl::PointXYZ>(cloud_parameter_line1, "cloud_parameter_line1");//viewer->setPointCloudRenderingProperties(//    pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 5, "cloud_parameter_line1");//viewer->setPointCloudRenderingProperties(//    pcl::visualization::PCL_VISUALIZER_COLOR, 1.0, 0.5, 0.5, "cloud_parameter_line1");// viewer->addLine(*coefficients1, "line1");while (!viewer->wasStopped()) {viewer->spinOnce(100);std::this_thread::sleep_for(100ms);}}void
demo()
{// line parametersdouble x0 = -2, y0 = -2, z0 = 0, a = 1, b = 1, c = 0;auto line_pcd_create = create_line(x0, y0, z0, a, b, c);pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_noise(new pcl::PointCloud<pcl::PointXYZ>);std::size_t noise_points_size = line_pcd_create->points.size() / 10;cloud_noise->width = noise_points_size;cloud_noise->height = 1;cloud_noise->points.resize(cloud_noise->width * cloud_noise->height);// add noisefor (std::size_t i = 0; i < noise_points_size; ++i) {int random_num = line_pcd_create->points.size() * rand() / (RAND_MAX + 1.0f);cloud_noise->points[i].x =line_pcd_create->points[random_num].x + 10 * rand() / (RAND_MAX + 1.0f) - 5;cloud_noise->points[i].y =line_pcd_create->points[random_num].y + 10 * rand() / (RAND_MAX + 1.0f) - 5;cloud_noise->points[i].z =line_pcd_create->points[random_num].z + 10 * rand() / (RAND_MAX + 1.0f) - 5;}pcl::PointCloud<pcl::PointXYZ>::Ptr line_with_noise(new pcl::PointCloud<pcl::PointXYZ>);*line_with_noise = *cloud_noise + *line_pcd_create;//pcl::visualization::PCLVisualizer::Ptr viewer;//viewer = simpleVis(line_with_noise);//while (!viewer->wasStopped()) {//  viewer->spinOnce(100);//  std::this_thread::sleep_for(100ms);//}fit_line(line_with_noise, 1);
}int
main(int argc, char* argv[])
{if (argc < 3) {std::cout << "please input parametars:\nfilepath\ndistance_threshold" << std::endl;demo();return -1;}std::string file_path = argv[1];double distance_threshold = atof(argv[2]);pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);if (pcl::io::loadPLYFile(file_path, *cloud) < 0) {std::cout << "can not read file " << file_path << std::endl;return -1;}std::cout << "point size: " << cloud->points.size() << std::endl;fit_line(cloud, distance_threshold);return 0;
}

CmakeLists.txt

cmake_minimum_required(VERSION 2.8 FATAL_ERROR)project(line_fit)find_package(PCL 1.2 REQUIRED)include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})add_executable (line_seg line_seg.cpp)
target_link_libraries (line_seg ${PCL_LIBRARIES})

compile&run

cmake -DCMAKE_BUILD_TYPE=Release -DPCL_DIR="YOUR_PATH/PCL 1.10.0/cmake" -S ./ -B ./build
cmake --build ./build --config Release --target ALL_BUILD
.\build\Release\line_seg.exe

result

在这里插入图片描述

在这里插入图片描述

参考

https://blog.csdn.net/qq_39506862/article/details/124274222
https://blog.csdn.net/qq_36686437/article/details/114171317
https://blog.csdn.net/qq_41102371/article/details/121482141
https://pcl.readthedocs.io/projects/tutorials/en/pcl-1.11.0/random_sample_consensus.html


http://chatgpt.dhexx.cn/article/tFSEvfLZ.shtml

相关文章

opencv 直线拟合

一、话说直线拟合 霍夫直线检测容易受到线段形状与噪声的干扰而失真&#xff0c;这个时候我们需要另辟蹊径&#xff0c;通过对图像进行二值分析&#xff0c;提取骨架&#xff0c;对骨架像素点拟合生成直线&#xff0c;这种做法在一些场景下非常有效&#xff0c;而且效果还比较…

拟合算法之一 直线拟合

直线拟合 很早就想学习拟合了&#xff0c;经常听同事用到拟合&#xff0c;当时尚且一窍不通&#xff0c;必须快递加急紧追此处才是&#xff0c;也参考了网上大佬的一些宝贵经验&#xff0c;先将拟合方法总结如下&#xff1a; 最小二乘法 1.原理 2.举例实现 void fitline3(…

直线拟合问题(Python实现)

程序如下&#xff1a; import matplotlib.pyplot as plt import numpy as npx_list [466, 741, 950, 1422, 1634] y_list [7.04, 4.28, 3.40, 2.54, 2.13] # x_list [0, 1, 3, 5] # y_list [1, 2, 4, 8]l_mat11 len(x_list) l_mat12 l_mat21 sum(x for x in x_list) l_…

OpenCV直线拟合检测

点击上方“小白学视觉”&#xff0c;选择加"星标"或“置顶” 重磅干货&#xff0c;第一时间送达本文转自&#xff1a;opencv学堂 OpenCV直线拟合检测 霍夫直线检测容易受到线段形状与噪声的干扰而失真&#xff0c;这个时候我们需要另辟蹊径&#xff0c;通过对图像进行…

RANSAC 直线拟合

result&#xff1a; code&#xff1a; #include "stdafx.h". #include <opencv2\opencv.hpp> #include <iostream> #include <ctime>using namespace std; using namespace cv;//生成[0,1]之间符合均匀分布的数 double uniformRandom(void) {ret…

OpenCV——直线拟合

相比于直线检测&#xff0c;直线拟合的最大特点是将所有数据只拟合出一条直线 void fitLine( InputArray points, OutputArray line, int distType,double param, double reps, double aeps ); points&#xff1a;输入待拟合直线的2D或者3D点集。line&#xff1a;输出描述直线…

直线拟合

在进行直线拟合算法中&#xff0c;一直使用最小二乘法&#xff0c;使用时间长了&#xff0c;也比较熟练了&#xff0c;但是在最近一次使用中&#xff0c;最小二乘法在拟合垂直或者接近垂直的直线时&#xff0c;效果不好&#xff1b;斜率很大&#xff0c;使用稳定性不好。查阅《…

Android 冷启动 热启动 测试

一、应用的启动 启动方式 通常来说&#xff0c;在安卓中应用的启动方式分为两种&#xff1a;冷启动和热启动。 1、冷启动&#xff1a;当启动应用时&#xff0c;后台没有该应用的进程&#xff0c;这时系统会重新创建一个新的进程分配给该应用&#xff0c;这个启动方式就是冷启动…

Spring Boot 热启动

目的&#xff1a;修改类文件可以马上编译发布&#xff0c;提高了工作效率 步骤&#xff1a; 第一步&#xff1a; 修改pom.xml <!-- 热启动 --> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools&l…

APP冷热启动专项测试

一、冷热启动的概念 冷启动&#xff1a;当启动应用时&#xff0c;后台没有该应用的进程&#xff0c;这时系统会重新创建一个新的进程分配给该应用&#xff0c;这个启动方式就是冷启动。 热启动&#xff1a;当启动应用时&#xff0c;后台已有该应用的进程&#xff08;例&#…

嵌入式linux热启动和冷启动,使用keil判断ARM的冷启动和热启动的方法

微处理器:LPC2114 编译环境:Keil MDK V4.10 思路: 常把单片机系统的复位分为冷启动和热启动。所谓冷启动&#xff0c;也就是一般所说的上电复位&#xff0c;冷启动后片内外RAM的内容是随机的&#xff0c;通常是0x00或0xFF&#xff1b;单片机的热启动是通过外部电路给运行中的单…

Android冷启动和热启动以及冷启动优化方案

1、什么是冷启动和热启动 冷启动&#xff1a; 当启动应用时&#xff0c;后台没有该应用的进程&#xff0c;这时系统会重新创建一个新的进程分配给该应用&#xff0c;这个启动方式就是冷启动&#xff0c;也就是先实例化Application。热启动&#xff1a; 当启动应用时&#xff0…

冷启动和热启动的区别android,app冷启动和热启动的区别(详解两者定义及区别)...

介绍一下 app 冷启动和热启动方式来实现 app 秒开的效果。那么,先来看看什么叫冷启动和热启动。 冷启动:指 app 被后台杀死后,在这个状态打开 app,这种启动方式叫做冷启动。 热启动:指 app 没有被后台杀死,仍然在后台运行,通常我们再次去打开这个 app,这种启动方式叫热…

热启动和冷启动以及复位启动的小知识

热启动和冷启动的区别&#xff1a; 1、重启是热启动。开机是冷启动。 2、热启动是通过开始菜单、任务管理器或者快捷键&#xff0c;重新启动计算机&#xff0c;叫热启动。冷启动是在关机状态下按POWER启动计算机&#xff0c;叫做冷启动 。 3、热启动是在计算机已经开启的状态…

dimen属性报错

<TextViewandroid:id"id/tvQuote1"android:layout_width"fill_parent"android:layout_height"wrap_content"android:textColor"#FFFFFF"android:textSize"dimen/text_size" /> 发现问题是dimen属性出现错误 别的手机上…

解决android:padding=“@dimen/activity_vertical_margin“> 标红问题

解决android:padding“dimen/activity_vertical_margin”> 标红问题 如果有这个问题&#xff0c;可以在values中新建一个dimen.xml文件 在dimen.xml里增加如下代码&#xff1a; <?xml version"1.0" encoding"utf-8"?><resources><…

android:paddingTop=“@dimen/activity_horizontal_margin“报错(报红)解决方法

android:paddingTop"dimen/activity_horizontal_margin"报错&#xff08;报红&#xff09;解决方法 在app----->res----->values------>dimens.xml中添加如下代码&#xff1a; <dimen name“activity_horizontal_margin” / (后面还有一个尖括号)&#…

android 手机适配之values适配dimen值

android 适配屏幕的方式有很多,最方便最直接的无非就是适配values里的dimens文件值来进行适配. 张鸿洋大神已经写过一篇适配的文章,很详细 但是我在阅读的时候还是有点疑问,这个values-1920x1080到底是dp值还是手机分辨率,因为我在实际操作中发现这样一句话. 很明显可以看…

Android开发——AS插件批量解决XML中的String/Color/Dimen硬编码

1. 问题抛出 1.1 开发方面 对于日常开发中&#xff0c;每写一个"#333"&#xff0c;都要手动的在当前xml与colors.xml中来回切换&#xff0c;查看是否已经定义过&#xff0c;如果定义过则拿过来复用&#xff0c;如果没有就要新定义一个叫"#333"的资源名&a…

dimen.xml浅析

转自&#xff1a;http://blog.csdn.net/kazeik/article/details/8268721 有时候我们为了维护一个工程&#xff0c;或者想定义一个button样式&#xff0c;或textView样式&#xff0c;这些样式中包含着文字的大小&#xff0c;背景图片&#xff0c;前置图片等一些资源。而且这个…