標籤:
一.點雲顯示模組 根據PCL中國官方論壇上田博士的四篇文章http://www.pclcn.org/bbs/forum.php?mod=viewthread&tid=223&page=1&extra=#pid750,在MFC環境中搭建了基本的點雲顯示模組。這是後續所有操作的基礎。 1.需要解決的問題有: ( 1)由于闐博士在文章裡說,PCL-1.6.0-AllInOne-msvc2010-win32中提供的VTK5.8缺少關鍵檔案vtkMFCWindow.h和vktMFC.lib,所以無法實現基於MFC的PCL表單。因此需要自行下載VTK5.10,用CMake產生工程檔案;我下載的CMake版本是2.8.11.1,第一次進行配置的時候,看不到VTK_USE_MFC的選項,通過複選“Advanced”複選框找到了VTK_GUI_SUPPORT選項,勾選這個選項之後單擊“Config”按鈕,才找到了VTK_USE_MFC的選項;注意,如果不勾選VTK_USE_MFC的選項,就不能產生vtkMFC工程需要的資訊;(具體過程參考筆記《VTK安裝及源碼編譯》)。(2)編譯自己的項目時會在下面的代碼處,遇到很多編譯錯誤:std::numeric_limits<double >::max();std::max();編譯錯誤的內容是:“(”: “::”右邊的非法標記錯誤原因:函數模板max與VisualC++中的全域的宏max衝突。從網上找到的解決辦法是把“std::numeric_limits<double>::max”用小括弧括起來;(std::numeric_limits<double>::max)();(std::max)();還有另外一種解決方案是在衝突的檔案的標頭檔加上:#undef max #undef min(3)一些其他的調試問題。
2.修改點雲顯示模組田博士修改的代碼中點雲顯示類型是sensor_msgs::PointCloud2
- this->binary_blob.reset();
- binary_blob = sensor_msgs::PointCloud2::Ptr (newsensor_msgs::PointCloud2);
- // read new data
- //*.pcd檔案
- pcl::PCDReader pcd_reader;
- if (pcd_reader.read ((char*)_bstr_t(filename.c_str()),*binary_blob) != 0) //* load the file
- {
- MessageBox(_T("Couldn‘t read PCData file!"));
- return;
- }
- }
- if (binary_blob ==NULL)
- {
- MessageBox("Please load PCD file firstly!");
- return;
- }
- else
- {
- //其他控制代碼
- if (pcl::getFieldIndex(*binary_blob, "rgb") >0)
- {
- color_Handler =pcl::mfc_visualization::PointCloudColorHandlerRGBField<sensor_msgs::PointCloud2>::Ptr
- (newpcl::mfc_visualization::PointCloudColorHandlerRGBField<sensor_msgs::PointCloud2>(binary_blob));
- this->viewer->addPointCloud(binary_blob, color_Handler,sensor_origin, sensor_orientation);
- }
- else
- {
- xyz_Handler =pcl::mfc_visualization::PointCloudGeometryHandlerXYZ<sensor_msgs::PointCloud2>::Ptr
- (newpcl::mfc_visualization::PointCloudGeometryHandlerXYZ<sensor_msgs::PointCloud2>(binary_blob));
- this->viewer->addPointCloud(binary_blob, xyz_Handler,sensor_origin, sensor_orientation);
- }
- this->viewer->resetCamera();
我們將其修改為pcl::PointCloud<pcl::PointXYZ>:並獨立出顯示函數void CPointCloudLabDlg::simplevis(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud){ //統計選取點雲數 //建立3D視窗並添加點雲 viewer->removeAllPointClouds(); viewer->removeAllShapes(); viewer->setBackgroundColor (0,0,0); viewer->addPointCloud<pcl::PointXYZ> (cloud,"sample cloud"); viewer->setPointCloudRenderingProperties(pcl::mfc_visualization::PCL_VISUALIZER_POINT_SIZE, 1, "samplecloud"); viewer->addCoordinateSystem (1.0); //viewer->initCameraParameters (); viewer->resetCamera(); }
圖1
圖2
二.點雲濾波1.直通濾波器
這是一個書桌的情境,濾波之前其可視化結果2所示。很明顯可以看出其右側存在一大塊雜訊資料,對於這種大塊的且與主體點雲資料存在明顯界限的雜訊資料,最快的方法就是直接設計一個直通濾波器,該方法簡單易用,且效果明顯,唯一不足的就是需要手動濾波,即使用者必須經過多次嘗試,找到雜訊資料與主體點雲資料的大致邊界。圖3即為直通濾波之後的結果,直通濾波器設定為保留x座標在-0.9~0.6之間的點雲資料,很明顯可以看出書桌左右兩部分的大量雜訊資料被移除掉了。
圖3對於巷道
圖42.StatisticOutlierRemoval濾波器移除離群點 直通濾波雖然能快速移除大量的雜訊點,但其具有很大的局限性,一是需要手動濾波,需要人為判斷雜訊點的一般位置,經過多次嘗試才能找到大致的濾波範圍;二是直通濾波的應用場合有限,除非雜訊點與主體點雲資料具有明顯的界限。下面介紹一種不需要人工判斷且能有限移除主體點雲周圍離群雜訊點的方法,可以解決其中部分問題:建立點雲資料的拓撲結構,對每個點的鄰域進行一個統計分析,並修剪掉那些不符合一定標準的點。我們的稀疏離群點移除方法基於在輸人資料中對點到臨近點的距離分布的計算。對每個點,我們計算它到它的所有臨近點的平均距離。假設得到的結果是一個高斯分布,其形狀由均值和標準差決定,平均距離在標準範圍(由全域距離平均值 和方差定義)之外的點,可被定義為離群點並可從資料集中去除掉。使用StatisticOutlierRemoval濾波器移除離群點之前3所示,濾波過後5所示。
三.點雲精簡
上面兩幅圖的右下角都顯示了其點的數量。
1.包圍盒法
該方法是首先用一個體包圍盒來約束點雲,將所有的點雲資料置於這個包圍盒中,然後把這個大包圍盒分解成許多大小一致的小盒,選取與各小盒中心點或與中心點最接近的點取代各小盒中全部的點,經過該方法處理過的點雲個數即為小盒的個數,該方法操作簡單,能有效減少點雲數量。首先設定包圍盒長寬高,一般我們就用立方體。邊長越長,精簡程度越大。
2.基於Alpha Shapes
基於AlphaShapes的點雲精簡演算法是筆者在研究三維點雲的凸包模型時發現的,三維點雲的凸包模型能近似表示物體表面的輪廓,通過提取三維凸包模型的凸包點來構建物體表面,就可以大幅減少點雲資料量,但是三維凸包不能真實反映物體的輪廓形貌,當物體表面存在凹陷時,凸包就不能反映出來,因此衍生出一種AlphaShapes的概念,該方法能有效保持物體的原貌,其精簡精度也易控制。下面對上面的點雲進一步簡化。
四.點雲重建1.貪婪投影三角化演算法設定參數
來自為知筆記(Wiz)
附件列表
點雲處理軟體開發進度