点云分割segmentation

        点云分割是根据空间、几何和纹理等特征对点云进行划分,使得同一划分区域内的点云拥有相似的特征 。点云的有效分割往往是许多应用的前提。例如,在逆向工程CAD/CAM 领域,对零件的不同扫描表面进行分割,然后才能更好地进行孔洞修复、曲面重建、特征描述和提取,进而进行基于3D内容的检索、组合重用等。在激光遥感领域,同样需要对地面、物体首先进行分类处理,然后才能进行后期地物的识别、重建 。

        总之,分割采用分而治之的思想,在点云处理中和滤波一样属于重要的基础操作,在PCL 中目前实现了进行分割的基础架构,为后期更多的扩展奠定了基础,现有实现的分割算法是鲁棒性比较好的Cluster聚类分割和RANSAC基于随机采样一致性的分割。

        PCL分割库包含多种算法,这些算法用于将点云分割为不同簇。适合处理由多个隔离区域空间组成的点云。将点云分解成其组成部分,然后可以对其进行独立处理。 可以在集群提取教程中找到理论入门,以解释集群方法的工作原理。这两个图说明了平面模型分割(左)和圆柱模型分割(右)的结果。

平面模型分割

代码实现

#include <iostream>
#include <pcl/ModelCoefficients.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/sample_consensus/method_types.h>
#include <pcl/sample_consensus/model_types.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/visualization/pcl_visualizer.h>int main(int argc, char** argv) 
{pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);/**** 生成20个无序点云,x,y为随机数,z为1.0* 将points中0、3、6、9、12、15索引位置的z值进行修改,将之作为离群值*/cloud->width = 20;cloud->height = 1;cloud->points.resize(cloud->width * cloud->height);for (std::size_t i = 0; i < cloud->points.size(); ++i) {cloud->points[i].x = 1024 * rand() / (RAND_MAX + 1.0f);cloud->points[i].y = 1024 * rand() / (RAND_MAX + 1.0f);cloud->points[i].z = 1.0;}// 设置离群点cloud->points[0].z = 2.0;cloud->points[3].z = -2.0;cloud->points[6].z = 4.0;cloud->points[9].z = 3.0;cloud->points[12].z = -3.0;cloud->points[15].z = -4.0;std::cerr << "Point cloud data: " << cloud->points.size() << " points" << std::endl;for (std::size_t i = 0; i < cloud->points.size(); ++i)std::cerr << "    " << cloud->points[i].x << " "<< cloud->points[i].y << " "<< cloud->points[i].z << std::endl;/*** 创建分割时所需要的模型系数对象 coefficients 及存储内点的点索引集合对象 inliers .* 这也是我们指定“阈值距离DistanceThreshold”的地方,该距离阈值确定点必须与模型有多远才能被视为离群点。* 这里距离阔值是 0.01m ,即只要点到 z=1 平面距离小于该阈值的点都作为内部点看待,而大于该阈值的则看做离群点。* 我们将使用RANSAC方法(`pcl::SAC_RANSAC`)作为可靠的估计器。因为RANSAC比较简单(其他强大的估算工具也以此为基础,并添加了其他更复杂的概念)。*/pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients);pcl::PointIndices::Ptr inliers(new pcl::PointIndices);// 创建分割对象pcl::SACSegmentation<pcl::PointXYZ> seg;// 可选配置:是否优化模型系数seg.setOptimizeCoefficients(true);// 必选配置:设置分割的模型类型、分割算法、距离阈值、输入点云seg.setModelType(pcl::SACMODEL_PLANE);seg.setMethodType(pcl::SAC_RANSAC);seg.setDistanceThreshold(0.01);seg.setInputCloud(cloud);// 执行分割操作,并存储分割结果保存到点集合 inliers 及存储平面模型系数 coefficientsseg.segment(*inliers, *coefficients);if (inliers->indices.size() == 0) {PCL_ERROR("Could not estimate a planar model for the given dataset.");return (-1);}// 此段代码用来打印出估算的平面模型的参数(以 ax+by+ca+d=0 形式),详见RANSAC采样一致性算法的SACMODEL_PLANE平面模型std::cerr << "Model coefficients: " << coefficients->values[0] << " "<< coefficients->values[1] << " "<< coefficients->values[2] << " "<< coefficients->values[3] << std::endl;std::cerr << "Model inliers: " << inliers->indices.size() << std::endl;for (std::size_t i = 0; i < inliers->indices.size(); ++i)std::cerr << inliers->indices[i] << "    " << cloud->points[inliers->indices[i]].x << " "<< cloud->points[inliers->indices[i]].y << " "<< cloud->points[inliers->indices[i]].z << std::endl;return 0;
}

