前兩天做了乙個點雲降取樣的專案,用pcl自帶的降取樣方法出來的結果不是很理想,於是就自己寫了乙個。為了使**執行效率高點就採用了基於點雲索引的方式。
本文使用的方法為:首先,計算點雲群的bounding box;然後,根據一定的解析度將空間點雲體素化,並記錄下每個體素所包含點雲的索引(體素化的實質就是給點雲賦予體素標籤);最後,遍歷體素,根據每個體素內點雲的索引取點雲座標,計算每個體素重心的座標,保留體素內距離重心最近的點。從而實現降取樣。
經過以上操作獲取的點雲密度相對較為均勻。
1、點雲索引計算公式(即計算每個點雲屬於哪個體素)
2、重心座標計算公式
//二、計算相同標籤點雲的重心座標,並求出距離重心最近的點雲,儲存該點雲至filter_cloud
//每個體素中點雲的個數有三種:0,1,>1
for(size_t i =
0; i < voxel_number;
++i)
else
else
//體素中點雲個數大於1
int pt_number = all_label[i]
.size()
;double center_x = sum_x / pt_number;
double center_y = sum_y / pt_number;
double center_z = sum_z / pt_number;
//尋找最近點
//計算體素中每個點與重心的距離
std::vector distance;
for(size_t k =
0; k < all_label[i]
.size()
;++k)
//記錄最近點的索引
auto min_dis = std::
min_element
(std::
begin
(distance)
, std::
end(distance));
int min_dis_index = std::
distance
(std::
begin
(distance)
,min_dis)
;int pt_index = all_label[i]
[min_dis_index]
;//儲存最近點
pcl::pointxyzrgb pt;
pt.x = in_cloud-
>points[pt_index]
.x; pt.y = in_cloud-
>points[pt_index]
.y; pt.z = in_cloud-
>points[pt_index]
.z; pt.r = in_cloud-
>points[pt_index]
.r; pt.g = in_cloud-
>points[pt_index]
.g; pt.b = in_cloud-
>points[pt_index]
.b; filtered_cloud-
>points.
push_back
(pt);}
}}all_label.
clear()
;}void
las2las
(std::string fname)
//自製取樣
pcl::pointcloud<:pointxyzrgb>
::ptr filteredcloud
(new pcl::pointcloud<:pointxyzrgb>);
//以0.1m為解析度進行體素化->尋找每個體素中,距離體素重心最近的點雲保留下來
subsample
(in_cloud,filteredcloud)
;//寫入las檔案
fname.
replace
(fname.
find
("in"),
2,"out");
std::ofstream ofs = std::
ofstream
(fname, std::ios::out | std::ios::binary)
;//設定檔案頭、點數、格式、縮放因子、偏移量
liblas::header f_header;
f_header.
setversionmajor(1
);f_header.
setversionminor(2
);f_header.
setdataformatid
(liblas::pointformatname::epointformat3)
; f_header.
setoffset
(x_setoff,y_setoff,z_setoff)
;//這裡注意偏移量要從讀取部分的標頭檔案獲取
f_header.
setscale
(0.001
,0.001
,0.001);
int out_p_n = filteredcloud-
>
size()
; f_header.
setpointrecordscount
(out_p_n)
; liblas::writer writer
(ofs, f_header)
; liblas::point point
(&f_header)
;//轉換為las
for(size_t i =
0; i < filteredcloud-
>
size()
;++i)
writer.
setheader
(f_header)
; ofs.
flush()
; ofs.
close()
; std::cout << fname <<
" "
<<
"finished!"
<<:endl>
in_cloud-
>
clear()
; filteredcloud-
>
clear()
;}intmain()
ifs.
close()
;//std::cout << dir.size() << std::endl;
for(size_t i =
0; i < dir.
size()
-1;++i)
return exit_success;
}
利用PCL點雲下取樣實現資料體素化
pcl pcl point cloud library 庫整合了針對大體量級別的空間點資料處理所需要的演算法和操作,降低了處理相關需求的複雜度,對快速建立點雲資料文件和渲染有著很好的作用。體素化voxelization 體素化是通過用空間均勻大小的體素網格 voxel grid 來模擬模型或者點雲的...
基於霍夫變換的點雲分割方法
基於霍夫變換的點雲平面分割方法 1 標準霍夫變換方法 2 概率霍夫變換 3 漸進概率霍夫變換 4 隨機霍夫變換 5 自適應霍夫變換 1.borrmann,d.et al.the 3d hough transform for plane detection in point clouds a revi...
點雲視覺化方法 PCLVisualizer
3d點雲視覺化可以通過rviz,cloud viewer或者pclvisualizer等方法進行視覺化,這些介紹pclvisualizer的方法。首先是載入點雲並顯示 include include int main int argc,char argv viewer addpointcloud c...