PCL可视化-vtk窗口嵌入对话框(pcl1.8All in one安装的库直接可以用,不用自己编译)
一、环境介绍:
1、pcl1.8All in one直接安装的,包括vtk在内的一些库都没有自己编译过。
2、vs2015
(很多博客的介绍,需要自己编译支持MFC的VTK啊,或者需要修改源码啊,最终经过实验,只用pcl带的vtk库也是可以完成的。)
二、实现过程
1、新建mfc对话框程序
2、拖控件
对话框中拖出一个CStaitc控件,在控件上右键-》添加变量,添加一个名为m_PCLView的CStatic变量。点确定。
3、为控件添加变量
在dlg.h中找到这个m_PCLView变量,把类型改为PCLVTKViewer(自定义的用于mfc的pcl-vtk可视化类,也是后面代码中的类名)
4、添加PCLVTKViewer类
后面有完整代码,但最重要的就几行:
.h中的新增三个变量:
public:
boost::shared_ptr<pcl::visualization::PCLVisualizer> m_viewer;//要共享指针类型的,要不然,显示窗口会跳出MFC界面
vtkSmartPointer<vtkRenderWindow> m_win;
vtkSmartPointer<vtkRenderWindowInteractor> m_iren;
.cpp中
LPRECT rect = new CRect;
GetWindowRect(rect);
m_viewer.reset(new pcl::visualization::PCLVisualizer("viewer", false));
m_win = m_viewer->getRenderWindow();
m_win->SetParentId(m_hWnd);
m_iren = vtkRenderWindowInteractor::New();
m_win->SetSize(rect->right - rect->left, rect->bottom - rect->top);
m_win->SetPosition(0, 0);
m_iren->SetRenderWindow(m_win);
m_viewer->createInteractor();
//m_viewer->addCoordinateSystem(1);
m_viewer->setBackgroundColor(255, 255, 255);
m_viewer->initCameraParameters();
m_win->Render();
5、调用
首先需要在dlg.cpp的OnInitDialog函数中,调用PCLVTKViewer的init()。
6、完成效果
三、完整代码
1、.h
#pragma once
#pragma once
#include "stdafx.h"
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/io/io.h>
#include <pcl/io/pcd_io.h>
#include <pcl/console/parse.h>
//vtk
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkAutoInit.h>
class PCLVTKViewer : public CStatic
{
DECLARE_DYNAMIC(PCLVTKViewer)
public:
PCLVTKViewer();
virtual ~PCLVTKViewer();
boost::shared_ptr<pcl::visualization::PCLVisualizer> m_viewer;//要共享指针类型的,要不然,显示窗口会跳出MFC界面
vtkSmartPointer<vtkRenderWindow> m_win;
vtkSmartPointer<vtkRenderWindowInteractor> m_iren;
void init();
void setBaseCloud(std::string filename);
protected:
DECLARE_MESSAGE_MAP()
};
2、.cpp
// PCLVTKViewer.cpp : 实现文件
#include "stdafx.h"
#include "PCLVTKViewer.h"
// PCLVTKViewer
IMPLEMENT_DYNAMIC(PCLVTKViewer, CStatic)
PCLVTKViewer::PCLVTKViewer()
{
clicked_points_3d.reset(new pcl::PointCloud<PointT>);
baseCloud.reset(new pcl::PointCloud<PointT>());
}
PCLVTKViewer::~PCLVTKViewer()
{
}
void PCLVTKViewer::init()
{
LPRECT rect = new CRect;
GetWindowRect(rect);
m_viewer.reset(new pcl::visualization::PCLVisualizer("viewer", false));
m_win = m_viewer->getRenderWindow();
m_win->SetParentId(m_hWnd);
m_iren = vtkRenderWindowInteractor::New();
m_win->SetSize(rect->right - rect->left, rect->bottom - rect->top);
m_win->SetPosition(0, 0);
m_iren->SetRenderWindow(m_win);
m_viewer->createInteractor();
//m_viewer->addCoordinateSystem(1);
m_viewer->setBackgroundColor(255, 255, 255);
m_viewer->initCameraParameters();
m_win->Render();
}
//设置显示的点云
void PCLVTKViewer::setBaseCloud(std::string filename)
{
clicked_points_3d.reset(new pcl::PointCloud<PointT>);
baseCloud.reset(new pcl::PointCloud<PointT>());
if (pcl::io::loadPCDFile(filename, *baseCloud))
{
std::cerr << "ERROR: Cannot open file " << filename << "! Aborting..." << std::endl;
return;
}
updateView();
}
BEGIN_MESSAGE_MAP(PCLVTKViewer, CStatic)
END_MESSAGE_MAP()
// PCLVTKViewer 消息处理程序
3、调用
在界面放一个Cstatic,右键->添加变量->命名为m_PCLView。再去dlg.h文件中,把“Cstatic m_PCLView”,改为PCLVTKViewer m_PCLView。最后一步,在dlg.cpp 的OnInitDialog()函数中,调用m_PCLView.init(),初始化显示窗口,把vtk嵌入到对话框中Cstatic的位置。在需要显示的代码中,调用m_PCLView.setBaseCloud()
BOOL CHS_CtrlDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
……
……
……
m_PCLView.init();
m_PCLView.setBaseCloud("y1180.pcd");
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}