输出结果

Point cloud data: 20 points1.28125 577.094 2197.938 828.125 1599.031 491.375 1358.688 917.438 -2842.562 764.5 1178.281 879.531 1727.531 525.844 4311.281 15.3438 193.5938 373.188 1150.844 169.875 31012.22 456.375 1121.938 4.78125 19.125 386.938 -3544.406 584.875 1616.188 621.719 1170.219 678.938 -4461.594 360.562 158.4062 622.25 1802.094 821.844 1532.344 309.188 1
Model coefficients: 0 0 1 -1
Model inliers: 14
1    197.938 828.125 1
2    599.031 491.375 1
4    842.562 764.5 1
5    178.281 879.531 1
7    311.281 15.3438 1
8    93.5938 373.188 1
10    1012.22 456.375 1
11    121.938 4.78125 1
13    544.406 584.875 1
14    616.188 621.719 1
16    461.594 360.562 1
17    58.4062 622.25 1
18    802.094 821.844 1
19    532.344 309.188 1

圆柱体模型分割

        本节举例说明了如何采用随机采样一致性估计从带有噪声的点云中提取一个圆柱体模型,整个程序处理流程如下 :

  1. 过滤掉远于 1. 5 m 的数据点
  2. 估计每个点的表面法线
  3. 分割出平面模型 (数据集中的桌面)并保存到磁盘中。
  4. 分割圆出柱体模型(数据集中的杯子)并保存到磁盘中。

注:由于数据中包含噪声,圆柱体模型并不十分严格 。

 代码实现

