pointcloud library(PCL)是目前發展勢頭最猛的三維點雲處理庫,並且在許多領域都扮演者重要的角色。為了能讓大家更好的了解和使用PCL庫,我們現在正在着手名為PCLlab的項目,目標是集成PCL中的算法實現類似meshlab功能的軟件。而對於PCL的操作,我們需要借助MFC,QT之類的平台來實現界面操作。目前我們主要以MFC平台來集成各個算法。這里要處理的第一個問題就是最基本的顯示功能:如何將PCL中產生的分離窗口與MFC窗口結合。
要實現該功能需要以下幾個關鍵設置:不需要重新繼承其他類,只需要做一些簡單設置即可實現
(1)實例化的初始設置
pcl::visualization::PCLVisualizer m_viewer("PCL",false);
注意:初始化時必須設置成false,否則窗口始終是分離。如果要在類中實例化,由於這種實例化方式不允許,所以可以在pcl_visualizer.h中將構造函數的默認值改為false。
(2)設置顯示窗口的父窗口
m_win =m_viewer.getRenderWindow();
m_win->SetParentId(this->m_hWnd);
(3)添加點雲前要刪除所有點雲,否則無法顯示。如果只是一次性載入的話,可以省略這步
m_viewer.removeAllPointClouds();
核心程序
PCLlabView.h
視圖類頭文件配置
// PCL #include <pcl/console/parse.h> #include <pcl/io/io.h> #include <pcl/io/pcd_io.h> #include <pcl/point_types.h> #include <pcl/common/io.h> #include <pcl/visualization/pcl_visualizer.h> //vtk #include <vtkRenderWindow.h> #include <vtkRenderWindowInteractor.h>
私有成員變量
//Implementation private: pcl::PCLPointCloud2::Ptr m_cloud; pcl::visualization::PCLVisualizer m_viewer; vtkSmartPointer<vtkRenderWindow> m_win; vtkSmartPointer<vtkRenderWindowInteractor> m_iren;
PCLlabView.cpp
主要設置構造函數和OnDraw函數
CPCLlabView::CPCLlabView() { // TODO: addconstruction code here m_win = m_viewer.getRenderWindow(); m_iren = vtkRenderWindowInteractor::New();//重新申請地址 } void CPCLlabView::OnDraw(CDC* /*pDC*/) { CPCLlabDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if(!pDoc) return; // TODO: adddraw code for native data here std::string filename ="pcl_logo.pcd"; if(pcl::io::loadPCDFile(filename,*m_cloud ) == -1)// load the file { PCL_ERROR ("Couldn't read file"); } m_viewer.setBackgroundColor( 0.0, 0.0,0.0 ); m_viewer.removeAllPointClouds();//該函數不加則不顯示 //顯示不同類型pcd文件 Eigen::Vector4f sensor_origin =Eigen::Vector4f::Zero(); Eigen::Quaternionf sensor_orientation =Eigen::Quaternionf::Identity (); if(pcl::getFieldIndex(*m_cloud,"rgb") > 0) { pcl::visualization::PointCloudColorHandlerRGBField<pcl::PCLPointCloud2>::Ptrrgb_handler (newpcl::visualization::PointCloudColorHandlerRGBField<pcl::PCLPointCloud2>(m_cloud)); m_viewer.addPointCloud(m_cloud,rgb_handler, sensor_origin, sensor_orientation); } else { pcl::visualization::PointCloudGeometryHandlerXYZ<pcl::PCLPointCloud2>::Ptrxyz_handler (newpcl::visualization::PointCloudGeometryHandlerXYZ<pcl::PCLPointCloud2>(m_cloud)); m_viewer.addPointCloud(m_cloud,xyz_handler, sensor_origin, sensor_orientation); } m_viewer.resetCamera();//使點雲顯示在屏幕中間,並繞中心操作 CRect rect; GetClientRect(&rect);//實時獲取MFC窗口大小 m_win = m_viewer.getRenderWindow(); m_win->SetSize(rect.right-rect.left,rect.bottom-rect.top); m_win->SetParentId(this->m_hWnd);//將vtk窗口結合到MFC窗口中 m_iren->SetRenderWindow(m_win); m_viewer.createInteractor();//由於初始化設置為false,該處重新創建PCL風格的Interactor m_win->Render(); }
注意:(1)為了突出設置的重點,上面程序只是載入固定的點雲,若實現打開不同文件顯示的功能,可以參考MFC的相關內容。
結果顯示:
最好在win7 環境下進行編譯,在win8下編譯后pcl的窗口和mfc的視圖是分離的。