您的位置:首页 > 编程语言 > Qt开发

用vtk+Qt实现离散数据的体绘制

2017-03-16 22:14 585 查看
数据是三维矩阵保存其值,坐标表示位置

以下是实现代码(头文件和main函数没有贴上去)

#define vtkRenderingCore_AUTOINIT 4(vtkInteractionStyle,vtkRenderingFreeType,vtkRenderingFreeType,vtkRenderingOpenGL2)
#define vtkRenderingVolume_AUTOINIT 1(vtkRenderingVolumeOpenGL2)
#include <vtkAutoInit.h>

#include "test_qt.h"
#include <vtkSmartPointer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkCylinderSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkProperty.h>
#include <QVBoxLayout>
#include <QGridLayout>
#include <QFileDialog>
#include <vtkSmartPointer.h>
#include <vtkImageData.h>
#include <vtkStructuredPoints.h>
#include <vtkStructuredPointsReader.h>
#include <vtkVolumeRayCastCompositeFunction.h>
#include <vtkGPUVolumeRayCastMapper.h>
#include <vtkVolumeRayCastMapper.h>
#include <vtkColorTransferFunction.h>
#include <vtkPiecewiseFunction.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkVolumeProperty.h>
#include <vtkAxesActor.h>
#include <vtkImageShiftScale.h>
#include <vtkImageCast.h>
#include <vtkFixedPointVolumeRayCastMapper.h>
#include <vtkInformation.h>
#include <vtkInteractorStyleTrackballActor.h>
#include <fstream>
#include <cmath>

