Julia内核项目
1、处理ASCII文本文件
1.1、读取文本文件🔥
准备处理文本格式的点云文件,常见的有CSV和.xyz,xyz和csv基本一致,就先写csv的处理逻辑。
Julia的性能可以接近C/C++,当然我得写的足够规范,才能发挥出Julia的优势。处理文本格式的点云文件,可以预见,真正耗时的读取部分,我的主要目的肯定不是处理文本点云文件,工程上las/laz,e57,ply都比文本格式好。
但是,我需要准备处理文本格式的点云文件,所以还是得写。一方面能够熟悉Juia,一方面可以为后续的功能打基础。对于工程设计上,我经验很少,很多只能摸着石头过河了~😄
df = CSV.read("p1.csv", DataFrame;
select=[1,2,3], delim = ',')
# 只读取前三列
delim是函数参数,如果知道csv的分隔符,直接指定会更好,delim不指定,函数会读取前十行数据,进行推断,所以直接指定会更省一点时间。
2、函数🔥
函数实现对Z值按最小值归一化,和按高度提取切片
流程 1.对Z列数据,求出最小值,2.归一化到这个最小值 3.按Z值大小,提取前两列
function extract_slice(DF::DataFrame,limit1::Float64,limit2::Float64)
z_min = minimum(DF.Z); #julia的minimum自身优化过,性能很好
DF_1 = DF.Z .- z_min; #广播机制
mask = (limit1 .< DF_1 ) .& (DF_1 .< limit2);
DF_output = DF[mask, :] #导出切片点云
return DF_DBH_output
end
这其实不是最快的实现,但是性能足够使用了,DF_1 是DF.Z的副本,创造副本加剧开销!但是我不想破坏原Dataframe。
只得好好说到的广播机制和向量化操作,在提取切片点云时,我们需要将DF.Z 减去z_min值,这其实就是一个广播操作,在Julia中,广播操作可以通过 .- 符号实现。好处就是在大量数据面前快!
.<表示对limit1 和 DF_1 中的对应元素逐一进行 < 比较,生成一个布尔数组,其中必须指定limit1和limit2是一个标量,标量会自动和DF_1这个向量对齐。
✨其实还有其他方法实现,利用subset函数:
output = subset(DF, :Z_norm =>
ByRow(x -> limit1 < x < limit2))
💡使用Byrow()函数,将Z列中的值与limit1和limit2进行比较。x -> limit1 < x < limit2匿名函数用法。这里:Z_norm是提前归一化的Z列。
ByRow()函数很好,不用复制列,直接在ByRow()函数中使用列名,能减少内存。
3、总结
实际应用中,归一化拿出函数外边去做,里边用subset函数,能减少内存。况且调用切片点云的时候,一般都已经归一化完了。😃