基於體素化方法的點雲降取樣

2021-10-13 20:54:00 字數 3839 閱讀 9557

前兩天做了乙個點雲降取樣的專案,用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...