test_qt::test_qt(QWidget *parent)
: QMainWindow(parent)
{
//ui.setupUi(this);
setWindowTitle(tr("vtk show 3D"));
setCentralWidget(&widget);

//renderer = vtkSmartPointer<vtkRenderer>::New();
//renderer->AddActor(cylinderActor);
//renderer->SetBackground(1.0, 1.0, 1.0);

resize(1200, 800);

rightWidget = new QDockWidget("Navigation", this);
rightWidget->setFeatures(QDockWidget::DockWidgetMovable);
rightWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
//leftWidget->setWindowFlags(Qt::FramelessWindowHint);
addDockWidget(Qt::RightDockWidgetArea, rightWidget);

minLabel = new QLabel(tr("min:"));
minLineEdit = new QLineEdit(tr("4"));
QGridLayout * minLabelLayout = new QGridLayout;
minLabelLayout->addWidget(minLabel, 0, 0);
minLabelLayout->addWidget(minLineEdit, 0, 1);

minScrollBar = new QScrollBar(Qt::Horizontal);
minScrollBar->setRange(0, 255);
minScrollBar->setSingleStep(1);
minScrollBar->setValue(4);
connect(minScrollBar, SIGNAL(valueChanged(int)), this, SLOT(minChanged(int)));

maxLabel = new QLabel(tr("max:"));
maxLineEdit = new QLineEdit(tr("200"));
QGridLayout * maxLabelLayout = new QGridLayout;
maxLabelLayout->addWidget(maxLabel, 0, 0);
maxLabelLayout->addWidget(maxLineEdit, 0, 1);

maxScrollBar = new QScrollBar(Qt::Horizontal);
maxScrollBar->setRange(0, 255);
maxScrollBar->setSingleStep(1);
maxScrollBar->setValue(200);
connect(maxScrollBar, SIGNAL(valueChanged(int)), this, SLOT(maxChanged(int)));

QVBoxLayout * layoutGray = new QVBoxLayout;
layoutGray->addSpacing(10);
layoutGray->addLayout(minLabelLayout);
layoutGray->addWidget(minScrollBar);
layoutGray->addSpacing(10);
layoutGray->addLayout(maxLabelLayout);
layoutGray->addWidget(maxScrollBar);
layoutGray->addSpacing(10);

grayGroupBox = new QGroupBox;
grayGroupBox->setLayout(layoutGray);
grayGroupBox->setTitle(tr("Gray level[0,255]"));

transparencyScrollBar = new QScrollBar(Qt::Horizontal);
transparencyScrollBar->setRange(0, 100);
transparencyScrollBar->setSingleStep(1);
transparencyScrollBar->setValue(3);
connect(transparencyScrollBar, SIGNAL(valueChanged(int)),
this, SLOT(transparencyChanged(int)));

transparencyLabel = new QLabel(tr("transparency:"));
transparencyLineEdit = new QLineEdit(tr("0.03"));
QGridLayout * transparencyLabelLayout = new QGridLayout;
transparencyLabelLayout->addWidget(transparencyLabel, 0, 0);
transparencyLabelLayout->addWidget(transparencyLineEdit, 0, 1);

QVBoxLayout * layoutTrans = new QVBoxLayout;
layoutTrans->addLayout(transparencyLabelLayout);
layoutTrans->addWidget(transparencyScrollBar);

transparencyGroupBox = new QGroupBox;
transparencyGroupBox->setLayout(layoutTrans);
transparencyGroupBox->setTitle(tr("Transparency[0,1]"));

QGridLayout * layoutGroupBox = new QGridLayout;
layoutGroupBox->addWidget(grayGroupBox);
layoutGroupBox->addWidget(transparencyGroupBox);

ParSetGroupBox = new QGroupBox;
ParSetGroupBox->setLayout(layoutGroupBox);
ParSetGroupBox->setTitle(tr("Parameter Setting"));

xLabel = new QLabel(tr("x:"));
yLabel = new QLabel(tr("y:"));
zLabel = new QLabel(tr("z:"));

xLineEdit = new QLineEdit(tr("480"));
xLineEdit->setMaximumWidth(50);
yLineEdit = new QLineEdit(tr("480"));
yLineEdit->setMaximumWidth(50);
zLineEdit = new QLineEdit(tr("16"));
zLineEdit->setMaximumWidth(50);

QHBoxLayout * xyzLayout = new QHBoxLayout;
xyzLayout->addWidget(xLabel);
xyzLayout->addWidget(xLineEdit);
xyzLayout->addWidget(yLabel);
xyzLayout->addWidget(yLineEdit);
xyzLayout->addWidget(zLabel);
xyzLayout->addWidget(zLineEdit);

dxLabel = new QLabel(tr("dx:"));
dyLabel = new QLabel(tr("dy:"));
dzLabel = new QLabel(tr("dz:"));

dxLineEdit = new QLineEdit(tr("5"));
dxLineEdit->setMaximumWidth(50);
dyLineEdit = new QLineEdit(tr("5"));
dyLineEdit->setMaximumWidth(50);
dzLineEdit = new QLineEdit(tr("50"));
dzLineEdit->setMaximumWidth(50);

QHBoxLayout * dxyzLayout = new QHBoxLayout;
dxyzLayout->addWidget(dxLabel);
dxyzLayout->addWidget(dxLineEdit);
dxyzLayout->addWidget(dyLabel);
dxyzLayout->addWidget(dyLineEdit);
dxyzLayout->addWidget(dzLabel);
dxyzLayout->addWidget(dzLineEdit);

openBtn = new QPushButton(tr("Open"));
connect(openBtn, SIGNAL(clicked()), this, SLOT(open()));

QVBoxLayout * btnLayout = new QVBoxLayout;

btnLayout->addLayout(xyzLayout);
btnLayout->addLayout(dxyzLayout);
btnLayout->addWidget(openBtn);

readGroupBox = new QGroupBox;
readGroupBox->setLayout(btnLayout);
readGroupBox->setTitle(tr("Data Setting"));

QVBoxLayout * rightlayout = new QVBoxLayout;
rightlayout->addSpacing(150);
rightlayout->addWidget(ParSetGroupBox);
rightlayout->addSpacing(150);
rightlayout->addWidget(readGroupBox);
//rightlayout->addLayout(layout5);

QWidget * widget1 = new QWidget;
widget1->setLayout(rightlayout);
rightWidget->setWidget(widget1);

min_gray = 4;
max_gray = 200;
transparency = 0.03;
dx = dy = 5;
dz = 50;
x = y = 480;
z = 16;
isOpen = false;

vtkSmartPointer<vtkRenderer> ren1 = vtkSmartPointer<vtkRenderer>::New();
ren1->SetBackground(1.0, 1.0, 1.0);

auto window = widget.GetRenderWindow();

window->AddRenderer(ren1);
window->Render();

}

