VTK&mimics Calculate Parts

前言:本博文主要研究mimics中Calculate Parts所采用的方法以及VTK中三维重建的方法,希望对各位小伙伴有所帮助,谢谢!

mimics-Calculate parts - Interpolation

Gray Interpolation

灰度值插值是一种真正的3D插值,它考虑了部分体积效应,因此更准确。使用灰度值插值方法,我们假设骨密度给出了一个像素内骨骼数量的指示。根据灰度值确定表面的所有边缘。另外,这两个像素之间的位置是基于这两个像素的灰度值。

灰度值插值的优点是它提供了大量的细节和尺寸是正确的。缺点是,你得到不必要的细节,由于在图像中的噪声。以大腿骨为例,当使用这个灰度值插值时,你会得到更好的结果(意思是:一个很好的圆润边缘)。当然,你也需要做一些平滑来减少噪音。

然而,重要的是要认识到,灰度值插值并不总是产生良好的结果。当扫描的切片距离明显偏离切片厚度时,得到的网格表面会产生噪声。只有当切片厚度和切片距离相同时,灰度值插值才能很好地工作。在扫描(采集)过程中应满足此条件。因此,Z分辨率的变化(参见关于矩阵缩减的段落)不应与灰度值插值结合使用。降低XY分辨率并不违反该条件。

灰度值插值建议用于CT技术应用。

Contour Interpolation

​​​​​​​

 轮廓插值是在图像平面上平滑扩展到三维空间的二维插值。该插值算法在切片内使用灰度值插值,但在Z方向上使用轮廓之间的线性插值(如下图所示)。这种插值方法为医疗目的提供了最好的结果。

vtkContourFilter

描述:vtkContourFilter是一个过滤器,接受任何数据集的输入并输出等值面或等值线。输出的形式取决于输入数据的维数。若输入数据包含3D单元,则输出等值面。若输入数据包含2D单元,则输出等值线。同样的,若输入数据包含1D或0D,则输出等指点。如果输入维度为混合的,则可以输出混合类型。

ComputeNormal():Set/Get法线的计算。计算法线相当耗费时间和内存。如果输出数据将由修改拓扑或几何的过滤器处理,那么关闭法线和梯度可能是明智的。对于vtkImageData, vtklineargrid, vtkStructuredGrid和vtkUnstructuredGrid输入,此设置默认为On,而对于所有其他输入则为Off。

vtkSynchronizedTemplates3D

描述:用于从结构数据生成等值面。vtkSynchronizedTemplates3D是同步模板算法的3D实现。注意,vtkContourFilter将在适当的时候自动使用这个类。该接口只针对3D图像。

核心函数为ContourImage

根据Image以及设定的Contour值,寻找Contour的边界;

根据添加的点以及所在的位置,建立拓扑关系(拓扑关系基于两个Table进行);

若输入图像为多值图像,即不是二值图像,添加的点会进行插值;

测试代码

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

#include "vtkSmartPointer.h"

#include "vtkCamera.h"
#include "vtkDoubleArray.h"
#include "vtkImageData.h"
#include "vtkImageProperty.h"
#include "vtkImageReslice.h"
#include "vtkImageSincInterpolator.h"
#include "vtkImageSlice.h"
#include "vtkImageSliceMapper.h"
#include "vtkInteractorStyleImage.h"
#include "vtkPNGReader.h"
#include "vtkPointData.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkRenderer.h"

#include "vtkTestUtilities.h"
#include <vtkImageData.h>
#include <vtkMetaImageReader.h>
#include <vtkContourFilter.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkSTLWriter.h>
#include <vtkSTLReader.h>
#include <vtkPolyDataNormals.h>
#include <vtkStripper.h>
#include <vtkXMLPolyDataReader.h>
#include <vtkImageResliceMapper.h>

#include "zxContourFilter.h"

void CreateColorImage(vtkImageData* image);

int main()
{

    vtkSmartPointer<vtkImageData> image = vtkSmartPointer<vtkImageData>::New();
    CreateColorImage(image);

    zxContourFilter* filter = zxContourFilter::New();
    filter->SetInputData(image);
    filter->SetValue(0, 4);
    //filter->GenerateValues(3, -10., 10.);
    filter->Update();

    vtkSTLWriter* writer = vtkSTLWriter::New();
    writer->SetFileName("F:\\contourPolyData.stl");
    writer->SetInputData(filter->GetOutput());
    writer->Write();

    /*vtkPolyDataNormals* normals = vtkPolyDataNormals::New();
    normals->SetInputData(filter->GetOutput());
    normals->SetFeatureAngle(60);
    normals->SetComputePointNormals(true);
    normals->Update();

    vtkSTLWriter* writer2 = vtkSTLWriter::New();
    writer2->SetFileName("F:\\contourNormals.stl");
    writer2->SetInputData(normals->GetOutput());
    writer2->Write();

    vtkStripper* stripper = vtkStripper::New();
    stripper->SetInputData(normals->GetOutput());
    stripper->Update();*/

    /*vtkSTLWriter* writer3 = vtkSTLWriter::New();
    writer3->SetFileName("F:\\contourStripper.stl");
    writer3->SetInputData(stripper->GetOutput());
    writer3->Write();*/

    vtkPolyDataMapper* contourMapper = vtkPolyDataMapper::New();
    contourMapper->SetInputData(filter->GetOutput());
    vtkActor* contourActor = vtkActor::New();
    contourActor->SetMapper(contourMapper);

    // Setup renderers
    vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
    //renderer->AddViewProp(imageSlice);
    renderer->AddActor(contourActor);
    renderer->ResetCamera();

    // Setup render window
    vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
    renderWindow->SetSize(300, 300);
    renderWindow->AddRenderer(renderer);

    // Setup render window interactor
    vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
        vtkSmartPointer<vtkRenderWindowInteractor>::New();

    vtkSmartPointer<vtkInteractorStyleTrackballCamera> style =
        vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();

    renderWindowInteractor->SetInteractorStyle(style);

    // Render and start interaction
    renderWindowInteractor->SetRenderWindow(renderWindow);
    renderWindow->Render();
    renderWindowInteractor->Initialize();

    renderWindowInteractor->Start();

    return EXIT_SUCCESS;
}

void CreateColorImage(vtkImageData* image)
{
    int directSize = 7;
    int zSize = 5;
    image->SetDimensions(directSize, directSize, zSize);
    image->AllocateScalars(VTK_UNSIGNED_CHAR, 1);

    for (unsigned int z = 0; z < zSize; z++)
    {
        for (unsigned int y = 0; y < directSize; y++)
        {
            for (unsigned int x = 0; x < directSize; x++)
            {
                unsigned char* pixel = static_cast<unsigned char*>(image->GetScalarPointer(x, y, z));
                pixel[0] = 0;
            }
        }
    }
    for (unsigned int z = 1; z < 5; z++)
    {
        for (unsigned int y = z; y < directSize -z; y++)
        {
            for (unsigned int x = z; x < directSize - z; x++)
            {
                unsigned char* pixel = static_cast<unsigned char*>(image->GetScalarPointer(x, y, z));
                pixel[0] = 4;
            }
        }
    }
}


猜你喜欢

转载自blog.csdn.net/qq_40041064/article/details/130643148