VTK_Learning_vtkMarchingCubes

1.vtkMarchingCubes读取骨骼和皮肤

 

 

2.代码

#include <QCoreApplication>
#include <QDebug>
#include <iostream>
#include <sstream>
#include <QtCore>
#include <QMainWindow>
#include <QWidget>

#include <QGuiApplication>
#include <QQuickView>
#include <QtQml>
#include <QQmlApplicationEngine>


//vtk
#include <vtkActor.h>
#include <vtkCamera.h>
#include <vtkCylinderSource.h>
#include <vtkNamedColors.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>


#include <array>

#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkRenderingFreeType);
VTK_MODULE_INIT(vtkInteractionStyle);

//dicom
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkDICOMImageReader.h"
#include "vtkMarchingCubes.h"
#include "vtkStripper.h"
#include "vtkPolyDataMapper.h"
#include "vtkActor.h"
#include "vtkSmartPointer.h"
#include "vtkProperty.h"
#include "vtkCamera.h"
#include "vtkOutlineFilter.h"
#include "vtkOBJExporter.h"


int main(int argc, char *argv[])
{
        QGuiApplication app(argc, argv);
        vtkSmartPointer<vtkRenderer>ren=vtkSmartPointer<vtkRenderer>::New();             //设置绘制者(绘制对象指针)
        vtkSmartPointer<vtkRenderWindow>renWin=vtkSmartPointer<vtkRenderWindow>::New();         //设置绘制窗口
        renWin->AddRenderer(ren);                                 //将绘制者加入绘制窗口

        vtkSmartPointer<vtkRenderWindowInteractor>iren=vtkSmartPointer<vtkRenderWindowInteractor>::New();//设置绘制交互操作窗口的
        iren->SetRenderWindow(renWin);                             //将绘制窗口添加到交互窗口

        vtkSmartPointer<vtkDICOMImageReader>Reader=vtkSmartPointer<vtkDICOMImageReader>::New(); //创建读取dicom图片指针对象
        Reader->SetDirectoryName("../../sunguihua/SGH"); //设置医学图像文件夹路径
        Reader->SetDataByteOrderToLittleEndian();
        Reader->Update();
        cout<<"读取数据完成"<<endl;

        //
        vtkSmartPointer<vtkMarchingCubes>marchingcube=vtkSmartPointer<vtkMarchingCubes>::New();       //建立一个Marching Cubes 算法的对象
        //marchingcube->SetInput((vtkDataSet *)Reader->GetOutput());      //获得所读取的数据
        marchingcube->SetInputConnection(Reader->GetOutputPort());      //第二种读取数据的方法
        marchingcube->SetValue(0,-700);  //-700 1400                                //提取出灰度值为45的东西
        marchingcube->Update();


        vtkSmartPointer<vtkStripper>Stripper=vtkSmartPointer<vtkStripper>::New();                   //建立三角带对象
        Stripper->SetInputConnection( marchingcube->GetOutputPort());              //将生成的三角片连接成三角带

        vtkSmartPointer<vtkPolyDataMapper>Mapper=vtkSmartPointer<vtkPolyDataMapper>::New();   //建立一个数据映射对象
        Mapper->SetInputConnection(Stripper->GetOutputPort() );            //将三角带映射为几何数据
        Mapper->ScalarVisibilityOff();

        vtkSmartPointer<vtkActor>actor=vtkSmartPointer<vtkActor>::New();                            //建立一个代表皮肤的演员
        actor->SetMapper(Mapper);                                  //获得皮肤几何数据的属性
        actor->GetProperty()->SetDiffuseColor(1, .49, .25);            //设置皮肤颜色的属性//(1, .49, .25)
        //actor->GetProperty()->SetDiffuseColor(1, 1, .25);
        actor->GetProperty()->SetSpecular(0.3);                         //设置反射率
        actor->GetProperty()->SetSpecularPower(20);                    //设置反射光强度
        actor->GetProperty()->SetOpacity(1.0);
        actor->GetProperty()->SetColor(1,0,0);                 //设置角色的颜色
        actor->GetProperty()->SetRepresentationToWireframe();


        vtkSmartPointer<vtkCamera>aCamera=vtkSmartPointer<vtkCamera>::New();     // 创建摄像机
        aCamera->SetViewUp ( 0, 0, -1 );        //设置相机的“上”方向
        aCamera->SetPosition ( 0, 1, 0 );       //位置:世界坐标系,设置相机位置
        aCamera->SetFocalPoint( 0, 0, 0 );     //焦点:世界坐标系,控制相机方向
        aCamera->ComputeViewPlaneNormal();     //重置视平面法向,基于当前的位置和焦点。否则会出现斜推剪切效果

        ///
        vtkSmartPointer<vtkOutlineFilter>outlinefilter=vtkSmartPointer<vtkOutlineFilter>::New();
        outlinefilter->SetInputConnection(Reader->GetOutputPort());

        vtkSmartPointer<vtkPolyDataMapper>outlineMapper=vtkSmartPointer<vtkPolyDataMapper>::New();
        outlineMapper->SetInputConnection(outlinefilter->GetOutputPort());

        vtkSmartPointer<vtkActor>OutlineActor=vtkSmartPointer<vtkActor>::New();
        OutlineActor->SetMapper(outlineMapper);
        OutlineActor->GetProperty()->SetColor(0,0,0);
        // 告诉绘制者将要在绘制窗口中进行显示的演员
        ren->AddActor(actor);
        ren->AddActor(OutlineActor);

        ren->SetActiveCamera(aCamera);               设置渲染器的相机
        ren->ResetCamera();
        aCamera->Dolly(1.5);                //使用Dolly()方法沿着视平面法向移动相机,实现放大或缩小可见角色物体
        ren->SetBackground(1,1,1);               //设置背景颜色
        //ren->ResetCameraClippingRange();
        renWin->SetSize(1000, 600);
        renWin->Render();
        iren->Initialize();
        iren->Start();


    return app.exec();
}

问题:

(1)stripple 的输出仍然是网格,没有连接成面?mapper的输入可以是marchingcube或者stripple。

(2)骨骼的灰度值是140,皮肤的灰度值是-700

3.从MarchingCube中读取点集数据,存储到.xyz文件

        //获得点集
        vtkSmartPointer<vtkPolyData> source =
            vtkSmartPointer<vtkPolyData>::New();
        source->SetPoints(marchingcube->GetOutput()->GetPoints());

        char *path = "../../DCM_points/sunguihua.xyz";
        std::ofstream out;
        out.open(path);
        std::cout<<"Export "<< path << "...\n";
        for(auto i=0 ;i<source->GetNumberOfPoints();i++)
        {
            double test[3];
            marchingcube->GetOutput()->GetPoint(i, test);
            //source->GetPoint(i, test);
            std::cout<<test[0]<<" "<<test[1]<<" "<<test[2]<<std::endl;
            out<<test[0]<<" "<<test[1]<<" "<<test[2]<<std::endl;
        }

        std::cout<<source->GetNumberOfPoints()<<std::endl;
        out.close();
        std::cout<<"exportXYZ finished..."<<std::endl;

4.从.xyz中读取数据存储到vector中。(一行有三个数据或超过3个数据)

void RegistrationPointCloud::getVectorFieldData(std::string DataPath, std::vector<std::vector<float>> &tempMatrix)
{
    std::ifstream infile_v(DataPath);
    std::vector<float> temp_line;
    std::string line;
    tempMatrix.clear();
    temp_line.clear();
    float temp{};
    while (getline(infile_v, line)) {  //按行读取
        std::stringstream lineTxt{};
        lineTxt << line;
//        while (lineTxt >> temp) {
//            std::cout << temp << " ";
//            temp_line.push_back(temp);  //将数据转化为int型并存入一维vector中
//        }
        int count=3;
        while ((lineTxt >> temp)&&(count--)) {
            std::cout << temp << " ";
            temp_line.push_back(temp);  //将数据转化为int型并存入一维vector中
        }


        std::cout << endl;
        tempMatrix.push_back(temp_line);  //保存所有数据
        temp_line.clear();
    }
    cout << endl << endl;
}

5.vector中的点数据,转化为VTK的polydata数据

void RegistrationPointCloud::writeDataToVtk(vtkSmartPointer<vtkPolyData> &polydata, std::vector<std::vector<float>> &tempMatrix,std::string dataOutPutPath, bool isSave)
{
    //创建几何数据,没有拓扑数据
        vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
        for(auto temp:tempMatrix)
        {
            points->InsertNextPoint(temp[0],temp[1],temp[2]);
        }
        //把几何数据(拓扑数据为空)放入到某个数据集中
        polydata = vtkSmartPointer<vtkPolyData>::New();
        polydata->SetPoints(points);

       //将polydata类型的数据写到一个vtk文件中

      if(isSave)
      {
          vtkSmartPointer<vtkPolyDataWriter> writer = vtkSmartPointer<vtkPolyDataWriter>::New();
          writer->SetFileName(dataOutPutPath.c_str());
          writer->SetInputData(polydata);
          writer->Write();
      }
}

6.VOI提取Dicm的一片区域

#include <vtkExtractVOI.h>
        voi
        /**
        * @brief 提取体中感兴趣的某一区域块*/

          vtkSmartPointer<vtkExtractVOI> extractVOI =
              vtkSmartPointer<vtkExtractVOI>::New();
          extractVOI->SetInputConnection(Reader->GetOutputPort());
          int* dim = Reader->GetOutput()->GetDimensions();
          std::cout << "Dims: " << " x: " << dim[0]
                                  << " y: " << dim[1]
                                  << " z: " << dim[2] << std::endl;
          extractVOI->SetVOI(0,4.*dim[0]/4-1,3*dim[1]/4,4.*dim[1]/4.-1,0,4.*dim[2]/4-1);
          extractVOI->Update();


        //
        vtkSmartPointer<vtkMarchingCubes>marchingcube=vtkSmartPointer<vtkMarchingCubes>::New();       //建立一个Marching Cubes 算法的对象
        //marchingcube->SetInput((vtkDataSet *)Reader->GetOutput());      //获得所读取的数据
        marchingcube->SetInputConnection(extractVOI->GetOutputPort());      //第二种读取数据的方法
        marchingcube->SetValue(0,-700);     //-500                             //提取出灰度值为45的东西
        marchingcube->Update();

7.对VOI做处理,去除不连续的区域,使脸部的点云数据只有一层

#include <vtkPolyDataConnectivityFilter.h>
 // To remain largest region
       vtkSmartPointer<vtkPolyDataConnectivityFilter> confilter =
         vtkSmartPointer<vtkPolyDataConnectivityFilter>::New();
       confilter->SetInputConnection(marchingcube->GetOutputPort());
       confilter->SetExtractionModeToClosestPointRegion();
       confilter->Update();
      //获得点集

      vtkSmartPointer<vtkPolyData> targ =
          vtkSmartPointer<vtkPolyData>::New();
      targ->SetPoints(confilter->GetOutput()->GetPoints());

 

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值