test_qt::~test_qt()
{

}

void test_qt::maxChanged(int v)
{
maxLineEdit->setText(QString::number(v));
max_gray = v;
if (isOpen)
update();
}

void test_qt::transparencyChanged(int v)
{
transparencyLineEdit->setText(QString::number(v / 100.0f));
transparency = v / 100.0f;
if (isOpen)
update();
}

void test_qt::minChanged(int v)
{
minLineEdit->setText(QString::number(v));
min_gray = v;
if (isOpen)
update();
}

void test_qt::open()
{
QString filename = QFileDialog::getOpenFileName(this,
tr("Open the file"),
"",
tr("*.dat"));
if (!filename.isEmpty())
{
dx = dxLineEdit->text().toInt();
dy = dyLineEdit->text().toInt();
dz = dzLineEdit->text().toInt();

x = xLineEdit->text().toInt();
y = yLineEdit->text().toInt();
z = zLineEdit->text().toInt();

auto img = vtkSmartPointer<vtkImageData>::New();
auto info = vtkSmartPointer<vtkInformation>::New();
//auto info3 = img->GetInformation();//此处也可以从img里面获取information,如
//果information为空,则会创建一个新的,相当于调用New之后再SetInformation
img->SetDimensions(x, y, z);
img->SetSpacing(dx, dy, dz);
img->SetOrigin(0, 0, 0);
img->SetScalarType(VTK_UNSIGNED_CHAR, info);
img->SetNumberOfScalarComponents(1, info);
img->AllocateScalars(info);

unsigned char *ptr = (unsigned char *)img->GetScalarPointer();
ifstream infile(filename.toStdString(), std::ios::binary);
float temp, max = 0;
fl
4000
oat *tempfloat = new float[x * y * z];

for (int i = 0; i<x * y * z; i++)
{
infile.read((char*)&temp, sizeof(float));
//temp = log(temp);
if (max < temp)
max = temp;
tempfloat[i] = temp;
}
infile.close();
for (int i = 0; i<x * y * z; i++)
*ptr++ = tempfloat[i] / max * 255;
delete[] tempfloat;

volumeMapper = vtkSmartPointer<vtkGPUVolumeRayCastMapper>::New();
volumeMapper->SetInputData(img);

vtkSmartPointer<vtkVolumeProperty> volumeProperty
= vtkSmartPointer<vtkVolumeProperty>::New();
volumeProperty->SetInterpolationTypeToLinear();
//volumeProperty->ShadeOn(); //打开或者关闭阴影测试
volumeProperty->SetAmbient(0.4);
volumeProperty->SetDiffuse(0.6);
volumeProperty->SetSpecular(0.2);

vtkSmartPointer<vtkPiecewiseFunction> compositeOpacity =
vtkSmartPointer<vtkPiecewiseFunction>::New();
compositeOpacity->ClampingOn();
compositeOpacity->AddPoint(min_gray, 0);
compositeOpacity->AddPoint(max_gray, transparency);

volumeProperty->SetScalarOpacity(compositeOpacity); //设置不透明度传输函数

vtkSmartPointer<vtkColorTransferFunction> color =
vtkSmartPointer<vtkColorTransferFunction>::New();

color->AddRGBPoint(0.0, 0.0, 0.0, 0.0);
color->AddRGBPoint(36.0, 1.0, 0.0, 0.0);
color->AddRGBPoint(72.0, 1.0, 1.0, 0.0);
color->AddRGBPoint(108.0, 0.0, 1.0, 0.0);
color->AddRGBPoint(144.0, 0.0, 1.0, 1.0);
color->AddRGBPoint(180.0, 0.0, 0.0, 1.0);
color->AddRGBPoint(216.0, 1.0, 0.0, 1.0);
color->AddRGBPoint(255.0, 1.0, 1.0, 1.0);
/*
color->AddRGBPoint(0.0, 0.0, 0.0, 0.0);
color->AddRGBPoint(36.0, 1.0, 0.0, 0.0);
color->AddRGBPoint(72.0, 1.0, 1.0, 0.0);
color->AddRGBPoint(108.0, 0.0, 1.0, 0.0);
color->AddRGBPoint(144.0, 0.0, 1.0, 1.0);
color->AddRGBPoint(180.0, 0.0, 0.0, 1.0);
color->AddRGBPoint(216.0, 1.0, 0.0, 1.0);
color->AddRGBPoint(255.0, 1.0, 1.0, 1.0);*/
volumeProperty->SetColor(color);

volume = vtkSmartPointer<vtkVolume>::New();
volume->SetMapper(volumeMapper);
volume->SetProperty(volumeProperty);

ren = vtkSmartPointer<vtkRenderer>::New();
ren->SetBackground(1.0, 1.0, 1.0);
ren->AddVolume(volume);
//ren->ResetCamera();

auto window = widget.GetRenderWindow();

window->AddRenderer(ren);
window->Render();

interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
interactor->SetRenderWindow(window);

auto style = vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
interactor->SetInteractorStyle(style);

interactor->Initialize();
isOpen = true;
}
}

