QT顯示PCL點雲

項目需要,要在QT界面上顯示PCL點雲。所以整理一下,供大家和自己參考。

PCL點雲顯示是基於VTK做的,之前有方法是使用cmake編譯一個VTK控件,放在QT裏,拖動使用。如下圖所示:


這樣做是十分麻煩的,博主沒做過。不過還有個更加簡單的方法。

在QT控件裏拖出一個widget控件

然後右鍵選擇“提升爲”,填寫提升類名稱和頭文件。如下:


選擇添加和提升即可。然後在頭文件裏添加響應的頭文件就可以了(具體看下面代碼)。

注:博主在剛開始用這個方法時,QT版本爲5.4.1,結果不行,後來改成5.6.3可以了。

代碼:

.h文件:

#include <QtWidgets/QMainWindow>
#include "ui_displaymessage.h"

#include <vtkRenderWindow.h>//注意添加這個頭文件,不添加會報錯,但是這個頭文件會帶來編譯時間大大增加
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/visualization/pcl_visualizer.h>

#include<QFile>
#include <QTextStream>

#include<opencv.hpp>
#include<iostream>
#include <vector>
using namespace cv;
class DisplayMessage : public QMainWindow
{
    Q_OBJECT

public:
    DisplayMessage(QWidget *parent = Q_NULLPTR);
public slots:
void on_openButton_clicked();
private:
    Ui::DisplayMessageClass ui;
	pcl::visualization::PCLVisualizer::Ptr viewer;
};
.cpp文件:

#include "displaymessage.h"

DisplayMessage::DisplayMessage(QWidget *parent)
	: QMainWindow(parent)
{
	ui.setupUi(this);
	//初始化PCL顯示控件
	viewer.reset(new pcl::visualization::PCLVisualizer("viewer", false));
	ui.widget->SetRenderWindow(viewer->getRenderWindow());
	viewer->setupInteractor(ui.widget->GetInteractor(), ui.widget->GetRenderWindow());
	ui.widget->update();
}

void DisplayMessage::on_openButton_clicked()
{
	QFile file("PointCloud.txt");
	file.open(QIODevice::ReadOnly|QIODevice::Text);
	QTextStream in(&file);
	QString pointsStr;
	QString midStr;
	vector<double> mid;
	Point3f point;
	Vector<Point3f> points;
	while (!in.atEnd()){
		pointsStr = in.readLine();
		int i = 0;
		do{
			
			midStr.append(pointsStr[i]);
			i++;
			
			if(pointsStr[i]==' '||pointsStr[i]=='\0'){
				mid.push_back(midStr.toDouble());
				midStr.clear();
				i++;
			}
		} 
		while (pointsStr[i] != '\0');
		point.x = mid[0];
		point.y = mid[1];
		point.z = mid[2];
		points.push_back(point);
		mid.clear();

	}
	//定義cloudPoints大小,無序點雲
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloudPoints(new pcl::PointCloud<pcl::PointXYZ>);
	cloudPoints->resize(points.size());
	//將三維座標賦值給PCL點雲座標
	for (int i = 0; i < points.size(); i++){
		(*cloudPoints)[i].x = points[i].x;
		(*cloudPoints)[i].y = points[i].y;
		(*cloudPoints)[i].z = points[i].z;
	}
	//移除窗口點雲
	viewer->removeAllPointClouds();
	//點雲設置
	//設置點雲顏色
	pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_color(cloudPoints, 255, 255, 255);
	//點雲顏色渲染	
	viewer->addPointCloud(cloudPoints, cloud_color, "cloud");
	//設置點雲大小
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "cloud");
	viewer->resetCamera();
	ui.widget->update();
}

注:1.剛開始沒有添加頭文件#include <vtkRenderWindow.h>,報出錯誤:

 錯誤2 error C2440: “static_cast”: 無法從“vtkObjectBase *const ”轉換爲“vtkRenderWindow *”C:\Program Files\PCL 1.8.0\3rdParty\VTK\include\vtk-7.0\vtkSmartPointer.h

 添加後錯誤消失

 2.這裏讀取的是txt文件,需要轉換爲PCL的數據格式,所以寫了個簡單的轉換算法,博主txt文件格式爲:

 xxx xxx xxx

3.PCL官方格式爲pcd。只需要在txt文件前添加文件頭就可以了。格式如下:

# .PCD v0.7 - Point Cloud Data file format
 VERSION 0.7
 FIELDS x y z
 SIZE 4 4 4
 TYPE F F F
 COUNT 1 1 1
 WIDTH 20240000
 HEIGHT 1
 VIEWPOINT 0 0 0 1 0 0 0
 POINTS 20240000
 DATA ascii

注意:PCL點雲分爲有序點雲和無序點雲。博主只使用過無序點雲,無需點雲WIDTH設爲點雲個數,HEIGHT設爲1,

POINT設爲點雲個數。最後把txt後綴改爲pcd即可



參考:http://blog.csdn.net/wokaowokaowokao12345/article/details/51314439




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章