点云边界提取方法总结

2023-11-10

原始点云:
在这里插入图片描述

经纬线扫描法

经纬线扫描法的基本思想是:将经过坐标变换后的二维数据点集按照 x值的大小排序后存储在一个链表中,在二维平面建立点集的最小包围盒并分别计算出 x 和 y 的最大、最小值;令经线从 x 的最小值开始,取步长为dx,在 x 的取值范围内分别计算出每根经线的最大和最小 y 值,并将它们的索引值放在一个新建的链表中,扫描完整个 x 区间;同样的方法扫描纬线,最后将重复的索引值删掉。
该算法的运算速度受点云点数以及搜索分辨率影响。下面代码在点云形状近似为平面,且在xoy平面上投影面积最大时表现较好,其他情况需要修改。

#include <iostream>
#include <algorithm>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>

void BoundaryExtraction(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_boundary, int resolution)
{
	pcl::PointXYZ px_min = *std::min_element(cloud->begin(), cloud->end(), [](pcl::PointXYZ pt1, pcl::PointXYZ pt2) {return pt1.x < pt2.x; });
	pcl::PointXYZ px_max = *std::max_element(cloud->begin(), cloud->end(), [](pcl::PointXYZ pt1, pcl::PointXYZ pt2) {return pt1.x < pt2.x; });

	float delta_x = (px_max.x - px_min.x) / resolution;
	float min_y = INT_MAX, max_y = -INT_MAX;
	std::vector<int> indexs_x(2 * resolution + 2);
	std::vector<std::pair<float, float>> minmax_x(resolution + 1, { INT_MAX,-INT_MAX });
	for (size_t i = 0; i < cloud->size(); ++i)
	{
		int id = (cloud->points[i].x - px_min.x) / delta_x;
		if (cloud->points[i].y < minmax_x[id].first)
		{
			minmax_x[id].first = cloud->points[i].y;
			indexs_x[id] = i;
		}
		else if (cloud->points[i].y > minmax_x[id].second)
		{
			minmax_x[id].second = cloud->points[i].y;
			indexs_x[id + resolution + 1] = i;
		}
	}

	pcl::PointXYZ py_min = *std::min_element(cloud->begin(), cloud->end(), [](pcl::PointXYZ pt1, pcl::PointXYZ pt2) {return pt1.y < pt2.y; });
	pcl::PointXYZ py_max = *std::max_element(cloud->begin(), cloud->end(), [](pcl::PointXYZ pt1, pcl::PointXYZ pt2) {return pt1.y < pt2.y; });

	float delta_y = (py_max.y - py_min.y) / resolution;
	float min_x = INT_MAX, max_x = -INT_MAX;
	std::vector<int> indexs_y(2 * resolution + 2);
	std::vector<std::pair<float, float>> minmax_y(resolution + 1, { INT_MAX,-INT_MAX });
	for (size_t i = 0; i < cloud->size(); ++i)
	{
		int id = (cloud->points[i].y - py_min.y) / delta_y;
		if (cloud->points[i].x < minmax_y[id].first)
		{
			minmax_y[id].first = cloud->points[i].x;
			indexs_y[id] = i;
		}
		else if (cloud->points[i].x > minmax_y[id].second)
		{
			minmax_y[id].second = cloud->points[i].x;
			indexs_y[id + resolution + 1] = i;
		}
	}

	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_xboundary(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::copyPointCloud(*cloud, indexs_x, *cloud_xboundary);
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_yboundary(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::copyPointCloud(*cloud, indexs_y, *cloud_yboundary);
	*cloud_boundary = *cloud_xboundary + *cloud_yboundary;
}

int main(int argc, char* argv[])
{
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>),;
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_boundary(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::io::loadPCDFile("test.pcd", *cloud);
	
	BoundaryExtraction(cloud, cloud_boundary, 200);
	pcl::io::savePCDFile("boundary.pcd", *cloud_boundary);

	return EXIT_SUCCESS;
}

提取结果:
在这里插入图片描述

网格划分法

网格划分法分为三个步骤:(1)网格划分(2)寻找边界网格(3)提取边界线。首先建立数据点集的最小包围盒,并用给定间隔的矩形网格将其分割;然后找出边界网格,将这些边界网格按顺序连接起来形成一条由边界网格组成的“粗边界”;再对每个边界网格按照某种规则判断其内的点是否为边界点,连接初始边界,并对此边界线进一步处理使其光滑。
在这里插入图片描述
在这里插入图片描述
该算法的运算速度受点云点数以及搜索分辨率影响。下面代码在点云形状近似为平面,且在xoy平面上投影面积最大时表现较好,其他情况需要修改。

#include <iostream>
#include <vector>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/common/transforms.h>

void BoundaryExtraction( pcl::PointCloud<pcl::PointXYZ>::Ptr cloud,  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_boundary, int resolution)
{
	pcl::PointXYZ px_min = *std::min_element(cloud->begin(), cloud->end(), [](pcl::PointXYZ pt1, pcl::PointXYZ pt2) {return pt1.x < pt2.x; });
	pcl::PointXYZ px_max = *std::max_element(cloud->begin(), cloud->end(), [](pcl::PointXYZ pt1, pcl::PointXYZ pt2) {return pt1.x < pt2.x; });
	pcl::PointXYZ py_min = *std::min_element(cloud->begin(), cloud->end(), [](pcl::PointXYZ pt1, pcl::PointXYZ pt2) {return pt1.y < pt2.y; });
	pcl::PointXYZ py_max = *std::max_element(cloud->begin(), cloud->end(), [](pcl::PointXYZ pt1, pcl::PointXYZ pt2) {return pt1.y < pt2.y; });
	float x_min = px_min.x, x_max = px_max.x, y_min = py_min.y, y_max = py_max.y;

	float L = sqrt((x_max - x_min)*(y_max - y_min) / resolution);
	int x_num = (x_max - x_min) / L + 1;
	int y_num = (y_max - y_min) / L + 1;

	std::vector<std::vector< pcl::PointCloud<pcl::PointXYZ>::Ptr>> uv(x_num + 1, std::vector< pcl::PointCloud<pcl::PointXYZ>::Ptr>(y_num + 1));
	for (int i = 0; i <= x_num; ++i)
	{
		for (int j = 0; j <= y_num; ++j)
		{
			 pcl::PointCloud<pcl::PointXYZ>::Ptr ptcloud(new  pcl::PointCloud<pcl::PointXYZ>);
			 uv[i][j] = ptcloud;
		}
	}
	for (int i = 0; i < cloud->size(); ++i)
	{
		int x_id = (cloud->points[i].x - x_min) / L;
		int y_id = (cloud->points[i].y - y_min) / L;
		uv[x_id][y_id]->push_back(cloud->points[i]);
	}

	std::vector<std::vector<bool>> boundary_index(x_num + 1, std::vector<bool>(y_num + 1, false));
	for (int i = 0; i <= x_num; ++i)
	{
		if (uv[i][0]->size())
			boundary_index[i][0] = true;
		if (uv[i][y_num]->size())
			boundary_index[i][y_num] = true;
	}		
	for (int i = 0; i <= y_num; ++i)
	{
		if(uv[0][i]->size())
			boundary_index[0][i] = true;
		if (uv[x_num][i]->size())
			boundary_index[x_num][i] = true;
	}
	for (int i = 1; i < x_num - 1; ++i)
	{
		for (int j = 1; j < y_num - 1; ++j)
		{
			if (uv[i][j]->size())
			{
				if (!uv[i - 1][j - 1]->size() || !uv[i][j - 1]->size() || !uv[i + 1][j - 1]->size() || !uv[i][j - 1]->size() ||
					!uv[i + 1][j - 1]->size() || !uv[i + 1][j]->size() || !uv[i + 1][j + 1]->size() || !uv[i][j + 1]->size())
					boundary_index[i][j] = true;
			}
		}
	}

	for (int i = 0; i <= x_num; ++i)
	{
		for (int j = 0; j <= y_num; ++j)
		{
			if (boundary_index[i][j])
			{
				 pcl::PointCloud<pcl::PointXYZ>::Ptr ptcloud(new  pcl::PointCloud<pcl::PointXYZ>);
				ptcloud = uv[i][j];
				Eigen::Vector4f cloud_centroid;
				pcl::compute3DCentroid(*ptcloud, cloud_centroid);
				cloud_boundary->push_back(pcl::PointXYZ(cloud_centroid(0), cloud_centroid(1), cloud_centroid(2)));
			}
		}
	}
}

int main(int argc, char* argv[])
{
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new  pcl::PointCloud<pcl::PointXYZ>);
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_boundary(new  pcl::PointCloud<pcl::PointXYZ>);
	pcl::io::loadPCDFile("test.pcd", *cloud);
	
	BoundaryExtraction(cloud, cloud_boundary, 200*200);
	pcl::io::savePCDFile("boundary.pcd", *cloud_boundary);

	return EXIT_SUCCESS;
}

提取结果:
在这里插入图片描述

法线估计法

可参考PCL:点云数据基于法线的边界提取(从最初的法线估计理论推导到最终的边界提取)
该算法的运算速度受点云点数以及搜索半径影响。

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/features/normal_3d.h>
#include <pcl/features/boundary.h>


int main(int argc, char* argv[])
{

	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::io::loadPCDFile("test.pcd", *cloud);

	pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);
	pcl::PointCloud<pcl::Boundary> boundaries;
	pcl::BoundaryEstimation<pcl::PointXYZ, pcl::Normal, pcl::Boundary> est;
	pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());

	pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> normEst;
	normEst.setInputCloud(cloud);
	normEst.setSearchMethod(tree);
	normEst.setRadiusSearch(3);  //法向估计的半径  3
	//normEst.setKSearch(9);  //法向估计的点数
	normEst.compute(*normals);

	est.setInputCloud(cloud);
	est.setInputNormals(normals);
	est.setSearchMethod(tree);
	est.setKSearch(500);  //一般这里的数值越高,最终边界识别的精度越好
	est.compute(boundaries);

	pcl::PointCloud<pcl::PointXYZ>::Ptr boundPoints(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::PointCloud<pcl::PointXYZ> noBoundPoints;
	int countBoundaries = 0;
	for (int i = 0; i < cloud->size(); i++)
	{
		uint8_t x = (boundaries.points[i].boundary_point);
		int a = static_cast<int>(x); //该函数的功能是强制类型转换
		if (a == 1)
		{
			(*boundPoints).push_back(cloud->points[i]);
			countBoundaries++;
		}
		else
			noBoundPoints.push_back(cloud->points[i]);
	}

	pcl::io::savePCDFile("boundary.pcd", *boundPoints);

	return EXIT_SUCCESS;
}

提取结果:
在这里插入图片描述

alpha shapes算法

原理参考:alpha shapes提取平面点云边界点
该算法的运算速度受点云点数以及搜索半径影响。
手写实现:在alpha-shape计算二维点云边界–c++实现基础上精简优化

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/common/distances.h>
#include <pcl/kdtree/kdtree_flann.h>


int main()
{
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::io::loadPCDFile("test.pcd", *cloud);
	for (auto& point : *cloud)
		point.z = 0.0;

	pcl::PointCloud<pcl::PointXYZ>::Ptr boundary(new pcl::PointCloud<pcl::PointXYZ>);
	float alpha = 10.0;
	pcl::KdTreeFLANN<pcl::PointXYZ>kdtree;
	kdtree.setInputCloud(cloud);
	std::vector<int> indices;
	std::vector<float>dist;
	for (size_t i = 0; i < cloud->size(); ++i)
	{
		pcl::PointXYZ p = cloud->points[i];
		kdtree.radiusSearch(cloud->points[i], 2*alpha, indices, dist); //搜索在点云中到p点距离小于2*alpha的点
		for (size_t j = 1; j < indices.size(); ++j)
		{
			pcl::PointXYZ p1 = cloud->points[indices[j]];
			float s_2 = std::pow((p.x - p1.x), 2) + std::pow((p.y - p1.y), 2);
			float h = std::pow((alpha * alpha / s_2 - 0.25), 0.5);
			float x2 = p.x + 0.5 * (p1.x - p.x) - h * (p1.y - p.y);
			float y2 = p.y + 0.5 * (p1.y - p.y) - h * (p.x - p1.x);
			float x3 = p.x + 0.5 * (p1.x - p.x) + h * (p1.y - p.y);
			float y3 = p.y + 0.5 * (p1.y - p.y) + h * (p.x - p1.x);
			pcl::PointXYZ p2(x2, y2, 0.0);
			pcl::PointXYZ p3(x3, y3, 0.0);

			//计算邻域内除了p1之外的点到p2、p3的距离
			std::vector<bool> distp2_bool, distp3_bool;
			int count = 0;
			for (size_t k = 1; k < indices.size(); ++k)
			{
				pcl::PointXYZ p_other = cloud->points[indices[k]];
				if (k != j)
				{
					++count;
					//比较剩余的点到p2、p3距离与r的大小
					if (pcl::euclideanDistance(p_other, p2) > alpha)
						distp2_bool.push_back(true);
					if (pcl::euclideanDistance(p_other, p3) > alpha)
						distp3_bool.push_back(true);
				}
			}
			//如果邻域内所有点到p2,或者p3的距离均大于alpha,则表明p是边界点,退出循环
			if (count == distp2_bool.size() || count == distp3_bool.size())
			{
				boundary->push_back(cloud->points[i]);
				break;
			}
		}
	}

	pcl::io::savePCDFile("boundary.pcd", *boundary);

	return EXIT_SUCCESS;
}