void test_qt::update()
{
vtkSmartPointer<vtkVolumeProperty> volumeProperty
= vtkSmartPointer<vtkVolumeProperty>::New();
volumeProperty->SetInterpolationTypeToLinear();
//volumeProperty->ShadeOn(); //打开或者关闭阴影测试
volumeProperty->SetAmbient(0.4);
volumeProperty->SetDiffuse(0.6);
volumeProperty->SetSpecular(0.2);

vtkSmartPointer<vtkPiecewiseFunction> compositeOpacity =
vtkSmartPointer<vtkPiecewiseFunction>::New();
compositeOpacity->ClampingOff();
compositeOpacity->AddPoint(min_gray, 0);
compositeOpacity->AddPoint(max_gray, transparency);

volumeProperty->SetScalarOpacity(compositeOpacity); //设置不透明度传输函数

vtkSmartPointer<vtkColorTransferFunction> color =
vtkSmartPointer<vtkColorTransferFunction>::New();
float temp = (max_gray - min_gray) / 7;
color->AddRGBPoint(min_gray, 0.0, 0.0, 0.0);
color->AddRGBPoint(min_gray + temp, 1.0, 0.0, 0.0);
color->AddRGBPoint(min_gray + temp * 2, 1.0, 1.0, 0.0);
color->AddRGBPoint(min_gray + temp * 3, 0.0, 1.0, 0.0);
color->AddRGBPoint(min_gray + temp * 4, 0.0, 1.0, 1.0);
color->AddRGBPoint(min_gray + temp * 5, 0.0, 0.0, 1.0);
color->AddRGBPoint(min_gray + temp * 6, 1.0, 0.0, 1.0);
color->AddRGBPoint(min_gray + temp * 7, 1.0, 1.0, 1.0);
volumeProperty->SetColor(color);

//vtkSmartPointer<vtkVolume> volume = vtkSmartPointer<vtkVolume>::New();
volume->SetMapper(volumeMapper);
volume->SetProperty(volumeProperty);

//ren = vtkSmartPointer<vtkRenderer>::New();
ren->SetBackground(1.0, 1.0, 1.0);
ren->AddVolume(volume);
//ren->ResetCamera();

auto window = widget.GetRenderWindow();

window->AddRenderer(ren);
window->Render();

interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
interactor->SetRenderWindow(window);

auto style = vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
interactor->SetInteractorStyle(style);

interactor->Initialize();
}
以下是运行效果,只给界面图

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: