喝着咖啡的小程序猿
2018-04-12 09:00
采纳率: 100%
浏览 1.6k
已采纳

如果电脑没有安装OpenCV,那么请问该如何仅用VTK实现图形任意平面的切割?求大佬代码指点!

网上找了一些关于基于VTK的任意平面切割,但是代码都是那一个一样的基于OpenCV
的代码,而假如我不想使用OpenCV,(而且我还找不到头文件"VTKReBuild.h")那么这个程序改怎么写呢?而且我想切割出来的是一个有一定厚度的立体图,相当于一个圆环类似(以人体模型为例,若选择从腹部切割开来的话,保留的便是以切割平面为基准大概1cm上下的切割图)恳求大佬指点!

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

3条回答 默认 最新

  • _1_1_7_ 2018-04-12 09:03
    已采纳
    点赞 打赏 评论
  • 十分感谢你的回答,但是我想请问下头文件vtkTestUtilities.h和vtkRegressionTestImage.h是哪来的呢?请问是在安装VTK的时候我漏装了环境而使我没有这两个头文件吗?

    点赞 打赏 评论
  • #include "vtkAutoInit.h"

    VTK_MODULE_INIT(vtkRenderingOpenGL2);
    VTK_MODULE_INIT(vtkInteractionStyle);
    #include "vtkSmartPointer.h"
    #include "vtkRegressionTestImage.h"
    #include "vtkActor.h"
    #include "vtkCamera.h"
    #include "vtkCellPicker.h"
    #include "vtkCommand.h"
    #include "vtkImageActor.h"
    #include "vtkImageReslice.h"
    #include "vtkInteractorStyleImage.h"
    #include "vtkImageMapToColors.h"
    #include "vtkImagePlaneWidget.h"
    #include "vtkImageReader.h"
    #include "vtkInteractorEventRecorder.h"
    #include "vtkLookupTable.h"
    #include "vtkOutlineFilter.h"
    #include "vtkDICOMImageReader.h"
    #include "vtkPolyDataMapper.h"
    #include "vtkProperty.h"
    #include "vtkRenderWindow.h"
    #include "vtkRenderWindowInteractor.h"
    #include "vtkRenderer.h"
    #include "vtkVolume16Reader.h"
    #include "vtkImageData.h"
    #include "vtkPointData.h"
    #include "vtkPlaneSource.h"
    #include "vtkPlane.h"
    #include "vtkResliceCursorActor.h"
    #include "vtkResliceCursorPolyDataAlgorithm.h"
    #include "vtkResliceCursor.h"
    #include "vtkResliceCursorWidget.h"
    #include "vtkResliceCursorLineRepresentation.h"
    #include "vtkBiDimensionalWidget.h"

    #include "vtkTestUtilities.h"

    //----------------------------------------------------------------------------
    class vtkResliceCursorCallback : public vtkCommand
    {
    public:
    static vtkResliceCursorCallback *New()
    {
    return new vtkResliceCursorCallback;
    }

    void Execute(vtkObject *caller, unsigned long /*ev*/,
        void *callData) override
    {
        vtkImagePlaneWidget* ipw =
            dynamic_cast< vtkImagePlaneWidget* >(caller);
        if (ipw)
        {
            double* wl = static_cast<double*>(callData);
    
            if (ipw == this->IPW[0])
            {
                this->IPW[1]->SetWindowLevel(wl[0], wl[1], 1);
                this->IPW[2]->SetWindowLevel(wl[0], wl[1], 1);
            }
            else if (ipw == this->IPW[1])
            {
                this->IPW[0]->SetWindowLevel(wl[0], wl[1], 1);
                this->IPW[2]->SetWindowLevel(wl[0], wl[1], 1);
            }
            else if (ipw == this->IPW[2])
            {
                this->IPW[0]->SetWindowLevel(wl[0], wl[1], 1);
                this->IPW[1]->SetWindowLevel(wl[0], wl[1], 1);
            }
        }
    
        vtkResliceCursorWidget *rcw = dynamic_cast<
            vtkResliceCursorWidget * >(caller);
        if (rcw)
        {
            vtkResliceCursorLineRepresentation *rep = dynamic_cast<
                vtkResliceCursorLineRepresentation * >(rcw->GetRepresentation());
            vtkResliceCursor *rc = rep->GetResliceCursorActor()->
                GetCursorAlgorithm()->GetResliceCursor();
            for (int i = 0; i < 3; i++)
            {
                vtkPlaneSource *ps = static_cast< vtkPlaneSource * >(
                    this->IPW[i]->GetPolyDataAlgorithm());
                ps->SetNormal(rc->GetPlane(i)->GetNormal());
                ps->SetCenter(rc->GetPlane(i)->GetOrigin());
    
                // If the reslice plane has modified, update it on the 3D widget
                this->IPW[i]->UpdatePlacement();
    
                //std::cout << "Updating placement of plane: " << i << " " <<
                //  rc->GetPlane(i)->GetNormal()[0] << " " <<
                //  rc->GetPlane(i)->GetNormal()[1] << " " <<
                //  rc->GetPlane(i)->GetNormal()[2] << std::endl;
                //this->IPW[i]->GetReslice()->Print(cout);
                //rep->GetReslice()->Print(cout);
                //std::cout << "---------------------" << std::endl;
            }
        }
    
        // Render everything
        this->RCW[0]->Render();
    }
    
    vtkResliceCursorCallback() = default;
    vtkImagePlaneWidget* IPW[3];
    vtkResliceCursorWidget *RCW[3];
    

    };

    //----------------------------------------------------------------------------
    int main(int argc, char *argv[])
    {
    vtkSmartPointer reader =
    vtkSmartPointer::New();
    reader->SetDataDimensions(64, 64);
    reader->SetDataByteOrderToLittleEndian();
    reader->SetImageRange(1, 93);
    reader->SetDataSpacing(3.2, 3.2, 1.5);
    reader->SetFilePrefix("D:/programe/VTK/mhd/肝脏/1/062d1");
    reader->SetFilePattern("%s%30a.dcm");
    reader->ReleaseDataFlagOn();
    reader->SetDataMask(0x7fff);
    reader->Update();

    vtkSmartPointer<vtkOutlineFilter> outline =
        vtkSmartPointer<vtkOutlineFilter>::New();
    outline->SetInputConnection(reader->GetOutputPort());
    
    vtkSmartPointer<vtkPolyDataMapper> outlineMapper =
        vtkSmartPointer<vtkPolyDataMapper>::New();
    outlineMapper->SetInputConnection(outline->GetOutputPort());
    
    vtkSmartPointer<vtkActor> outlineActor =
        vtkSmartPointer<vtkActor>::New();
    outlineActor->SetMapper(outlineMapper);
    
    vtkSmartPointer<vtkRenderer> ren[4];
    
    vtkSmartPointer<vtkRenderWindow> renWin =
        vtkSmartPointer<vtkRenderWindow>::New();
    renWin->SetMultiSamples(0);
    
    for (int i = 0; i < 4; i++)
    {
        ren[i] = vtkSmartPointer<vtkRenderer>::New();
        renWin->AddRenderer(ren[i]);
    }
    
    vtkSmartPointer<vtkRenderWindowInteractor> iren =
        vtkSmartPointer<vtkRenderWindowInteractor>::New();
    iren->SetRenderWindow(renWin);
    
    vtkSmartPointer<vtkCellPicker> picker =
        vtkSmartPointer<vtkCellPicker>::New();
    picker->SetTolerance(0.005);
    
    vtkSmartPointer<vtkProperty> ipwProp =
        vtkSmartPointer<vtkProperty>::New();
    
    
    //assign default props to the ipw's texture plane actor
    vtkSmartPointer<vtkImagePlaneWidget> planeWidget[3];
    int imageDims[3];
    reader->GetOutput()->GetDimensions(imageDims);
    
    for (int i = 0; i < 3; i++)
    {
        planeWidget[i] = vtkSmartPointer<vtkImagePlaneWidget>::New();
        planeWidget[i]->SetInteractor(iren);
        planeWidget[i]->SetPicker(picker);
        planeWidget[i]->RestrictPlaneToVolumeOn();
        double color[3] = { 0, 0, 0 };
        color[i] = 1;
        planeWidget[i]->GetPlaneProperty()->SetColor(color);
        planeWidget[i]->SetTexturePlaneProperty(ipwProp);
        planeWidget[i]->TextureInterpolateOff();
        planeWidget[i]->SetResliceInterpolateToLinear();
        planeWidget[i]->SetInputConnection(reader->GetOutputPort());
        planeWidget[i]->SetPlaneOrientation(i);
        planeWidget[i]->SetSliceIndex(imageDims[i] / 2);
        planeWidget[i]->DisplayTextOn();
        planeWidget[i]->SetDefaultRenderer(ren[3]);
        planeWidget[i]->SetWindowLevel(1358, -27);
        planeWidget[i]->On();
        planeWidget[i]->InteractionOn();
    }
    
    planeWidget[1]->SetLookupTable(planeWidget[0]->GetLookupTable());
    planeWidget[2]->SetLookupTable(planeWidget[0]->GetLookupTable());
    
    
    vtkSmartPointer<vtkResliceCursorCallback> cbk =
        vtkSmartPointer<vtkResliceCursorCallback>::New();
    
    // Create the reslice cursor, widget and rep
    
    vtkSmartPointer< vtkResliceCursor > resliceCursor =
        vtkSmartPointer< vtkResliceCursor >::New();
    resliceCursor->SetCenter(reader->GetOutput()->GetCenter());
    resliceCursor->SetThickMode(0);
    resliceCursor->SetThickness(10, 10, 10);
    resliceCursor->SetImage(reader->GetOutput());
    
    vtkSmartPointer< vtkResliceCursorWidget > resliceCursorWidget[3];
    vtkSmartPointer< vtkResliceCursorLineRepresentation > resliceCursorRep[3];
    
    double viewUp[3][3] = { { 0, 0, -1 },{ 0, 0, 1 },{ 0, 1, 0 } };
    for (int i = 0; i < 3; i++)
    {
        resliceCursorWidget[i] = vtkSmartPointer< vtkResliceCursorWidget >::New();
        resliceCursorWidget[i]->SetInteractor(iren);
    
        resliceCursorRep[i] =
            vtkSmartPointer< vtkResliceCursorLineRepresentation >::New();
        resliceCursorWidget[i]->SetRepresentation(resliceCursorRep[i]);
        resliceCursorRep[i]->GetResliceCursorActor()->
            GetCursorAlgorithm()->SetResliceCursor(resliceCursor);
        resliceCursorRep[i]->GetResliceCursorActor()->
            GetCursorAlgorithm()->SetReslicePlaneNormal(i);
    
        const double minVal = reader->GetOutput()->GetScalarRange()[0];
        if (vtkImageReslice *reslice =
            vtkImageReslice::SafeDownCast(resliceCursorRep[i]->GetReslice()))
        {
            reslice->SetBackgroundColor(minVal, minVal, minVal, minVal);
        }
    
        resliceCursorWidget[i]->SetDefaultRenderer(ren[i]);
        resliceCursorWidget[i]->SetEnabled(1);
    
        ren[i]->GetActiveCamera()->SetFocalPoint(0, 0, 0);
        double camPos[3] = { 0,0,0 };
        camPos[i] = 1;
        ren[i]->GetActiveCamera()->SetPosition(camPos);
    
        ren[i]->GetActiveCamera()->ParallelProjectionOn();
        ren[i]->GetActiveCamera()->SetViewUp(
            viewUp[i][0], viewUp[i][1], viewUp[i][2]);
        ren[i]->ResetCamera();
        //ren[i]->ResetCameraClippingRange();
    
        // Tie the Image plane widget and the reslice cursor widget together
        cbk->IPW[i] = planeWidget[i];
        cbk->RCW[i] = resliceCursorWidget[i];
        resliceCursorWidget[i]->AddObserver(
            vtkResliceCursorWidget::ResliceAxesChangedEvent, cbk);
    
        // Initialize the window level to a sensible value
        double range[2];
        reader->GetOutput()->GetScalarRange(range);
        resliceCursorRep[i]->SetWindowLevel(range[1] - range[0], (range[0] + range[1]) / 2.0);
        planeWidget[i]->SetWindowLevel(range[1] - range[0], (range[0] + range[1]) / 2.0);
    
        // Make them all share the same color map.
        resliceCursorRep[i]->SetLookupTable(resliceCursorRep[0]->GetLookupTable());
        planeWidget[i]->GetColorMap()->SetLookupTable(resliceCursorRep[0]->GetLookupTable());
    }
    
    
    // Add the actors
    //
    ren[0]->SetBackground(0.3, 0.1, 0.1);
    ren[1]->SetBackground(0.1, 0.3, 0.1);
    ren[2]->SetBackground(0.1, 0.1, 0.3);
    ren[3]->AddActor(outlineActor);
    ren[3]->SetBackground(0.1, 0.1, 0.1);
    renWin->SetSize(600, 600);
    //renWin->SetFullScreen(1);
    
    ren[0]->SetViewport(0, 0, 0.5, 0.5);
    ren[1]->SetViewport(0.5, 0, 1, 0.5);
    ren[2]->SetViewport(0, 0.5, 0.5, 1);
    ren[3]->SetViewport(0.5, 0.5, 1, 1);
    
    // Set the actors' positions
    //
    renWin->Render();
    
    ren[3]->GetActiveCamera()->Elevation(110);
    ren[3]->GetActiveCamera()->SetViewUp(0, 0, -1);
    ren[3]->GetActiveCamera()->Azimuth(45);
    ren[3]->GetActiveCamera()->Dolly(1.15);
    ren[3]->ResetCameraClippingRange();
    
    vtkSmartPointer< vtkInteractorStyleImage > style =
        vtkSmartPointer< vtkInteractorStyleImage >::New();
    iren->SetInteractorStyle(style);
    
    iren->Initialize();
    
    
        iren->Start();
    
    
    return 0;
    

    }
    按照上面的指示,我只是轻微的修改了细微的几个地方而已,
    http://www.vtk.org/gitweb?p=VTK.git;a=blob_plain;f=Interaction/Widgets/Testing/Cxx/TestResliceCursorWidget2.cxx
    这是官网的代码,可是我的代码却运行不了呢?麻烦大家解答。

    点赞 打赏 评论

相关推荐 更多相似问题