#include <pcl/ModelCoefficients.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/filters/passthrough.h>
#include <pcl/features/normal_3d.h>
#include <pcl/sample_consensus/method_types.h>
#include <pcl/sample_consensus/model_types.h>
#include <pcl/segmentation/sac_segmentation.h>typedef pcl::PointXYZ PointT;int main(int argc, char** argv) {// 需要的所有对象pcl::PCDReader reader;                          // PCD文件读取对象pcl::PassThrough<PointT> pass;                  // 直通滤波器pcl::NormalEstimation<PointT, pcl::Normal> ne;  // 法线估算对象pcl::SACSegmentationFromNormals<PointT, pcl::Normal> seg;   // 分割器pcl::PCDWriter writer;                                      // PCD文件写出对象pcl::ExtractIndices<PointT> extract;                        // 点提取对象pcl::ExtractIndices<pcl::Normal> extract_normals;           // 法线提取对象pcl::search::KdTree<PointT>::Ptr tree(new pcl::search::KdTree<PointT>());// 数据pcl::PointCloud<PointT>::Ptr cloud(new pcl::PointCloud<PointT>);pcl::PointCloud<PointT>::Ptr cloud_filtered(new pcl::PointCloud<PointT>);pcl::PointCloud<pcl::Normal>::Ptr cloud_normals(new pcl::PointCloud<pcl::Normal>);pcl::PointCloud<PointT>::Ptr cloud_filtered2(new pcl::PointCloud<PointT>);pcl::PointCloud<pcl::Normal>::Ptr cloud_normals2(new pcl::PointCloud<pcl::Normal>);pcl::ModelCoefficients::Ptr coefficients_plane(new pcl::ModelCoefficients), coefficients_cylinder(new pcl::ModelCoefficients);pcl::PointIndices::Ptr inliers_plane(new pcl::PointIndices), inliers_cylinder(new pcl::PointIndices);// 读取点云数据reader.read("G:/vsdata/PCLlearn/PCDdata/table_scene_mug_stereo_textured.pcd", *cloud);std::cerr << "PointCloud has: " << cloud->points.size() << " data points." << std::endl;// 构建一个直通过滤器以删除虚假的NaNspass.setInputCloud(cloud);pass.setFilterFieldName("z");pass.setFilterLimits(0, 1.5);pass.filter(*cloud_filtered);std::cerr << "PointCloud after filtering has: " << cloud_filtered->points.size() << " data points." << std::endl;// 估计点法线ne.setSearchMethod(tree);ne.setInputCloud(cloud_filtered);ne.setKSearch(50);ne.compute(*cloud_normals);// 为平面模型创建分割对象并设置所有参数seg.setOptimizeCoefficients(true);seg.setModelType(pcl::SACMODEL_NORMAL_PLANE);seg.setNormalDistanceWeight(0.1);seg.setMethodType(pcl::SAC_RANSAC);seg.setMaxIterations(100);seg.setDistanceThreshold(0.03);seg.setInputCloud(cloud_filtered);seg.setInputNormals(cloud_normals);// 获得平面内点和系数seg.segment(*inliers_plane, *coefficients_plane);std::cerr << "Plane coefficients: " << *coefficients_plane << std::endl;// 从输入云中提取平面内联extract.setInputCloud(cloud_filtered);extract.setIndices(inliers_plane);extract.setNegative(false);// 将平面点云保存pcl::PointCloud<PointT>::Ptr cloud_plane(new pcl::PointCloud<PointT>());extract.filter(*cloud_plane);std::cerr << "PointCloud representing the planar component: " << cloud_plane->points.size() << " data points."<< std::endl;writer.write("table_scene_mug_stereo_textured_plane.pcd", *cloud_plane, false);// 移除平面inliers, 提取其余部分extract.setNegative(true);extract.filter(*cloud_filtered2);extract_normals.setNegative(true);extract_normals.setInputCloud(cloud_normals);extract_normals.setIndices(inliers_plane);extract_normals.filter(*cloud_normals2);// 设置圆柱体分割对象参数seg.setOptimizeCoefficients(true);seg.setModelType(pcl::SACMODEL_CYLINDER);   // 设置分割模型为圆柱体seg.setMethodType(pcl::SAC_RANSAC);         // 设置采用RANSAC算法进行参数估计seg.setNormalDistanceWeight(0.1);           // 设置表面法线权重系数seg.setMaxIterations(10000);                // 设置最大迭代次数10000seg.setDistanceThreshold(0.05);             // 设置内点到模型的最大距离 0.05mseg.setRadiusLimits(0, 0.1);                // 设置圆柱体的半径范围0 -> 0.1mseg.setInputCloud(cloud_filtered2);seg.setInputNormals(cloud_normals2);// 获取cylinder inliersseg.segment(*inliers_cylinder, *coefficients_cylinder);std::cerr << "Cylinder coefficients: " << *coefficients_cylinder << std::endl;// 将cylinder inliers保存extract.setInputCloud(cloud_filtered2);extract.setIndices(inliers_cylinder);extract.setNegative(false);pcl::PointCloud<PointT>::Ptr cloud_cylinder(new pcl::PointCloud<PointT>());extract.filter(*cloud_cylinder);if (cloud_cylinder->points.empty())std::cerr << "Can't find the cylindrical component." << std::endl;else {std::cerr << "PointCloud representing the cylindrical component: " << cloud_cylinder->points.size()<< " data points." << std::endl;writer.write("table_scene_mug_stereo_textured_cylinder.pcd", *cloud_cylinder, false);}return (0);
}

输出结果

