ITK VTK重建最简三维(dicom医学影像)更新(2)--仅供测试学习

5 篇文章 0 订阅
3 篇文章 0 订阅

开发环境 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();
    }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值