[pcl::VoxelGrid::applyFilter] Leaf size is too small for the input dataset. Integer indices would ov
1. 报错日志:
Python-pcl 点云下采样时报错如下:
[pcl::VoxelGrid::applyFilter] Leaf size is too small for the input dataset. Integer indices would overflow.[pcl::VoxelGrid::applyFilter] Leaf size is too small for the input dataset. Integer indices would overflow
首先得了解下采样/抽稀的原理:
点云VoxelGridFilter,称为体素格下采样,也叫抽稀。下采样是一种能显著减少点云的数据量,并保持其形状特征和空间结构信息与原始点云基本没差别的算法。
其核心是: 将点云分割成一个个微小的立方体,落在立方体内的所有点用一个重心点来最终表示,对所有的小立方体处理后得到最终的点云结果。
- 取重心点比所有点取平均值的算法稍慢,但是其结果更准确;
下采样设置的voxelGridFilter.set_leaf_size(rate,rate,rate) 值越大,最后保留的点云越少。
2. 报错原因:
虽然用的是python-pcl的api调用下采样算法,实质上调用的仍然是C++的VoxelGridFilter算法。划分的立方体格子的个数index是int32位,由于输入的点云的x,y,z跨度太大,导致划分的立方体个数超出了int32的最大大小,因此报错。
故需要对原始点云进行一点小小的操作。
3. 解决:
- 下采样前输入点云数据的 x,y,z分别减去各自的偏移量;下采样结果返回之后再分别加上其偏移量;
- 对点云进行分组处理,比如每100万点进行一次下采样,之后结果合并;
完美解决;
import pcl
import math
import time
from laspy.file import File
import numpy as np# 初始文件路径 输出文件路径 抽稀参数(单位m)
def cx(filePath, outputPath, rate):end1 = time.time()f = File(filePath, mode='r')total = len(f.points)print('points: ', total)# 获取偏移量offset = f.header.offsetx0 = offset[0]y0 = offset[1]z0 = offset[2]inFile = np.vstack((f.x - x0, f.y - y0, f.z - z0, f.intensity)).transpose()sp = math.ceil(len(inFile) / 1000000)cloud = pcl.PointCloud_PointXYZI()m2 = []for i in range(0, sp):end = (i + 1) * 1000000start = i * 1000000clPoints = inFile[start:end]cloud.from_array(np.array(clPoints, dtype=np.float32))# 抽稀sor = cloud.make_voxel_grid_filter()sor.set_leaf_size(rate, rate, rate)cloud_filtered = sor.filter()for i in range(0, cloud_filtered.size):m2.append((cloud_filtered[i][0] + x0, cloud_filtered[i][1] + y0, cloud_filtered[i][2] + z0, cloud_filtered[i][3]))x = [k[0] for k in m2]y = [k[1] for k in m2]z = [k[2] for k in m2]c = [k[3] for k in m2]print('【outputPath】', outputPath)cxlen = len(x)outFile = File(outputPath, mode='w', header=f.header)outFile.x = np.array(x)outFile.y = np.array(y)outFile.z = np.array(z)outFile.intensity = np.array(c)outFile.header.set_pointrecordscount(cxlen)outFile.close()print('cx ' + str(rate) + ' success...')print('total: ', total, 'cx: ', cxlen)print('percent: {:.2%}'.format(cxlen / total))end2 = time.time()print("cx 耗时:%.2f秒" % (end2 - end1))return cxlendef main():cx('D:/project/las/1001140020191217.las','D:/project/las/1001140020191217_cx.las', 0.03)if __name__ == "__main__":main()
总结
以上是生活随笔为你收集整理的[pcl::VoxelGrid::applyFilter] Leaf size is too small for the input dataset. Integer indices would ov的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: 使用Python,OpenCV加载图像并
- 下一篇: elasticsearch 索引 red