PointCloud has: 307200 data points.
PointCloud after filtering has: 139897 data points.
Plane coefficients: header:
seq: 0 stamp: 0 frame_id:
values[]values[0]:   0.016223values[1]:   -0.83761values[2]:   -0.546028values[3]:   0.528923PointCloud representing the planar component: 116054 data points.
Cylinder coefficients: header:
seq: 0 stamp: 0 frame_id:
values[]values[0]:   0.0519707values[1]:   0.172656values[2]:   0.834861values[3]:   0.0229013values[4]:   -0.836744values[5]:   -0.547116values[6]:   0.0387646PointCloud representing the cylindrical component: 11479 data points.

欧式聚类提取

        基于欧式距离的分割和基于区域生长的分割本质上都是用区分邻里关系远近来完成的。由于点云数据提供了更高维度的数据,故有很多信息可以提取获得。欧几里得算法使用邻居之间距离作为判定标准,而区域生长算法则利用了法线,曲率,颜色等信息来判断点云是否应该聚成一类。

欧几里德算法

具体的实现方法大致是:

  1. 找到空间中某点p10,有kdTree找到离他最近的n个点,判断这n个点到p的距离。将距离小于阈值r的点p12,p13,p14....放在类Q里
  2. 在 Q\p10 里找到一点p12,重复1
  3. 在 Q\p10,p12 找到一点,重复1,找到p22,p23,p24....全部放进Q里
  4. 当 Q 再也不能有新点加入了,则完成搜索了

        因为点云总是连成片的,很少有什么东西会浮在空中来区分。但是如果结合此算法可以应用很多东西。比如

  1. 半径滤波删除离群点
  2. 采样一致找到桌面或者除去滤波

        当然,一旦桌面被剔除,桌上的物体就自然成了一个个的浮空点云团。就能够直接用欧几里德算法进行分割了,这样就可以提取出我们想要识别的东西。

 代码实现

#include <pcl/ModelCoefficients.h>
#include <pcl/point_types.h>
#include <pcl/ModelCoefficients.h>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/features/normal_3d.h>
#include <pcl/kdtree/kdtree.h>
#include <pcl/sample_consensus/method_types.h>
#include <pcl/sample_consensus/model_types.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/segmentation/extract_clusters.h>
#include <pcl/visualization/pcl_visualizer.h>int main(int argc, char** argv)
{pcl::PCDReader reader;pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>), cloud_f(new pcl::PointCloud<pcl::PointXYZ>);reader.read("G:/vsdata/PCLlearn/PCDdata/table_scene_lms400.pcd", *cloud);std::cout << "PointCloud before filtering has: " << cloud->points.size() << " data points." << std::endl; //*// 执行降采样滤波,叶子大小1cmpcl::VoxelGrid<pcl::PointXYZ> vg;pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);vg.setInputCloud(cloud);vg.setLeafSize(0.01f, 0.01f, 0.01f);vg.filter(*cloud_filtered);std::cout << "PointCloud after filtering has: " << cloud_filtered->points.size() << " data points."<< std::endl; //*// 创建平面模型分割器并初始化参数pcl::SACSegmentation<pcl::PointXYZ> seg;pcl::PointIndices::Ptr inliers(new pcl::PointIndices);pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients);pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_plane(new pcl::PointCloud<pcl::PointXYZ>());pcl::PCDWriter writer;seg.setOptimizeCoefficients(true);seg.setModelType(pcl::SACMODEL_PLANE);seg.setMethodType(pcl::SAC_RANSAC);seg.setMaxIterations(100);seg.setDistanceThreshold(0.02);int i = 0, nr_points = (int)cloud_filtered->points.size();while (cloud_filtered->points.size() > 0.3 * nr_points) {// 移除剩余点云中最大的平面seg.setInputCloud(cloud_filtered);// 执行分割,将分割出来的平面点云索引保存到inliers中seg.segment(*inliers, *coefficients);if (inliers->indices.size() == 0) {std::cout << "Could not estimate a planar model for the given dataset." << std::endl;break;}// 从输入点云中取出平面内点pcl::ExtractIndices<pcl::PointXYZ> extract;extract.setInputCloud(cloud_filtered);extract.setIndices(inliers);extract.setNegative(false);// 得到与平面相关的点cloud_planeextract.filter(*cloud_plane);std::cout << "PointCloud representing the planar component: " << cloud_plane->points.size() << " data points."<< std::endl;// 从点云中剔除这些平面内点,提取出剩下的点保存到cloud_f中,并重新赋值给cloud_filtered。extract.setNegative(true);extract.filter(*cloud_f);*cloud_filtered = *cloud_f;}// 为提取算法的搜索方法创建一个KdTree对象pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>);tree->setInputCloud(cloud_filtered);/*** 在这里,我们创建一个PointIndices的vector,该vector在vector <int>中包含实际的索引信息。* 每个检测到的簇的索引都保存在这里-请注意,cluster_indices是一个vector,包含多个检测到的簇的PointIndices的实例。* 因此,cluster_indices[0]包含我们点云中第一个 cluster(簇)的所有索引。** 从点云中提取簇(集群),并将点云索引保存在 cluster_indices 中。*/std::vector<pcl::PointIndices> cluster_indices;pcl::EuclideanClusterExtraction<pcl::PointXYZ> ec;//因为点云是PointXYZ类型的,所以这里用PointXYZ创建一个欧氏聚类对象,并设置提取的参数和变量ec.setClusterTolerance(0.02); // 设置一个合适的聚类搜索半径 ClusterTolerance,如果搜索半径取一个非常小的值,那么一个实际独立的对象就会被分割为多个聚类;如果将值设置得太高,那么多个对象就会被分割为一个聚类,所以需要进行测试找出最合适的ClusterToleranceec.setMinClusterSize(100);    // 每个簇(集群)的最小大小ec.setMaxClusterSize(25000);  // 每个簇(集群)的最大大小ec.setSearchMethod(tree);     // 设置点云搜索算法ec.setInputCloud(cloud_filtered);   // 设置输入点云ec.extract(cluster_indices);        // 设置提取到的簇,将每个簇以索引的形式保存到cluster_indices;pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));// 为了从点云索引向量中分割出每个簇,必须迭代访问点云索引,int j = 0;for (std::vector<pcl::PointIndices>::const_iterator it = cluster_indices.begin();it != cluster_indices.end(); ++it) {// 每次创建一个新的点云数据集,并且将所有当前簇的点写入到点云数据集中。pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_cluster(new pcl::PointCloud<pcl::PointXYZ>);const std::vector<int>& indices = it->indices;for (std::vector<int>::const_iterator pit = indices.begin(); pit != indices.end(); ++pit)cloud_cluster->points.push_back(cloud_filtered->points[*pit]);cloud_cluster->width = cloud_cluster->points.size();cloud_cluster->height = 1;cloud_cluster->is_dense = true;std::cout << "PointCloud representing the Cluster: " << cloud_cluster->points.size() << " data points."<< std::endl;/*std::stringstream ss;ss << "cloud_cluster_" << j << ".pcd";writer.write<pcl::PointXYZ>(ss.str(), *cloud_cluster, false); //*/std::stringstream ss;ss << "cloud_cluster_" << j;// Generate a random (bright) colorpcl::visualization::PointCloudColorHandlerRandom<pcl::PointXYZ> single_color(cloud_cluster);viewer->addPointCloud<pcl::PointXYZ>(cloud_cluster, single_color, ss.str());viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, ss.str());j++;}std::cout << "cloud size: " << cluster_indices.size() << std::endl;viewer->addCoordinateSystem(0.5);while (!viewer->wasStopped()) {viewer->spinOnce();}return (0);
}

输出结果

PointCloud before filtering has: 460400 data points.
PointCloud after filtering has: 41049 data points.
PointCloud representing the planar component: 20536 data points.
PointCloud representing the planar component: 12442 data points.
PointCloud representing the Cluster: 4857 data points.
PointCloud representing the Cluster: 1386 data points.
PointCloud representing the Cluster: 321 data points.
PointCloud representing the Cluster: 291 data points.
PointCloud representing the Cluster: 123 data points.
cloud size: 5

实现效果

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/152515.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Go 并发编程

并发编程 1.1 并发与并⾏ 并⾏与并发是两个不同的概念&#xff0c;普通解释&#xff1a; 并发&#xff1a;交替做不同事情的能⼒并⾏&#xff1a;同时做不同事情的能⼒ 如果站在程序员的⻆度去解释是这样的&#xff1a; 并发&#xff1a;不同的代码块交替执⾏并⾏&#xf…

蓝牙技术|Matter或能改变中国智能家居市场,蓝牙技术将得到进一步应用

近年来&#xff0c;智能家居开放协议标准Matter&#xff08;目前版本 1.1&#xff09;由连接标准联盟发布&#xff0c;该联盟是一个由数百家公司组成的全球性机构&#xff0c;旨在提供与物联网 (IoT) 相关的标准。例如&#xff0c;Matter 用于允许 Amazon Alexa、Apple Home、G…

宝塔面板二次元透明主题美化模板

看惯了宝塔面板默认风格模板&#xff0c;我们可以试试自己美化修改&#xff0c;我的站长站知道一款非常漂亮的宝塔面板二次元透明主题美化模板&#xff0c;美不美大家看下图&#xff0c;分享给大家。 下载&#xff1a;飞猫盘&#xff5c;文件加速传输工具&#xff5c;云盘&…

学习css 伪类:has

学习抖音&#xff1a; 渡一前端提薪课 首先我们看下:has(selector)是什么 匹配包含&#xff08;相对于 selector 的 :scope&#xff09;指定选择器的元素。可以认为 selector 的前面有一个看不见的 :scope 伪类。它的强大之处是&#xff0c;可以实现父选择器和前面兄弟选择器…

R语言实现竞争风险模型(1)

#竞争风险模型 tmp <- data.frame(gene tiaoxuan[,5:6],OS.Time Train[,"Survival_months"], OS Train[,"CSS"],stringsAsFactors F) colnames(tmp) #方法1&#xff1a;riskregression library(riskRegression) fgr1<-FGR(Hist(OS.Time,OS)~gen…

【audio】alsa pcm音频路径

文章目录 AML方案音频路径分析dump alsa pcm各个音频路径的原始音频流数据 AML方案音频路径分析 一个Audio Patch用来表示一个或多个source端到一个或多个sink端。这个是从代码的注释翻译来的&#xff0c;大家可以把它比作大坝&#xff0c;可以有好几个入水口和出水口&#xf…

vue3+elementui实现表格样式可配置

后端接口传回的数据格式如下图 需要依靠后端传回的数据控制表格样式 实现代码 <!-- 可视化配置-表格 --> <template><div class"tabulation_main" ref"myDiv"><!-- 尝试过在mounted中使用this.$refs.myDiv.offsetHeight,获取父元素…

Windows安装Docker并创建Ubuntu环境及运行神经网络模型

目录 前言在Windows上安装Docker在Docker上创建Ubuntu镜像并运行容器创建Ubuntu镜像配置容器&#xff0c;使其可以在宿主机上显示GUI 创建容器并运行神经网络模型创建容器随便找一个神经网络模型试试 总结 前言 学生党一般用个人电脑玩神经网络&#xff0c;估计很少有自己的服…

JS-前端在dom中预览pdf等文件

1、将pdf等文件显示到dom元素中预览 pdf文件可以是blob、url、file类型等只要使用URL.createObjectURL(file)全部转为URL即可使用无需借助任何插件&#xff0c;只需要使用<object></object>标签即可实现 1.1、html <template><div class"home"…

vc课堂发票

在这个页面 在控制台中执行&#xff1a; // 获取需要存储的元素值 var 销货单位名称 document.querySelector("body > section > div.table_middle > table > tbody > tr:nth-child(5) >td:nth-child(2) > ul > li:nth-child(1) > span"…

基于Springboot实现影视影院订票选座管理系统【项目源码+论文说明】

