VTK&mimics Calcular Peças

Prefácio: Este blog post estuda principalmente o método adotado por Calculate Parts em imitações e o método de reconstrução 3D em VTK. Espero que seja útil a todos, obrigado!

imita-Calcular peças - Interpolação

Interpolação cinza

A interpolação de valores de cinza é uma verdadeira interpolação 3D, que leva em consideração parte do efeito de volume, por isso é mais precisa. Usando um método de interpolação de valores de cinza, assumimos que a densidade óssea dá uma indicação da quantidade de osso dentro de um pixel. Determina todas as arestas da superfície a partir de valores em tons de cinza. Além disso, a posição entre esses dois pixels é baseada no valor de cinza desses dois pixels.

A vantagem da interpolação de valores de cinza é que ela fornece muitos detalhes e é de tamanho correto. A desvantagem é que você obtém detalhes desnecessários devido ao ruído na imagem. Tomando o osso da coxa como exemplo, você obtém melhores resultados (ou seja: uma bela borda arredondada) ao interpolar com esse valor em tons de cinza. Claro, você também precisará fazer alguma suavização para reduzir o ruído.

No entanto, é importante perceber que a interpolação de valores de cinza nem sempre produz bons resultados. Quando a distância do corte digitalizado desvia significativamente da espessura do corte, a superfície da malha resultante será ruidosa. A interpolação de valores de cinza funciona bem somente quando a espessura e a distância da fatia são as mesmas. Esta condição deve ser atendida durante a digitalização (aquisição). Portanto, uma alteração na resolução Z (consulte o parágrafo sobre redução de matriz) não deve ser usada em conjunto com a interpolação de valores de cinza. Reduzir a resolução XY não viola esta condição.

A interpolação de valores de cinza é recomendada para aplicações de tecnologia CT.

Interpolação de Contorno

​​​​​

 A interpolação de contorno é uma interpolação bidimensional que se estende suavemente ao espaço tridimensional no plano da imagem. Este algoritmo de interpolação usa interpolação de valor em escala de cinza dentro da fatia, mas interpolação linear entre contornos na direção Z (como mostrado na imagem abaixo). Este método de interpolação fornece os melhores resultados para fins médicos.

vtkContourFilter

Descrição: vtkContourFilter é um filtro que aceita qualquer conjunto de dados como entrada e isosuperfícies ou contornos de saída. A forma da saída depende da dimensionalidade dos dados de entrada. Se os dados de entrada contiverem células 3D, a isosurface de saída. Se os dados de entrada contiverem células 2D, os contornos de saída. Da mesma forma, se os dados de entrada contiverem 1D ou 0D, a saída etc. ponteiros. Tipos mistos podem ser produzidos se as dimensões de entrada forem mistas.

ComputeNormal(): Cálculo de Set/Get normal. Computar normais consome bastante tempo e memória. Se os dados de saída forem processados ​​por filtros que modificam a topologia ou a geometria, pode ser uma boa ideia desativar normais e gradientes. O padrão dessa configuração é On para entradas vtkImageData, vtklineargrid, vtkStructuredGrid e vtkUnstructuredGrid e Off para todas as outras entradas.

vtkSynchronizedTemplates3D

Descrição: Usado para gerar isosuperfícies a partir de dados estruturais. vtkSynchronizedTemplates3D é uma implementação 3D do algoritmo Synchronized Templates. Observe que vtkContourFilter usará automaticamente essa classe quando apropriado. Esta interface é apenas para imagens 3D.

A função principal é ContourImage

Encontre o limite do contorno de acordo com a imagem e o valor do contorno definido;

De acordo com o ponto adicionado e sua localização, estabeleça uma relação topológica (a relação topológica é baseada em duas Tabelas);

Se a imagem de entrada for uma imagem multivalor, ou seja, não for uma imagem binária, os pontos adicionados serão interpolados;

código de teste

#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;
            }
        }
    }
}


Acho que você gosta

Origin blog.csdn.net/qq_40041064/article/details/130643148
Recomendado
Clasificación