调用api:

#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/surface/concave_hull.h>


int main(int argc, char* argv[])
{
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::io::loadPCDFile("test.pcd", *cloud);

	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_hull(new pcl::PointCloud<pcl::PointXYZ>); 
	pcl::ConcaveHull<pcl::PointXYZ> chull;
	chull.setInputCloud(cloud); //输入点云为投影后的点云
	chull.setAlpha(10); //设置aLpha值
	chull.reconstruct(*cloud_hull);
	pcl::io::savePCDFile("boundary.pcd", *cloud_hull);

	return EXIT_SUCCESS;
}

提取结果:
在这里插入图片描述

参考文献:[1]杨雪娇. 点云的边界提取及角点检测算法研究[D].哈尔滨工程大学,2010.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

点云边界提取方法总结 的相关文章

  • PCL测试程序(兔子)

    程序 include
  • 性别年龄识别器

    心情 最近比较郁闷 自己的小论文已经投了快8个月了 从去年的AAAI CVPR 到现在在审的TCSVT AAAI由于页数超限被拒 CVPR因为一个正面和2个负面评价被拒 TCSVT还前途未卜 真的很郁闷 心情不好 论文也不太想看 撸撸代码放
  • Opencv学习笔记(三)线性及非线性滤波

    大纲 1 滤波综述 2 方框滤波 3 均值滤波 4 高斯滤波 5 中值滤波 6 双边滤波 一 滤波综述 图像的滤波指的是在尽量保证图像细节特征的的情况下对图像中的噪声进行抑制 又因为图像的能量大部分集中在低频或者中频的区域 图像大部分区域是
  • 深度学习2015年文章整理(CVPR2015)

    国内外从事计算机视觉和图像处理相关领域的著名学者都以在三大顶级会议 ICCV CVPR和ECCV 上发表论文为荣 其影响力远胜于一般SCI期刊论文 这三大顶级学术会议论文也引领着未来的研究趋势 CVPR是主要的计算机视觉会议 可以把它看作是
  • CVPR2017-如何在无标签数据集上训练模型

    论文 Fine tuning Convolutional Neural Networks for Biomedical Image Analysis Actively and Incrementally 论文链接 http openacce
  • 【pytorch目标检测】创新之作:Fast R-CNN算法解读

    背景 2015年 提出了Fast RCNN算法 训练步骤实现端到端 CNN 基于VGG6 Fast R CNN是基于R CNN和SPPnets进行的改进 成果 训练速度比RCNN块9倍 测试速度快乐23倍 准确率68 4 SPPnets网络
  • Sequential Modeling Enables Scalable Learning for Large Vision Models

    目录 一 论文速读 1 1 摘要 1 2 论文概要总结 二 论文精度 2 1 论文试图解决什么问题 2 2 论文中提到的解决方案之关键是什么 2 3 论文提出的架构和损失函数是什么 2 4 用于定量评估的数据集是什么 代码有没有开源 2 5
  • 【论文】F1的单位是%还是1,mAP的单位是%还是1?答:F1的单位是1,mAP的单位是%

    文章目录 前提 1 F1的单位是 还是1 2 mAP的单位是 还是1 前提 以下回答均来自 chatgpt poe 感觉说的很正确 还参考了师兄师姐的论文的 答案应该是正确的 1 F1的单位是 还是1 F1分数的单位是 1 而不是百分比 F
  • halcon视觉缺陷检测常用的6种方法

    一 缺陷检测综述 缺陷检测是视觉需求中难度最大一类需求 主要是其稳定性和精度的保证 首先常见缺陷 凹凸 污点瑕疵 划痕 裂缝 探伤等 常用的手法有六大金刚 在halcon中的ocv和印刷检测是针对印刷行业的检测 有对应算子封装 1 blob
  • 软件测试/人工智能丨计算机视觉场景中,如何处理视频/图片数据并进行测试

    在计算机视觉中 处理视频和图片数据并进行测试是一个关键的任务 以下是一些常见的步骤和方法 处理图片数据 数据加载 使用图像处理库 例如OpenCV PIL 加载图像数据 将图像转换为模型所需的格式 通常是矩阵 预处理 标准化图像 将图像像素
  • 大语言模型:开启自然语言处理新纪元

    导言 大语言模型 如GPT 3 Generative Pre trained Transformer 3 标志着自然语言处理领域取得的一项重大突破 本文将深入研究大语言模型的基本原理 应用领域以及对未来的影响 1 简介 大语言模型是基于深度
  • 智能机器人:未来与现实的交汇

    导言 人工智能智能机器人是当今科技领域的璀璨明珠 将技术 感知和智能相结合 呈现出前所未有的发展态势 人工智能助力的智能机器人代表了科技融合的巅峰 其强大的感知 学习和决策能力正深刻改变着我们的生活 本文将深入探讨人工智能智能机器人的定义
  • 探索人工智能中的AI作画:创意、技术与未来趋势

    导言 AI作画是人工智能领域中一个备受关注的前沿应用 它将传统艺术与先进技术相结合 创造出令人惊艳的艺术品 本文将深入探讨AI作画的创意过程 技术原理以及未来可能的发展趋势 1 AI作画的创意过程 艺术风格迁移 AI作画通过学习大师的风格
  • 图像相关知识点及属性介绍

    图像常用属性指标 图像的常用属性指标有以下几个 分辨率 分辨率是指图像中可以显示的水平和垂直像素数 较高的分辨率意味着图像具有更多的细节和更高的清晰度 常用单位有像素 px 或者万像素 MP 色彩深度 色彩深度是指图像中每个像素可以表示的不
  • 2023长三角(芜湖)人工智能数字生态峰会成功召开!

    聚焦当下 共议数字时代发展 瞩目未来 共谋数字生态蓝图 12月11日 2023长三角 芜湖 人工智能数字生态峰会暨2023长三角 芜湖 人工智能视觉算法大赛颁奖典礼在芜湖宜居国际博览中心盛大召开 本次大会是由安徽省数据资源管理局 安徽省科学
  • 互操作性(Interoperability)如何影响着机器学习的发展?

    互操作性 Interoperability 也称为互用性 即两个系统之间有效沟通的能力 是机器学习未来发展中的关键因素 对于银行业 医疗和其他生活服务行业 我们期望那些用于信息交换的平台可以在我们需要时无缝沟通 我们每个人都有成千上万个数据
  • 对 pcl::StatisticalOutlierRemoval 滤波器的理解

    对 pcl StatisticalOutlierRemoval 滤波器的理解 注 以下内容基于与 GPT 4 的交流并结合个人理解整理而成 若有描述不准确或模糊之处 欢迎指正 参数配置 setMeanK int meanK 此参数设置每个点
  • 对 pcl::StatisticalOutlierRemoval 滤波器的理解

    对 pcl StatisticalOutlierRemoval 滤波器的理解 注 以下内容基于与 GPT 4 的交流并结合个人理解整理而成 若有描述不准确或模糊之处 欢迎指正 参数配置 setMeanK int meanK 此参数设置每个点
  • 图神经网络与智能化创作艺术:开启艺术的智能时代

    导言 图神经网络 GNNs 与智能化创作艺术的结合为艺术领域带来了新的可能性 本文深入研究二者的结合方向 包括各自的侧重点 当前研究动态 技术运用 实际场景 未来展望 并提供相关链接 1 图神经网络与智能化创作艺术的结合方向 1 1 图神经
  • 【图像融合】基于联合双边滤波和局部梯度能量的多模态医学图像融合研究(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码 图像 文章

随机推荐

  • Python--Email

    邮件定义 电子邮件 消息由头域 统称消息头 以及后面可选的消息体组成 根据 RFC 2822 唯一需要的消息标题只有发送日期字段和发送地址字段 即 Date 和 From MAIL FROM RCPT TO DATA 1 电子邮件系统组件和
  • Jbox2D入门学习一物理世界及最简单的物体创建

    这周末无聊 翻到舍友有本游戏开发的书 就浏览了遍 因为对游戏以前其实没接触过 可能就简单知道一边游戏绘图和逻辑以及游戏框架绘制的简单概念 这次主要是看了下游戏开发中最常用和基础的一个物理引擎 Box2D 对于这个引擎 可能说最好表现和表达出
  • Spring Boot彩色日志配置

    在spring boot中使用彩色日志 spring boot是默认支持彩色日志的 但是由于我又添加了自己的logback日志配置文件 然后就没有了彩色日志 经过一番搜索大法找到了一个完美还原spring boot的彩色日志 下面是logb
  • 华为OD机试 - 数字加减游戏(Java)

    题目描述 小明在玩一个数字加减游戏 只使用加法或者减法 将一个数字s变成数字t 每个回合 小明可以用当前的数字加上或减去一个数字 现在有两种数字可以用来加减 分别为a b a b 其中b没有使用次数限制 请问小明最少可以用多少次a 才能将数
  • 技术流

    如果让你向别人推荐十部电影 你会推荐哪十部 这是在知乎上被浏览过 2000 万的问题 一共有 5036 个回答 花 5 分钟读完这篇文章 可以帮你节省99 的找电影时间 全是知乎上最值得推荐的电影 并最后让你获取到几百万人收藏的超级电影名单
  • Spring 之 jwt,过滤器,拦截器,aop,监听器,参数校验

    Spring 之 jwt 过滤器 拦截器 aop 监听器 一 jwt编写 1 1 pom 1 2 JwtUtils 1 3 注意 1 4 用法 1 5 jwt实战 1 5 1 过滤器判断jwt 1 5 2 过滤器注入Bean 1 5 3 t
  • under-approximation & over-approximation

    Under approximation and over approximation are concepts often used in the context of formal methods a field that applies
  • IDM403解决办法之一:和百度网盘和平共处

    不知道有没有小伙伴和我一样 对百度云恨之入骨 在千兆时代 它的下载速度竟然还能再100KB左右 于是 我在网络上找了各种方法 最好用的是用IDM下载 不过有的时候 IDM也会失灵 特别是针对百度网盘里的大文件 以前300MB以上 这次我下载
  • git代码使用空格缩进

    1 idea设置缩进符为空格 Java 代码 golang 代码 2 设置提交仓库时的空格处理 否则 golang 代码为了减少文件大小 可能会把空格缩进改为制表符 设置当前仓库配置 git config core whitespace t
  • sublime text3 智能提示

    1 启动编辑器 编写代码方法 发现只有html方面的提示 并没有函数方面的提示 2 点击 preferences package control 准备插件包各项操作 3 点击下拉框中的 install package 安装插件包 4 在输入
  • 如何提高一个研发团队的“代码速度”?

    阿里妹导读 Code Velocity 代码速度 体现了一个研发团队快速响应业务需求的能力 如果做得好 代码从commit到上线可能平均只需要两三天时间 甚至连紧急发布都不怎么需要了 今天 蚂蚁金服国际事业群技术风险部研究员南门 将和大家聊
  • linux的oops界面,Linux编程时遇到Oops提示该如何排查?

    用于表示函数的调用关系 通过这段信息我们可以知道 函数的整个执行流程 知道它的函数调用关系 最后整理出来的函数执行流程如下 本文引用地址 http www eepw com cn article 201811 395128 htm 从中我们
  • 基于LiDAR的目标检测算法

    自动驾驶中 激光雷达点云如何做特征表达 基于激光雷达点云 lidar 的目标检测方法之BEV 基于激光雷达点云 lidar 的目标检测方法之camera range view 基于激光雷达点云 lidar 的目标检测方法之point wis
  • VueTouchKeyboard——一个模拟键盘

    功能需求 封装一个带有设计好的样式的输入组件 输入方式为模拟的数字键盘 键盘组件为VueTouchKeyboard 下载方式如下 npm install vue touch keyboard save image png 封装的输入组件 模
  • 素数的求解方法:

    一 朴素判断素数算法 就判断素数而言 事实上是非常简单的了 根据定义 判断一个整数n是否是素数 只需要去判断在整数区间 2 n 1 之内 是否具有某个数m 使得n m 0 代码可以这么写 int isPrime int n int i fo
  • Arduino IDE 烧录 ESP8266教程

    Arduino IDE for ESP8266教程 原出处 http www windworkshop cn p 758 ESP8266是现在性价比不错的Wifi模块 用了一块ESP8266 01之后感觉还行 用在数据采集器上表现还是不错的
  • IDEA中build path导入外包jar 包的方法

    小编今天需要在IDEA中导入外部jar包 由于在eclipse中可以在外部jar包上直接右键 build path 然后点击add to Build Path 就成功导入了 可惜IDEA并不是如此 有点小苦恼 接下来 小编就带大家操作 ID
  • 分解命令行字符串为argc和argv

    有时候需要用空格把一个命令行参数字符串分解为参数个数和参数指针 就是常见的c语言main 函数入口argc argv 这里采用strtok 函数可以很方便的做到 char strtok char str const char delim 用
  • 关于取消开机bois密码的方法

    有时在不小心设置了bois密码 导致每次开机都需要输入密码 显得十分麻烦 如何取消bois密码呢 经过查阅各种资料 有两种2情况 分别是 知道bois密码 和不知道bois密码 大部分的文章中都讲到的是忘记bois密码的方式 这边将一下 知
  • 点云边界提取方法总结

    目录 经纬线扫描法 网格划分法 法线估计法 alpha shapes算法 原始点云 经纬线扫描法 经纬线扫描法的基本思想是 将经过坐标变换后的二维数据点集按照 x值的大小排序后存储在一个链表中 在二维平面建立点集的最小包围盒并分别计算出 x