开发环境 ITK(5.3.0) VTK(8.2.0) QT(5.12.12) VS2017 win10 X64home
代码(部分代码如下,完整代码和程序下载路径如下,所有代码、数据等等相关内容仅供测试学习)
-------------------------------TestITKimage0524.7z-------------------------------------------------
(更新:1.目前增加了 三维重建后面 WW/WL
2.鼠标中间单击切换Zoom 和 WW/WL功能
3.ESC 键恢复初始
)
https://zyq1569.github.io/down.html下载
https://sourceforge.net/projects/health1212/files/Tools/HealthApp/下载
如果直接运行,没有安装环境运行包,需要安装vc2017环境包
下载VC_redist.x64.exe VC_redist.x86.exe
路径下也有 https://sourceforge.net/projects/health1212/files/Tools/HealthApp/下载
----------------------- 选项仅对 Volume-3D 有效
代码如下:
static constexpr double MinimumWindowWidth = 0.0001;
class vtkInteractorStyleTrackballCameraWindowleve : public vtkInteractorStyleTrackballCamera
{
public:
static vtkInteractorStyleTrackballCameraWindowleve *New()
{
return new vtkInteractorStyleTrackballCameraWindowleve;
}
void OnRightButtonDown() override
{
if (m_bFlagWindowLeve)
{
m_startWindowLeve = true;
startWindowLevel();
}
vtkInteractorStyleTrackballCamera::OnRightButtonDown();
}
void OnRightButtonUp() override
{
if (m_bFlagWindowLeve)
{
m_startWindowLeve = false;
endWindowLevel();
}
vtkInteractorStyleTrackballCamera::OnRightButtonUp();
}
void OnMouseMove() override
{
//double p[3];//Interactor->GetPicker()->GetPickPosition(p);
static bool first = true;
if (first)
{
HWND hwnd = (HWND)m_vtkRenderWindow->GetGenericWindowId();
if (hwnd)
{
first = false;
// 设置窗口类的光标
LONG_PTR prevCursor = SetClassLongPtr(hwnd, GCLP_HCURSOR, reinterpret_cast<LONG_PTR>(m_hCursor));
if (prevCursor == 0 && GetLastError() != 0)
{
// 获取错误信息
LPVOID lpMsgBuf;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&lpMsgBuf, 0, NULL);
MessageBox(NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONERROR);
LocalFree(lpMsgBuf);
}
}
}
if (m_bFlagWindowLeve && m_startWindowLeve)
{
doWindowLevel();
}
else
{
vtkInteractorStyleTrackballCamera::OnMouseMove();
}
}
void OnMiddleButtonUp() override
{
m_bFlagWindowLeve = !m_bFlagWindowLeve;
vtkInteractorStyleTrackballCamera::OnMiddleButtonUp();
}
void startWindowLevel()
{
VoiLut voiLut;
voiLut = m_initialLut;
m_initialWindow = voiLut.getWindowLevel().getWidth();
m_initialLevel = voiLut.getWindowLevel().getCenter();
m_initialLut = voiLut.getLut();
m_initialLut.setName(voiLut.getOriginalLutExplanation());
int *vtkpoint = m_vtkRenderWindow->GetInteractor()->GetEventPosition();
m_windowLevelStartPosition = QPoint(vtkpoint[0], vtkpoint[1]);
}
void endWindowLevel()
{
m_vtkRenderWindow->Render();
}
void doWindowLevel()
{
if (m_vtkRenderWindow)
{
//m_vtkRenderWindow->SetCurrentCursor(g_cursor);
//m_viewer->setCursor(QCursor(QPixmap(":/images/cursors/contrast.svg")));
int *vtkpoint = m_vtkRenderWindow->GetInteractor()->GetEventPosition();
m_windowLevelCurrentPosition = QPoint(vtkpoint[0], vtkpoint[1]);
int *vtksize = m_vtkRenderWindow->GetSize();
QSize size = QSize(vtksize[0], vtksize[1]);
double dx = 4.0 * (m_windowLevelCurrentPosition.x() - m_windowLevelStartPosition.x()) / size.width();
double dy = 4.0 * (m_windowLevelStartPosition.y() - m_windowLevelCurrentPosition.y()) / size.height();
double initialWindowWidth = std::max(std::abs(m_initialWindow), MinimumWindowWidth);
dx *= initialWindowWidth;
dy *= initialWindowWidth;
double newWindow = dx + m_initialWindow;
if (newWindow > -MinimumWindowWidth && newWindow < MinimumWindowWidth)
{
newWindow = std::copysign(MinimumWindowWidth, newWindow);
}
double newLevel = m_initialLevel - dy;
VoiLut voiLut;
double oldX1 = m_initialLut.keys().first();
double oldX2 = m_initialLut.keys().last();
double newX1 = newLevel - newWindow / 2.0;
double newX2 = newLevel + newWindow / 2.0;
voiLut = VoiLut(m_initialLut.toNewRange(oldX1, oldX2, newX1, newX2), m_initialLut.name());
voiLut.setExplanation("Custom");
m_initialLut = voiLut.getLut();
m_volumeProperty->SetScalarOpacity(voiLut.getLut().vtkOpacityTransferFunction());
m_volumeProperty->SetColor(voiLut.getLut().vtkColorTransferFunction());
m_vtkRenderWindow->Render();
}
}
void setWindowLeve(bool b)
{
m_bFlagWindowLeve = b;
m_startWindowLeve = false;
}
virtual void OnKeyPress() override
{
vtkRenderWindowInteractor *interactor = this->GetInteractor();
int keyCode = m_vtkRenderWindow->GetInteractor()->GetKeyCode();
if (keyCode == 27)
{
//MessageBox(NULL, "keycode 27", "Error", MB_OK);
m_volumeProperty->SetScalarOpacity(m_oldTransferFunction.vtkOpacityTransferFunction());
m_volumeProperty->SetColor(m_oldTransferFunction.vtkColorTransferFunction());
m_vtkRenderWindow->Render();
}
/*
std::string key = interactor->GetKeySym();
// 打印按下的键
std::cout << "Key pressed: " << key << std::endl;
// 处理特定按键
if (key == "Up")
{
std::cout << "Up arrow key pressed." << std::endl;
}
else if (key == "Down")
{
std::cout << "Down arrow key pressed." << std::endl;
}
*/
// 调用父类的 OnKeyPress 方法
vtkInteractorStyleTrackballCamera::OnKeyPress();
}
private:
bool m_bFlagWindowLeve;
TransferFunction m_initialLut,m_oldTransferFunction;
QPoint m_windowLevelStartPosition;
QPoint m_windowLevelCurrentPosition;
/// Valors per controlar el mapeig del window level
double m_initialWindow, m_initialLevel, m_currentWindow, m_currentLevel;
vtkRenderWindow *m_vtkRenderWindow;
vtkVolumeProperty *m_volumeProperty;
MainWindow *m_MainWindow;
bool m_startWindowLeve;
vtkEventQtSlotConnect *m_vtkQtConnections;
HCURSOR m_hCursor;
public:
void setMainwindowsHand(MainWindow *m_main)
{
m_MainWindow = m_main;
}
void setHCURSOR(HCURSOR hcursor)
{
m_hCursor = hcursor;
}
void setMainwindowsVTKParms(vtkVolumeProperty* vp, vtkRenderWindow* vr, TransferFunction tr)
{
m_vtkRenderWindow = vr;
m_volumeProperty = vp;
m_initialLut = tr;
m_vtkQtConnections = vtkEventQtSlotConnect::New();
//m_MainWindow = m_main;
//m_vtkQtConnections->Connect(m_vtkRenderWindow->GetInteractor(), vtkCommand::AnyEvent, m_MainWindow, SLOT(eventHandler(vtkObject*, unsigned long, void*, void*, vtkCommand*)));
}
void setSaveTransferFunction(TransferFunction tr)
{
VoiLut voiLut;
voiLut = tr;
m_oldTransferFunction = voiLut.getLut();;
m_oldTransferFunction.setName(voiLut.getOriginalLutExplanation());
}
protected:
vtkInteractorStyleTrackballCameraWindowleve()
{
}
~vtkInteractorStyleTrackballCameraWindowleve() override
{
}
private:
vtkInteractorStyleTrackballCameraWindowleve(const vtkInteractorStyleTrackballCameraWindowleve&) = delete;
void operator=(const vtkInteractorStyleTrackballCameraWindowleve&) = delete;
};
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
vtkObjectFactory::RegisterFactory(vtkRenderingOpenGL2ObjectFactory::New());
vtkObjectFactory::RegisterFactory(vtkRenderingVolumeOpenGL2ObjectFactory::New());
QString dir = QCoreApplication::applicationDirPath();
ui->m_dcmDir->setText(dir+"/Dicom Data");
m_rendererViewer=NULL;
m_renderWindow=NULL;
m_opacityTransform=NULL;
m_colorTransformFunction=NULL;
m_gradientTransform=NULL;
m_volumeProperty=NULL;
m_volumeMapper=NULL;
m_volume=NULL;
m_outlineData=NULL;
m_mapOutline=NULL;
m_outline=NULL;
m_renderWindowInteractor=NULL;
m_interactorstyle=NULL;
m_lodProp3D=NULL;
//m_vtkWidget = new QVTKOpenGLNativeWidget(this);
QCursor g_cursor(QPixmap(":/images/cursors/contrast.svg"));
//setCursor(g_cursor);
loadRenderingStyles();
}
MainWindow::~MainWindow()
{
delete ui;
free3Dviewer();
}
void MainWindow::on_pBDir_clicked()
{
QString dlg;
dlg = ui->m_dcmDir->toPlainText();
//第三个参数 如果是"./" 代表当前应用的目录. QString()空为上次打开的目录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
QString path = QFileDialog::getExistingDirectory(this,"select dicom dir...",dlg/*QString()*/,QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
//QString path(QWidget *parent = nullptr, const QString &caption = QString(), const QString &dir = QString(), QFileDialog::Options options = ShowDirsOnly);
//ui->cbDcmDir->setCurrentText(path);
ui->m_dcmDir->setText(path);
ui->m_dcmDir->update();
}
void showImage2D(Input3dImageType::Pointer image)
{
vtkSmartPointer<vtkImageViewer2> viewer = vtkSmartPointer<vtkImageViewer2>::New();
viewer->SetInputData(ImageDataItkToVtk(image));
//设置基本属性
viewer->SetSize(640, 480);
viewer->SetColorLevel(500);
viewer->SetColorWindow(2000);
viewer->SetSlice(40);
viewer->SetSliceOrientationToXY();
viewer->Render();
viewer->GetRenderer()->SetBackground(0, 0, 0);
viewer->GetRenderWindow()->SetWindowName("ImageViewer2D");
vtkSmartPointer<vtkInteractorStyleTrackballCamera> vtkInteractorStyle = vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
vtkSmartPointer<vtkRenderWindowInteractor> RenderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
//设置交互属性
viewer->SetupInteractor(RenderWindowInteractor);
viewer->GetRenderer()->GetRenderWindow()->GetInteractor()->SetInteractorStyle(vtkInteractorStyle);
vtkSmartPointer<vtkSliderRepresentation2D> sliderRep = vtkSmartPointer<vtkSliderRepresentation2D>::New();
sliderRep->SetMinimumValue(viewer->GetSliceMin());
sliderRep->SetMaximumValue(viewer->GetSliceMax());
sliderRep->SetValue(5.0);
sliderRep->GetSliderProperty()->SetColor(1, 0, 0);//red
sliderRep->GetTitleProperty()->SetColor(1, 0, 0);//red
sliderRep->GetLabelProperty()->SetColor(1, 0, 0);//red
sliderRep->GetSelectedProperty()->SetColor(0, 1, 0);//green
sliderRep->GetTubeProperty()->SetColor(1, 1, 0);//yellow
sliderRep->GetCapProperty()->SetColor(1, 1, 0);//yellow
sliderRep->GetPoint1Coordinate()->SetCoordinateSystemToDisplay();
sliderRep->GetPoint1Coordinate()->SetValue(40, 40);
sliderRep->GetPoint2Coordinate()->SetCoordinateSystemToDisplay();
sliderRep->GetPoint2Coordinate()->SetValue(500, 40);
vtkSmartPointer<vtkSliderWidget> sliderWidget = vtkSmartPointer<vtkSliderWidget>::New();
sliderWidget->SetInteractor(RenderWindowInteractor);
sliderWidget->SetRepresentation(sliderRep);
sliderWidget->SetAnimationModeToAnimate();
sliderWidget->EnabledOn();
vtkSmartPointer<vtkSliderCallback> callback = vtkSmartPointer<vtkSliderCallback>::New();
callback->viewer = viewer;
sliderWidget->AddObserver(vtkCommand::InteractionEvent, callback);
vtkSmartPointer<vtkAxesActor> axes = vtkSmartPointer<vtkAxesActor>::New();
double axesSize[3] = { 100,100,100 };
axes->SetTotalLength(axesSize);
axes->SetConeRadius(0.1);
axes->SetShaftTypeToLine();
axes->SetAxisLabels(false);
viewer->GetRenderer()->AddActor(axes);
RenderWindowInteractor->Start();
viewer->Render();
}
//showDcmImage2D
void MainWindow::on_pBITK_clicked()
{
QString dir = ui->m_dcmDir->toPlainText();
std::string Input_Name = qPrintable(dir);
Input3dImageType::Pointer image = GdcmRead3dImage(Input_Name, dir);
showImage2D(image);
return;
}
void MainWindow::loadRenderingStyles()
{
m_renderingStyleModel = new QStandardItemModel(this);
// For the first version we create all this by default.
// For each style we create an item and assign some data that will be used to apply it.
QStandardItem *item;
RenderingStyle renderingStyle;
TransferFunction *transferFunction;
item = new QStandardItem(QIcon(":/renderingstyles/spine2.png"), tr("Spine"));
item->setToolTip("Spine");
renderingStyle.setMethod(RenderingStyle::RayCasting);
renderingStyle.setShading(true);
renderingStyle.setAmbientCoefficient(0.1);
renderingStyle.setDiffuseCoefficient(0.7);
renderingStyle.setSpecularCoefficient(1.0);
renderingStyle.setSpecularPower(64.0);
transferFunction = TransferFunctionIO::fromXmlFile(":/renderingstyles/spine2.xml");
renderingStyle.setTransferFunction(*transferFunction);
delete transferFunction;
item->setData(renderingStyle.toVariant());
m_renderingStyleModel->appendRow(item);
item = new QStandardItem(QIcon(":/renderingstyles/thorax1.png"), tr("Thorax"));
item->setToolTip("Thorax");
renderingStyle.setMethod(RenderingStyle::RayCasting);
renderingStyle.setShading(true);
renderingStyle.setAmbientCoefficient(0.1);
renderingStyle.setDiffuseCoefficient(0.7);
renderingStyle.setSpecularCoefficient(1.0);
renderingStyle.setSpecularPower(64.0);
transferFunction = TransferFunctionIO::fromXmlFile(":/renderingstyles/thorax1.xml");
renderingStyle.setTransferFunction(*transferFunction);
delete transferFunction;
item->setData(renderingStyle.toVariant());
m_renderingStyleModel->appendRow(item);
item = new QStandardItem(QIcon(":/renderingstyles/pelvis2.png"), tr("Pelvis"));
item->setToolTip("Pelvis");
renderingStyle.setMethod(RenderingStyle::RayCasting);
renderingStyle.setShading(true);
renderingStyle.setAmbientCoefficient(0.1);
renderingStyle.setDiffuseCoefficient(0.7);
renderingStyle.setSpecularCoefficient(1.0);
renderingStyle.setSpecularPower(64.0);
transferFunction = TransferFunctionIO::fromXmlFile(":/renderingstyles/pelvis2.xml");
renderingStyle.setTransferFunction(*transferFunction);
delete transferFunction;
item->setData(renderingStyle.toVariant());
m_renderingStyleModel->appendRow(item);
item = new QStandardItem(QIcon(":/renderingstyles/cow1.png"), tr("Circle of Willis"));
item->setToolTip("Circle of Willis");
renderingStyle.setMethod(RenderingStyle::RayCasting);
renderingStyle.setShading(true);
renderingStyle.setAmbientCoefficient(0.1);
renderingStyle.setDiffuseCoefficient(0.7);
renderingStyle.setSpecularCoefficient(0.0);
transferFunction = TransferFunctionIO::fromXmlFile(":/renderingstyles/cow1.xml");
renderingStyle.setTransferFunction(*transferFunction);
delete transferFunction;
item->setData(renderingStyle.toVariant());
m_renderingStyleModel->appendRow(item);
item = new QStandardItem(QIcon(":/renderingstyles/carotids2.png"), tr("Carotids"));
item->setToolTip("Carotids");
renderingStyle.setMethod(RenderingStyle::RayCasting);
renderingStyle.setShading(true);
renderingStyle.setAmbientCoefficient(0.1);
renderingStyle.setDiffuseCoefficient(0.7);
renderingStyle.setSpecularCoefficient(1.0);
renderingStyle.setSpecularPower(64.0);
transferFunction = TransferFunctionIO::fromXmlFile(":/renderingstyles/carotids2.xml");
renderingStyle.setTransferFunction(*transferFunction);
delete transferFunction;
item->setData(renderingStyle.toVariant());
m_renderingStyleModel->appendRow(item);
item = new QStandardItem(QIcon(":/renderingstyles/bones4.png"), tr("Bones"));
item->setToolTip("Bones");
renderingStyle.setMethod(RenderingStyle::RayCasting);
renderingStyle.setShading(true);
renderingStyle.setAmbientCoefficient(0.1);
renderingStyle.setDiffuseCoefficient(0.7);
renderingStyle.setSpecularCoefficient(1.0);
renderingStyle.setSpecularPower(64.0);
transferFunction = TransferFunctionIO::fromXmlFile(":/renderingstyles/bones4.xml");
renderingStyle.setTransferFunction(*transferFunction);
delete transferFunction;
item->setData(renderingStyle.toVariant());
m_renderingStyleModel->appendRow(item);
item = new QStandardItem(QIcon(":/renderingstyles/bonehires.png"), tr("Bones 2"));
item->setToolTip("Bones 2");
renderingStyle.setMethod(RenderingStyle::RayCasting);
renderingStyle.setShading(true);
renderingStyle.setAmbientCoefficient(0.1);
renderingStyle.setDiffuseCoefficient(0.7);
renderingStyle.setSpecularCoefficient(0.0);
transferFunction = TransferFunctionIO::fromXmlFile(":/renderingstyles/bonehires.xml");
renderingStyle.setTransferFunction(*transferFunction);
delete transferFunction;
item->setData(renderingStyle.toVariant());
m_renderingStyleModel->appendRow(item);
item = new QStandardItem(QIcon(":/renderingstyles/abdomenbones.png"), tr("Abdomen bones"));
item->setToolTip("Abdomen bones");
renderingStyle.setMethod(RenderingStyle::RayCasting);
renderingStyle.setShading(true);
renderingStyle.setAmbientCoefficient(0.1);
renderingStyle.setDiffuseCoefficient(0.7);
renderingStyle.setSpecularCoefficient(1.0);
renderingStyle.setSpecularPower(64.0);
transferFunction = TransferFunctionIO::fromXmlFile(":/renderingstyles/abdomenbones.xml");
renderingStyle.setTransferFunction(*transferFunction);
delete transferFunction;
item->setData(renderingStyle.toVariant());
m_renderingStyleModel->appendRow(item);
item = new QStandardItem(QIcon(":/renderingstyles/abdomenrunoff1.png"), tr("Abdomen run-off"));
item->setToolTip("Abdomen run-off");
renderingStyle.setMethod(RenderingStyle::RayCasting);
renderingStyle.setShading(true);
renderingStyle.setAmbientCoefficient(0.1);
renderingStyle.setDiffuseCoefficient(0.7);
renderingStyle.setSpecularCoefficient(1.0);
renderingStyle.setSpecularPower(64.0);
transferFunction = TransferFunctionIO::fromXmlFile(":/renderingstyles/abdomenrunoff1.xml");
renderingStyle.setTransferFunction(*transferFunction);
delete transferFunction;
item->setData(renderingStyle.toVariant());
m_renderingStyleModel->appendRow(item);
item = new QStandardItem(QIcon(":/renderingstyles/abdomenslab.png"), tr("Abdomen slab"));
item->setToolTip("Abdomen slab");
renderingStyle.setMethod(RenderingStyle::RayCasting);
renderingStyle.setShading(true);
renderingStyle.setAmbientCoefficient(0.1);
renderingStyle.setDiffuseCoefficient(0.7);
renderingStyle.setSpecularCoefficient(1.0);
renderingStyle.setSpecularPower(64.0);
transferFunction = TransferFunctionIO::fromXmlFile(":/renderingstyles/abdomenslab.xml");
renderingStyle.setTransferFunction(*transferFunction);
delete transferFunction;
item->setData(renderingStyle.toVariant());
m_renderingStyleModel->appendRow(item);
//ui->m_renderingStyleListView->setSpacing(6);
//ui->m_renderingStyleListView->setIconSize(QSize(64, 64));
//m_renderingStyleListView->setModel(m_renderingStyleModel);
ui->m_renderingStyleListView->setModel(m_renderingStyleModel);
// Rendering styles
connect(ui->m_renderingStyleListView, SIGNAL(activated(const QModelIndex&)), SLOT(applyRenderingStyle(const QModelIndex&)));
}
void MainWindow::applyRenderingStyle(const QModelIndex &index)
{
if (m_volumeProperty)
{
QStandardItem *item = m_renderingStyleModel->itemFromIndex(index);
RenderingStyle renderingStyle = RenderingStyle::fromVariant(item->data());
m_transferFunction = renderingStyle.getTransferFunction();
m_volumeProperty->SetScalarOpacity(m_transferFunction.vtkOpacityTransferFunction());
m_volumeProperty->SetColor(m_transferFunction.vtkColorTransferFunction());
m_volumeProperty->SetAmbient(0.1);
m_volumeProperty->SetDiffuse(0.7);
m_volumeProperty->SetSpecular(renderingStyle.getSpecularCoefficient());
m_volumeProperty->SetSpecularPower(64.0);
m_renderWindow->Render();
m_renderWindow->SetWindowName("Volume-3D");
m_interactorstyle->setMainwindowsVTKParms( m_volumeProperty, m_renderWindow, m_transferFunction);
m_interactorstyle->setSaveTransferFunction(m_transferFunction);
}
}
void MainWindow::initImage3D_ITK_VTK(vtkActor *vtkactor)
{
QString dir = ui->m_dcmDir->toPlainText();
Input3dImageType::Pointer image = GdcmRead3dImage(qPrintable(dir), dir);
vtkMarchingCubes *marchingcube = vtkMarchingCubes::New();
vtkSmartPointer<vtkImageData> ImageVTKData = ImageDataItkToVtk(image);
image = NULL;
marchingcube->SetInputData(ImageVTKData);
marchingcube->SetValue(0, 200);//Setting the threshold;
marchingcube->ComputeNormalsOn();//计算表面法向量;
vtkStripper *Stripper = vtkStripper::New();
Stripper->SetInputConnection(marchingcube->GetOutputPort());//获取三角片
marchingcube->Delete();
marchingcube = NULL;
vtkPolyDataMapper *Mapper = vtkPolyDataMapper::New();//将三角片映射为几何数据;
Mapper->SetInputConnection(Stripper->GetOutputPort());
Stripper->Delete();
Stripper = NULL;
Mapper->ScalarVisibilityOff();//
vtkactor->SetMapper(Mapper);//获得皮肤几何数据
Mapper->Delete();
Mapper = NULL;
vtkactor->GetProperty()->SetDiffuseColor(.50, .50, .50);//设置皮肤颜色;
vtkactor->GetProperty()->SetSpecular(0.3);//反射率;
vtkactor->GetProperty()->SetOpacity(1.0);//透明度;
vtkactor->GetProperty()->SetSpecularPower(20);//反射光强度;
vtkactor->GetProperty()->SetColor(0.23, 0.23, 0.23);//设置角的颜色;
vtkactor->GetProperty()->SetRepresentationToWireframe();//线框;
vtkOutlineFilter * outfilterline = vtkOutlineFilter::New();
outfilterline->SetInputData(ImageVTKData);
vtkPolyDataMapper *outmapper = vtkPolyDataMapper::New();
outmapper->SetInputConnection(outfilterline->GetOutputPort());
outfilterline->Delete();
outfilterline = NULL;
ImageVTKData = NULL;
vtkActor *OutlineActor = vtkActor::New();
OutlineActor->SetMapper(outmapper);
OutlineActor->GetProperty()->SetColor(0, 0, 0);//线框颜色
outmapper->Delete();
outmapper = NULL;
OutlineActor->Delete();
OutlineActor = NULL;
}
void MainWindow::showImage3D_ITK_VTK()
{
QString DicomDir = ui->m_dcmDir->toPlainText();
QDir dir;
if (!dir.exists(DicomDir))
{
QMessageBox::information(NULL, "Dicom3D", "No dicom files!");
return;
}
vtkActor *vtkactor = vtkActor::New();
initImage3D_ITK_VTK(vtkactor);
vtkRenderer *vtkrenderer = vtkRenderer::New();
vtkRenderWindow* show3DWinow = vtkRenderWindow::New();
show3DWinow->AddRenderer(vtkrenderer);
vtkRenderWindowInteractor *show3DInteractor = vtkRenderWindowInteractor::New();
show3DInteractor->SetRenderWindow(show3DWinow);
vtkrenderer->AddActor(vtkactor);
vtkrenderer->SetBackground(1, 1, 1);//设置背景颜色;
show3DWinow->SetSize(500, 500);
vtkInteractorStyleTrackballCamera *style = vtkInteractorStyleTrackballCamera::New();
show3DInteractor->SetInteractorStyle(style);
show3DWinow->Render();
show3DWinow->SetWindowName("Image3D-Viewer");
show3DInteractor->Initialize();
show3DInteractor->Start();
style->Delete();
style = NULL;
vtkrenderer->Delete();
vtkrenderer = NULL;
vtkactor->Delete();
vtkactor = NULL;
show3DWinow->Delete();
show3DWinow = NULL;
show3DInteractor->Delete();
show3DInteractor = NULL;
}
void MainWindow::on_pBITK3D_clicked()//return show3DIVTK(Input_Name);
{
showImage3D_ITK_VTK();
}
void MainWindow::free3Dviewer()
{
if (m_rendererViewer)
{
m_rendererViewer->Delete();
m_renderWindow->Delete();
m_volumeProperty->Delete();
m_volumeMapper->Delete();
m_volume->Delete();
m_outlineData->Delete();
m_mapOutline->Delete();
m_outline->Delete();
m_renderWindowInteractor->Delete();
m_interactorstyle->Delete();
m_lodProp3D->Delete();
m_rendererViewer = NULL;
m_renderWindow = NULL;
//m_opacityTransform = NULL;
//m_colorTransformFunction = NULL;
//m_gradientTransform = NULL;
m_volumeProperty = NULL;
m_volumeMapper = NULL;
m_volume = NULL;
m_outlineData = NULL;
m_mapOutline = NULL;
m_outline = NULL;
m_renderWindowInteractor = NULL;
m_interactorstyle = NULL;
m_lodProp3D = NULL;
}
}
void MainWindow::on_pBVolume3D_clicked()
{
static bool init = true;
if (init)
{
init = false;
ui->pBVolume3D->setText("Close 3DViewer");
QString DicomDir = ui->m_dcmDir->toPlainText();
QDir dir;
if (!dir.exists(DicomDir))
{
QMessageBox::information(NULL, "Dicom3D", "No dicom files!");
return;
}
std::string Input_Name = qPrintable(DicomDir);
Input3dImageType::Pointer dicomimage = GdcmRead3dImage(Input_Name, DicomDir);
static bool init = false;
if (!init)
{
vtkObjectFactory::RegisterFactory(vtkRenderingOpenGL2ObjectFactory::New());
vtkObjectFactory::RegisterFactory(vtkRenderingVolumeOpenGL2ObjectFactory::New());
init = true;
}
//定义绘制器;
m_rendererViewer = vtkRenderer::New();//指向指针;
m_renderWindow = vtkRenderWindow::New(); //m_vtkWidget->GetRenderWindow();
//m_renderWindow->GetCurrentCursor();
m_renderWindow->AddRenderer(m_rendererViewer);
/// Funció de transferència d'opacitat escalar.
//OpacityTransferFunction m_scalarOpacity;
//m_transferFunction.colorTransferFunction = colorTransformFunction;
//m_transferFunction.opacityTransferFunction = opacityTransform;
//透明度映射函数定义;
m_transferFunction.setScalarOpacity(-1024, 0.0);
m_transferFunction.setScalarOpacity(-24, 0.0);
m_transferFunction.setScalarOpacity(167.00000000000000, 0.16862745098039220);
m_transferFunction.setScalarOpacity(218.00000000000000, 0.41960784313725491);
m_transferFunction.setScalarOpacity(218.00000000000000, 0.41960784313725491);
m_transferFunction.setScalarOpacity(445.00000000000000, 0.57254901960784310);
m_transferFunction.setScalarOpacity(1455.0000000000000, 0.87450980392156863);
m_transferFunction.setScalarOpacity(2784.0000000000000, 0.88235294117647056);
//颜色映射函数定义,梯度上升的
m_transferFunction.setColor(-1024.0, 1.0, 0.13725490196078433, 0.17254901960784313);
m_transferFunction.setColor(24.0, 1.0, 0.13725490196078433, 0.17254901960784313);
m_transferFunction.setColor(163.0, 1.0, 0.13725490196078433, 0.17254901960784313);
m_transferFunction.setColor(167.0, 1.0, 0.35294117647058826, 0.16862745098039217);
m_transferFunction.setColor(218.0, 1.0, 0.63921568627450975, 0.11372549019607843);
m_transferFunction.setColor(445.0, 1.0, 1.0, 1.0);
m_transferFunction.setColor(1455.0, 1.0, 1.0, 1.0);
m_transferFunction.setColor(2784.0, 1.0, 1.0, 1.0);
//m_gradientTransform = vtkPiecewiseFunction::New();
//m_gradientTransform->AddPoint(1, 0.0);
//m_gradientTransform->AddPoint(70, 0.5);
//m_gradientTransform->AddPoint(130, 1.0);
//gradientTransform->AddPoint(300, 0.1);
//体数据属性;
m_volumeProperty = vtkVolumeProperty::New();
m_volumeProperty->SetScalarOpacity(m_transferFunction.vtkOpacityTransferFunction());
m_volumeProperty->SetColor(m_transferFunction.vtkColorTransferFunction());
//m_volumeProperty->SetGradientOpacity(m_gradientTransform);
m_volumeProperty->SetIndependentComponents(true);
m_volumeProperty->ShadeOn();//应用
m_volumeProperty->SetInterpolationTypeToLinear();//直线间样条插值;
m_volumeProperty->SetAmbient(0.4);//环境光系数;
m_volumeProperty->SetDiffuse(0.69996);//漫反射;
m_volumeProperty->SetSpecular(0.2);
m_volumeProperty->SetSpecularPower(10);//高光强度;
vtkSmartPointer<vtkImageData> itkImageData = ImageDataItkToVtk(dicomimage);
//光纤映射类型定义:
//Mapper定义,
m_volumeMapper = vtkSmartVolumeMapper::New();
m_volumeMapper->SetInputData(itkImageData);//;cast_file->GetOutput());
m_volumeMapper->SetBlendModeToComposite();
m_volumeMapper->SetRequestedRenderModeToDefault();
m_lodProp3D = vtkLODProp3D::New();
m_lodProp3D->AddLOD(m_volumeMapper, m_volumeProperty, 0.0);
m_volume = vtkVolume::New();
m_volume->SetMapper(m_volumeMapper);
m_volume->SetProperty(m_volumeProperty);//设置体属性;
m_outlineData = vtkOutlineFilter::New();//线框;
m_outlineData->SetInputData(itkImageData);
m_mapOutline = vtkPolyDataMapper::New();
m_mapOutline->SetInputConnection(m_outlineData->GetOutputPort());
m_outline = vtkActor::New();
m_outline->SetMapper(m_mapOutline);
m_outline->GetProperty()->SetColor(0, 0, 0);//背景纯黑色;
m_rendererViewer->AddVolume(m_volume);
m_rendererViewer->AddActor(m_outline);
m_rendererViewer->SetBackground(1, 1, 1);
m_rendererViewer->ResetCamera();
//重设相机的剪切范围;
m_rendererViewer->ResetCameraClippingRange();
m_renderWindow->SetSize(600, 600);
m_renderWindowInteractor = vtkRenderWindowInteractor::New();
m_renderWindowInteractor->SetRenderWindow(m_renderWindow);
//设置相机跟踪模式
m_interactorstyle = vtkInteractorStyleTrackballCameraWindowleve::New();
m_interactorstyle->setWindowLeve(true);
m_interactorstyle->setMainwindowsVTKParms(m_volumeProperty, m_renderWindow, m_transferFunction);
m_interactorstyle->setSaveTransferFunction(m_transferFunction);
m_renderWindowInteractor->SetInteractorStyle(m_interactorstyle);
//vtkInteractorStyle *m_interactorStyle = vtkInteractorStyle::SafeDownCast(m_renderWindowInteractor->GetInteractorStyle());
//m_interactorStyle->StartRotate();
QCursor qcursor(QPixmap(":/images/cursors/contrast.svg"));
HCURSOR hCursor = QCursorToHCursor(qcursor);
m_interactorstyle->setHCURSOR(hCursor);
bool m_bWL = true;
m_renderWindow->Render();
m_renderWindow->SetWindowName("Volume-3D:ESC还原 右键WW/WL | 左键旋转");
SetCursor(hCursor);
//RenderWindowInteractor->Initialize();
//RenderWindowInteractor->Start();
}
else
{
init = true;
ui->pBVolume3D->setText("Volume-3D");
free3Dviewer();
}