几种取整方式
首先,取整函数常见三种:round,ceil,floor
分别对应为:四舍五入取整、向上取整、向下取整。
四舍五入取整比较常见,但用于区间统计问题时,通常需要向上或者向下取整。
区间统计,一维离散数据为例,比如存在一组数组x,统计其各个区间bins的分布数量,那么是不是需要对每个数据进行这样的区间判断呢?
if x(i) > bins(j - 1) && x(i) <= bins(j)
这种方法需要对每个变量遍历同时,对区间逐一遍历直至所属区间,在运算量上比较大;本文提出一种简易方式,遍历一次被统计数即可。
体素化
直接用三维数据的体素化举例,一二维离散数据的处理类比即可。
先解释一下:
- 栅格化,是将离散二维数据规整到指定区间、指定栅格尺寸的二维数组中;
- 体素化,即将离散三维数据投影到指定区间的三维数组中。
分享一段自己写的体素化代码:
function voxelData = voxelization(centralizedPointInfo,pointsNum,Roi,blockInfo)
% 功能:对点云数据投影到三维立体空间,即体素化
% centralizedPointInfo:入参,中心化之后的点云
% pointsNum:入参,点个数
% Roi:边界,防止出界的处理
% blockInfo:立体方块的尺寸信息
% centralizedPointInfo:出参,中心化之后的数据
% center:出参,质心
blockNum_x = floor((Roi.x_max - Roi.x_min) / blockInfo.size_x);
blockNum_y = floor((Roi.y_max - Roi.y_min) / blockInfo.size_y);
blockNum_z = floor((Roi.z_max - Roi.z_min) / blockInfo.size_z);
voxelData = zeros(blockNum_z,blockNum_y,blockNum_x);
for i = 1:pointsNum
ind_x = ceil((centralizedPointInfo(i).x - Roi.x_min) / blockInfo.size_x);
ind_y = ceil((centralizedPointInfo(i).y - Roi.y_min) / blockInfo.size_y);
ind_z = ceil((centralizedPointInfo(i).z - Roi.z_min) / blockInfo.size_z);
if ind_x == 0 || ind_y == 0 || ind_z == 0
continue;
end
if ind_x < 1
ind_x = 1;
end
if ind_x > blockNum_x
ind_x = blockNum_x;
end
if ind_y < 1
ind_y = 1;
end
if ind_y > blockNum_y
ind_y = blockNum_y;
end
if ind_z < 1
ind_z = 1;
end
if ind_z > blockNum_z
ind_z = blockNum_z;
end
voxelData(ind_z,ind_y,ind_x) = voxelData(ind_z,ind_y,ind_x) + 1;
end
end
不同平台取整方式
回到向上向下取整问题,我们知道,在matlab中,数组索引从1开始;而在c语言中数组索引从0开始,而ceil代表向上取整(天花板)、floor代表向下取整(地板)。
那么对应于体素化等模块实现时,同一操作,在matlab中选择ceil向上取整,即可实现有效数据索引从1开始,在c代码中floor向下取整,即可实现有效数组从0开始。