基于Springboot实现影视影院订票选座管理系统演示 摘要 本论文主要论述了如何使用JAVA语言开发一个影城管理系统 &#xff0c;本系统将严格按照软件开发流程进行各个阶段的工作&#xff0c;采用B/S架构&#xff0c;面向对象编程思想进行项目开发。在引言中&#xff0c;作者将论…

k8s-8 ingress-nginx

nodeport 默认端口 nodeport默认端口是30000-32767&#xff0c;超出会报错 添加如下参数&#xff0c;端口范围可以自定义 externalname ingress-nginx 通过一个外部的vip 地址 访问到集群内的多个service 一种全局的、为了代理不同后端 Service 而设置的负载均衡服务&…

掌动智能:性能压力测试的重要性

采用性能压力测试可以帮助企业预估系统容量、提升用户体验以及降低风险和成本。在软件开发过程中&#xff0c;将性能压力测试纳入测试策略的重要一环&#xff0c;将为企业的成功和用户满意度打下坚实的基础。 性能压力测试的重要性&#xff1a; 一、发现性能瓶颈 性能压力测试能…

FPGA实现HDMI输入转SDI视频输出,提供4套工程源码和技术支持

目录 1、前言免责声明 2、我目前已有的SDI编解码方案3、设计思路框架核模块解析设计框图IT6802解码芯片配置及采集ADV7611解码芯片配置及采集silicon9011解码芯片配置及采集纯verilog的HDMI 解码模块RGB888转YUV422SPMTE编码SDI模式图像缓存SPMTE SDIGTXGV8500 4、vivado工程1-…

排序算法——希尔排序

一、介绍: 希尔排序是一种可以减少插入排序中数据比较次数的排序算法&#xff0c;加速算法的进行&#xff0c;排序的原则是将数据区分为特定步长的小区块&#xff0c;然后以插入排序算法对小区块内部进行排序&#xff0c;经历过一轮排序则减少步长&#xff0c;直到所有数据都排…

超简单的视频截取方法,迅速提取所需片段!

“视频可以截取吗&#xff1f;用相机拍摄了一段视频&#xff0c;但是中途相机发生了故障&#xff0c;录进去了很多不需要的片段&#xff0c;现在想截取一部分视频出来&#xff0c;但是不知道方法&#xff0c;想问问广大的网友&#xff0c;知不知道视频截取的方法。” 无论是工…

国内就能使用的chatgpt网页版,包含AIGC应用工具

Chatgpt的出现在多个领域带来了重要的影响。它能够显著提高我们的工作效率&#xff0c;无论是编写文案代码还是回答常见问题&#xff0c;都能在短时间内完成任务。通过Chatgpt&#xff0c;我们能够迅速获取所需答案。随着人工智能技术的不断发展&#xff0c;相信在未来AI能够带…

交通物流模型 | MDRGCN:用于多模式交通客流预测的深度学习模型

城市交通拥堵是造成交通事故的重要原因,也是城市发展的主要障碍。通过学习历史交通流数据,我们可以预测未来一些区域的交通流,这对城市道路规划、交通管理、交通控制等都有重要意义。然而,由于交通网络拓扑结构的复杂性和影响交通流的因素的多样性,交通模式往往是复杂多变…

Linux系统中实现便捷运维管理和远程访问的1Panel部署方法

文章目录 前言1. Linux 安装1Panel2. 安装cpolar内网穿透3. 配置1Panel公网访问地址4. 公网远程访问1Panel管理界面5. 固定1Panel公网地址 前言 1Panel 是一个现代化、开源的 Linux 服务器运维管理面板。高效管理,通过 Web 端轻松管理 Linux 服务器&#xff0c;包括主机监控、…

利用KerasCV YOLOv8轻松实现目标精确检测

本文中将实现基于KerasCV YOLOv8的交通灯信号检测,并附录完整代码。。 自从You Only Look Once(简称 YOLO)的诞生以来,目标检测问题主要通过深度学习来解决。大多数深度学习架构通过巧妙地将目标检测问题构建为多个小分类问题和回归问题的组合来实现。具体而言,它是通过在…