[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,稱為體素格下采樣,也叫抽稀。下采樣是一種能顯著減少點云的數(shù)據(jù)量,并保持其形狀特征和空間結構信息與原始點云基本沒差別的算法。
其核心是: 將點云分割成一個個微小的立方體,落在立方體內的所有點用一個重心點來最終表示,對所有的小立方體處理后得到最終的點云結果。
- 取重心點比所有點取平均值的算法稍慢,但是其結果更準確;
下采樣設置的voxelGridFilter.set_leaf_size(rate,rate,rate) 值越大,最后保留的點云越少。
2. 報錯原因:
雖然用的是python-pcl的api調用下采樣算法,實質上調用的仍然是C++的VoxelGridFilter算法。劃分的立方體格子的個數(shù)index是int32位,由于輸入的點云的x,y,z跨度太大,導致劃分的立方體個數(shù)超出了int32的最大大小,因此報錯。
故需要對原始點云進行一點小小的操作。
3. 解決:
- 下采樣前輸入點云數(shù)據(jù)的 x,y,z分別減去各自的偏移量;下采樣結果返回之后再分別加上其偏移量;
- 對點云進行分組處理,比如每100萬點進行一次下采樣,之后結果合并;
完美解決;
import pcl
import math
import time
from laspy.file import File
import numpy as np# 初始文件路徑 輸出文件路徑 抽稀參數(shù)(單位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