Notes VTK - Classe de sonde vtkProbeFilter

Classe vtkProbeFiltervtkProbeFilter class

  vtkProbeFilterLa classe peut échantillonner la valeur de données à la position de point spécifiée et peut filtrer les données scalaires (valeur scalaire, valeur vectorielle) des données source à la position de point spécifiée. Il s'agit d'une classe de filtre ; la classe prend en charge deux types d'entrée, y compris la géométrievtkProbeFilter du filtre d'entrée et les données source à filtrer ; lors du calcul de la valeur de la position de point spécifiée, l'algorithme d'interpolation sera utilisé ; la classe copie les données source de chaque position de point spécifiée dans la sortie. La classe peut filtrer les données source transmises par un plan dans les données de volume tridimensionnelles, similaire à la fonction MPR ; la classe peut également rééchantillonner les données ou convertir un ensemble de données en un autre . Par exemple : Les grilles non structurées ( ) peuvent être sondées à l'aide de volumes (3D ) et les résultats visualisés à l'aide de techniques de rendu de volume. Ou sondez les données avec une ligne ou une courbe pour générer un tracé xy le long de cette ligne ou courbe. S'il s'agit d'une projection de surface de reconstruction de courbe, c'est la fonction de CPR ;vtkProbeFilter
  vtkProbeFilter
  vtkProbeFilterDataSetDataSetvtkImageDatavtkUnstructuredGrid
insérez la description de l'image ici

Figure 1 : Démo de la fonction que vtkProbeFilter peut réaliser

  vtkProbeFilterLes classes peuvent effectuer une reconstruction de section et une reconstruction de surface. Il convient de noter que vtkProbeFilterla sortie de la classe n'est pas vtkImageDatamais vtkDataSet; si vtkProbeFilterune classe reçoit un plan, elle produira le vtkImageReslicemême effet de rendu que la classe, si elle reçoit un ensemble de points irrégulier + topologie , il va générer une reconstruction de surface irrégulière ;

exemple

Exemple de site Web officiel CurvedReformation

namespace {
    
    
    vtkSmartPointer<vtkPolyData> SweepLine(vtkPolyData* line, double direction[3],
    	double distance, unsigned int cols);
}

int main(int, char*[])
{
    
    
    vtkNew<vtkNamedColors> colors;
    // Parse arguments
    std::string volumeFileName = "G:\\Data\\HeadMRVolume.mhd";
    std::string polyDataFileName = "G:\\Data\\polyline.vtk";;
    unsigned int resolution = 100;

    // Read the volume data
    vtkNew<vtkImageReader2Factory> imageFactory;
    vtkSmartPointer<vtkImageReader2> imageReader;
    imageReader.TakeReference(imageFactory->CreateImageReader2(volumeFileName.c_str()));
    imageReader->SetFileName(volumeFileName.c_str());
    imageReader->Update();

    // Read the Polyline
    vtkNew<vtkPolyDataReader> polyLineReader;
    polyLineReader->SetFileName(polyDataFileName.c_str());
    polyLineReader->Update();

    vtkNew<vtkSplineFilter> spline;
    spline->SetInputConnection(polyLineReader->GetOutputPort());
    spline->SetSubdivideToSpecified();
    spline->SetNumberOfSubdivisions(resolution);

    // Sweep the line to form a surface
    double direction[3];
    direction[0] = 0.0;
    direction[1] = 0.0;
    direction[2] = 1.0;
    double distance = 164;
    spline->Update();
    auto surface = SweepLine(spline->GetOutput(), direction, distance, 100);

    // Probe the volume with the extruded surface
    vtkNew<vtkProbeFilter> sampleVolume;
    sampleVolume->SetInputData(1, imageReader->GetOutput());
    sampleVolume->SetInputData(0, surface);

    // Compute a simple window/level based on scalar range
    vtkNew<vtkWindowLevelLookupTable> wlLut;
    double range = imageReader->GetOutput()->GetScalarRange()[1] -
        imageReader->GetOutput()->GetScalarRange()[0];
    double level = (imageReader->GetOutput()->GetScalarRange()[1] +
        imageReader->GetOutput()->GetScalarRange()[0]) / 2.0;
    wlLut->SetWindow(range);
    wlLut->SetLevel(level);

    // Create a mapper and actor.
    vtkNew<vtkDataSetMapper> mapper;
    mapper->SetInputConnection(sampleVolume->GetOutputPort());
    mapper->SetLookupTable(wlLut);
    mapper->SetScalarRange(0, 255);

    vtkNew<vtkActor> actor;
    actor->SetMapper(mapper);

    // Create a renderer, render window, and interactor
    vtkNew<vtkRenderer> renderer;
    vtkNew<vtkRenderWindow> renderWindow;
    renderWindow->AddRenderer(renderer);
    renderWindow->SetWindowName("CurvedReformation");

    vtkNew<vtkRenderWindowInteractor> renderWindowInteractor;
    renderWindowInteractor->SetRenderWindow(renderWindow);

    // Add the actors to the scene
    renderer->AddActor(actor);
    renderer->SetBackground(colors->GetColor3d("DarkSlateGray").GetData());

    // Set the camera for viewing medical images
    renderer->GetActiveCamera()->SetViewUp(0, 0, 1);
    renderer->GetActiveCamera()->SetPosition(0, 0, 0);
    renderer->GetActiveCamera()->SetFocalPoint(0, 1, 0);
    renderer->ResetCamera();

    // Render and interact
    renderWindow->Render();
    renderWindowInteractor->Start();
    return 0;
}

namespace {
    
    
    vtkSmartPointer<vtkPolyData> SweepLine(vtkPolyData* line, double direction[3],
        double distance, unsigned int cols)
    {
    
    
        unsigned int rows = line->GetNumberOfPoints();
        double spacing = distance / cols;
        vtkNew<vtkPolyData> surface;

        // Generate the points
        cols++;
        unsigned int numberOfPoints = rows * cols;
        unsigned int numberOfPolys = (rows - 1) * (cols - 1);
        vtkNew<vtkPoints> points;
        points->Allocate(numberOfPoints);
        vtkNew<vtkCellArray> polys;
        polys->Allocate(numberOfPolys * 4);

        double x[3];
        unsigned int cnt = 0;
        for (unsigned int row = 0; row < rows; row++) {
    
    
            for (unsigned int col = 0; col < cols; col++) {
    
    
                double p[3];
                line->GetPoint(row, p);
                x[0] = p[0] + direction[0] * col * spacing;
                x[1] = p[1] + direction[1] * col * spacing;
                x[2] = p[2] + direction[2] * col * spacing;
                points->InsertPoint(cnt++, x);
            }
        }
        // Generate the quads
        vtkIdType pts[4];
        for (unsigned int row = 0; row < rows - 1; row++) {
    
    
            for (unsigned int col = 0; col < cols - 1; col++) {
    
    
                pts[0] = col + row * (cols);
                pts[1] = pts[0] + 1;
                pts[2] = pts[0] + cols + 1;
                pts[3] = pts[0] + cols;
                polys->InsertNextCell(4, pts);
            }
        }
        surface->SetPoints(points);
        surface->SetPolys(polys);

        return surface;
    }
} // namespace

insérez la description de l'image iciinsérez la description de l'image iciinsérez la description de l'image ici
  Si l'affichage SweepLineretourné vtkPolygonDataest affiché sous forme de ligne, cela aura l'effet suivant :

vtkNew<vtkExtractEdges> extract;
extract->SetInputData(surface);
extract->Update();

vtkNew<vtkPolyDataMapper> mapper;
mapper->SetInputData(extract->GetOutput());

insérez la description de l'image ici
  Après avoir affiché l'entrée polyline.vtk, on constate que la grille blanche est générée par une courbe rouge dans une direction ;
insérez la description de l'image ici

lecture de codes

  fonction principale
  1. Utilisez vtkImageReader2la classe et vtkPolyDataReaderla classe pour interpréter respectivement le fichier HeadMRVolume.mhd/HeadMRVolume.rawet le fichierpolyline.vtk ; HeadMRVolume.mhd/HeadMRVolume.rawà l'intérieur se trouve un ensemble de séquences CT et le fichier polyline.vtkest le contenu de la structure géométrique de la polyligne ;
  2. Utilisez vtkSplineFilterl'interpolation de la polyligne pour générer une courbe ;
  3 . La méthode d'utilisation SweepLineest à partir de la courbe précédente , pour générer un vtkPolyDataobjet de surface, tel que la grille illustrée dans la figure ci-dessus ;
  4. Définissez vtkProbeFilterdeux entrées : l'entrée 0 est vtkPolyDatal'objet de surfacesurface ; l'entrée 1 est la source de donnéesimageReader->GetOutput() ; 5. Définir la classe de table de mappage
  en fonction de la plage des données de la source de données et ;   6. Définir et ;   7. Entrez le pipeline de rendu ;   ----------------------- ------------- ------------------------------------- ------------- ------------------------------------- ------------- -------------------- Méthode SweepLine   1. Calculer le nombre de lignes à générer comme le nombre de points sur la courbe , et obtenez la direction de la colonne en fonction de la somme deimageReader->GetOutput()vtkWindowLevelLookupTableSetWindowSetLevel
vtkDataSetMapperSetLookupTableSetScalarRange(0, 255)


  
surfaceline->GetNumberOfPoints()distancecolsspacing;
  2. Calculer surfacele nombre de points internes numberOfPointssous la forme rows * cols, et le nombre d'unités sous la forme (rows - 1) * (cols - 1);
  3. Générer vtkPointsdes objets de classe pointset vtkCellArraydes objets de classe polys;
  4. Traverser et générer les coordonnées des points de chaque ligne et colonne, et les placer dans points; chacun des quatre points adjacents constituent une unitéInsertNextCell(4, pts) ;
  5. Définir la somme surfacede l'objet ;   6. Renvoyez l'objet ; il balaye de la courbe dans une direction. S'il balaye de la courbe aux deux extrémités, le résultat est similaire à la fonction de CPR, mais le le résultat doit être placé sur un plan. Image dimensionnelle ;   convertir le résultat en un jeu de résultats, car la méthode utilise la courbe comme ligne Ligne et étend la colonne Col dans la direction ; selon les données 1, convertir le jeu de données ;SetPoints(points)SetPolys(polys)
surface
  SweepLine
vtkProbeFiltervtkImageDataSweepLinedirection

    vtkSmartPointer<vtkPolyData> final_poly = sampleVolume->GetPolyDataOutput();
    vtkSmartPointer<vtkImageData> final_image = vtkSmartPointer<vtkImageData>::New();
    final_image->SetDimensions(resolution + 1, resolution + 1, 1);
    final_image->AllocateScalars(VTK_DOUBLE, 1);
    final_image->SetSpacing(1, 1, 0);
    int *dims = final_image->GetDimensions();

    for (int y = 0; y < dims[1]; y++) {
    
    
        for (int x = 0; x < dims[0]; x++) {
    
    
            double *pixel = static_cast<double *>(final_image->GetScalarPointer(x, y, 0));
            double value = final_poly->GetPointData()->GetScalars()->GetTuple1(dims[0] * y + x);
            pixel[0] = value;
        }
    }

  L'image résultante est inclinée vers la droite ;
insérez la description de l'image ici

Exemple de site Web officiel TissueLens

#include <vtkSphere.h>
#include <vtkClipDataSet.h>
#include <vtkCylinder.h>
int main(int, char*[])
{
    
    
    vtkNew<vtkNamedColors> colors;

    std::array<unsigned char, 4> skinColor{
    
     {
    
    240, 184, 160, 255} };
    colors->SetColor("SkinColor", skinColor.data());
    std::array<unsigned char, 4> backColor{
    
     {
    
    255, 229, 200, 255} };
    colors->SetColor("BackfaceColor", backColor.data());
    std::array<unsigned char, 4> bkg{
    
     {
    
    51, 77, 102, 255} };
    colors->SetColor("BkgColor", bkg.data());

    // Read the volume data
    vtkNew<vtkMetaImageReader> reader;
    reader->SetFileName("G:\\Data\\vtk-examples-master\\src\\Testing\\Data\\FullHead.mhd");
    reader->Update();

    // An isosurface, or contour value of 500 is known to correspond to the
    // skin of the patient.
#ifdef USE_FLYING_EDGES
    vtkNew<vtkFlyingEdges3D> skinExtractor;
#else
    vtkNew<vtkMarchingCubes> skinExtractor;
#endif
    skinExtractor->SetInputConnection(reader->GetOutputPort());
    skinExtractor->SetValue(0, 1000);

    // Define a spherical clip function to clip the isosurface
    vtkNew<vtkSphere> clipFunction;
    clipFunction->SetRadius(50);
    clipFunction->SetCenter(73, 52, 15);

    // Clip the isosurface with a sphere
    vtkNew<vtkClipDataSet> skinClip;
    skinClip->SetInputConnection(skinExtractor->GetOutputPort());
    skinClip->SetClipFunction(clipFunction);
    skinClip->SetValue(0);
    skinClip->GenerateClipScalarsOn();
    skinClip->Update();

    vtkNew<vtkDataSetMapper> skinMapper;
    skinMapper->SetInputConnection(skinClip->GetOutputPort());
    skinMapper->ScalarVisibilityOff();

    vtkNew<vtkActor> skin;
    skin->SetMapper(skinMapper);
    skin->GetProperty()->SetDiffuseColor(colors->GetColor3d("SkinColor").GetData());

    vtkNew<vtkProperty> backProp;
    backProp->SetDiffuseColor(colors->GetColor3d("BackfaceColor").GetData());
    skin->SetBackfaceProperty(backProp);

    // Define a model for the "lens". Its geometry matches the implicit
    // sphere used to clip the isosurface
    vtkNew<vtkSphereSource> lensModel;
    lensModel->SetRadius(50);
    lensModel->SetCenter(73, 52, 15);
    lensModel->SetPhiResolution(100);
    lensModel->SetThetaResolution(100);
   

    // Sample the input volume with the lens model geometry
    vtkNew<vtkProbeFilter> lensProbe;
    lensProbe->SetInputConnection(lensModel->GetOutputPort());
    lensProbe->SetSourceConnection(reader->GetOutputPort());

    // Clip the lens data with the isosurface value
    vtkNew<vtkClipDataSet> lensClip;
    lensClip->SetInputConnection(lensProbe->GetOutputPort());
    lensClip->SetValue(500);
    lensClip->GenerateClipScalarsOff();
    lensClip->Update();

    // Define a suitable grayscale lut
    vtkNew<vtkLookupTable> bwLut;
    bwLut->SetTableRange(-600, 2048);
    bwLut->SetSaturationRange(0, 0);
    bwLut->SetHueRange(0, 0);
    bwLut->SetValueRange(0, 1);
    bwLut->Build();

    vtkNew<vtkDataSetMapper> lensMapper;
    lensMapper->SetInputConnection(lensClip->GetOutputPort());
    lensMapper->SetScalarRange(lensClip->GetOutput()->GetScalarRange());
    lensMapper->SetLookupTable(bwLut);

    vtkNew<vtkActor> lens;
    lens->SetMapper(lensMapper);

    // It is convenient to create an initial view of the data. The FocalPoint
    // and Position form a vector direction. Later on (ResetCamera() method)
    // this vector is used to position the camera to look at the data in
    // this direction.
    vtkNew<vtkCamera> aCamera;
    aCamera->SetViewUp(0, 0, -1);
    aCamera->SetPosition(0, -1, 0);
    aCamera->SetFocalPoint(0, 0, 0);
    aCamera->ComputeViewPlaneNormal();
    aCamera->Azimuth(30.0);
    aCamera->Elevation(30.0);

    // Create the renderer, the render window, and the interactor. The renderer
    // draws into the render window, the interactor enables mouse- and
    // keyboard-based interaction with the data within the render window.
    //
    vtkNew<vtkRenderer> aRenderer;
    vtkNew<vtkRenderWindow> renWin;
    renWin->AddRenderer(aRenderer);

    vtkNew<vtkRenderWindowInteractor> iren;
    iren->SetRenderWindow(renWin);

    // Actors are added to the renderer. An initial camera view is created.
    // The Dolly() method moves the camera towards the FocalPoint,
    // thereby enlarging the image.
    aRenderer->AddActor(lens);
    aRenderer->AddActor(skin);
    aRenderer->SetActiveCamera(aCamera);
    aRenderer->ResetCamera();
    aCamera->Dolly(1.5);

    // Set a background color for the renderer and set the size of the
    // render window (expressed in pixels).
    aRenderer->SetBackground(colors->GetColor3d("BkgColor").GetData());
    renWin->SetSize(640, 480);
    renWin->SetWindowName("TissueLens");

    // Note that when camera movement occurs (as it does in the Dolly()
    // method), the clipping planes often need adjusting. Clipping planes
    // consist of two planes: near and far along the view direction. The
    // near plane clips out objects in front of the plane; the far plane
    // clips out objects behind the plane. This way only what is drawn
    // between the planes is actually rendered.
    aRenderer->ResetCameraClippingRange();

    // Initialize the event loop and then start it.
    renWin->Render();
    iren->Initialize();
    iren->Start();

    return EXIT_SUCCESS;
}

lecture de codes

insérez la description de l'image ici
Lorsque le paramètre lensClipest SetValuedéfini sur 0, l'échelle de gris complète de l'hémisphère peut être affichée complètement. Lorsqu'il est défini sur 500, la valeur inférieure à 500 sera effacée ;
insérez la description de l'image ici
insérez la description de l'image ici

Lorsqu'un plan est composé de points et d'unités, une image plane en niveaux de gris + effet de rendu polygonal peut être générée, la limite inférieure de la valeur CT scalaire est contrainte
;vtkClipDataSet

#include <vtkSphere.h>
#include <vtkClipDataSet.h>
#include <vtkCylinder.h>
int main(int, char*[])
{
    
    
    vtkNew<vtkNamedColors> colors;

    std::array<unsigned char, 4> skinColor{
    
     {
    
    240, 184, 160, 255} };
    colors->SetColor("SkinColor", skinColor.data());
    std::array<unsigned char, 4> backColor{
    
     {
    
    255, 229, 200, 255} };
    colors->SetColor("BackfaceColor", backColor.data());
    std::array<unsigned char, 4> bkg{
    
     {
    
    51, 77, 102, 255} };
    colors->SetColor("BkgColor", bkg.data());

    // Read the volume data
    vtkNew<vtkMetaImageReader> reader;
    reader->SetFileName("G:\\Data\\vtk-examples-master\\src\\Testing\\Data\\FullHead.mhd");
    reader->Update();

    // An isosurface, or contour value of 500 is known to correspond to the
    // skin of the patient.
#ifdef USE_FLYING_EDGES
    vtkNew<vtkFlyingEdges3D> skinExtractor;
#else
    vtkNew<vtkMarchingCubes> skinExtractor;
#endif
    skinExtractor->SetInputConnection(reader->GetOutputPort());
    skinExtractor->SetValue(0, 1000);

    // Define a spherical clip function to clip the isosurface
    vtkNew<vtkSphere> clipFunction;
    clipFunction->SetRadius(50);
    clipFunction->SetCenter(73, 52, 15);

    // Clip the isosurface with a sphere
    vtkNew<vtkClipDataSet> skinClip;
    skinClip->SetInputConnection(skinExtractor->GetOutputPort());
    skinClip->SetClipFunction(clipFunction);
    skinClip->SetValue(0);
    skinClip->GenerateClipScalarsOn();
    skinClip->Update();

    vtkNew<vtkDataSetMapper> skinMapper;
    skinMapper->SetInputConnection(skinClip->GetOutputPort());
    skinMapper->ScalarVisibilityOff();

    vtkNew<vtkActor> skin;
    skin->SetMapper(skinMapper);
    skin->GetProperty()->SetDiffuseColor(
        colors->GetColor3d("SkinColor").GetData());

    vtkNew<vtkProperty> backProp;
    backProp->SetDiffuseColor(colors->GetColor3d("BackfaceColor").GetData());
    skin->SetBackfaceProperty(backProp);

    vtkSmartPointer<vtkPoints> gridPoints = vtkSmartPointer<vtkPoints>::New();
    vtkNew<vtkCellArray> polys;
    for (unsigned int x = 0; x < 200; x++)
    {
    
    
        for (unsigned int y = 0; y < 200; y++)
        {
    
    
            gridPoints->InsertNextPoint(30 + x, 30 + y, 15 + 0);
        }
    }

    vtkIdType pts[4];
    for (unsigned int row = 0; row < 200 - 1; row++) {
    
    
        for (unsigned int col = 0; col < 200 - 1; col++) {
    
    
            pts[0] = col + row * (200);
            pts[1] = pts[0] + 1;
            pts[2] = pts[0] + 200 + 1;
            pts[3] = pts[0] + 200;
            polys->InsertNextCell(4, pts);
        }
    }
   
    // Create a dataset from the grid points
    vtkSmartPointer<vtkPolyData> gridPolyData = vtkSmartPointer<vtkPolyData>::New();
    gridPolyData->SetPoints(gridPoints);
    gridPolyData->SetPolys(polys);

    // Sample the input volume with the lens model geometry
    vtkNew<vtkProbeFilter> lensProbe;
    lensProbe->SetInputData(gridPolyData);
    lensProbe->SetSourceConnection(reader->GetOutputPort());

    // Clip the lens data with the isosurface value
    vtkNew<vtkClipDataSet> lensClip;
    lensClip->SetInputConnection(lensProbe->GetOutputPort());
    lensClip->SetValue(500);
    lensClip->GenerateClipScalarsOff();
    lensClip->Update();

    // Define a suitable grayscale lut
    vtkNew<vtkLookupTable> bwLut;
    bwLut->SetTableRange(0, 2048);
    bwLut->SetSaturationRange(0, 0);
    bwLut->SetHueRange(0, 0);
    bwLut->SetValueRange(0, 1);
    bwLut->Build();

    vtkNew<vtkDataSetMapper> lensMapper;
    lensMapper->SetInputConnection(lensClip->GetOutputPort());
    lensMapper->SetScalarRange(lensClip->GetOutput()->GetScalarRange());
    lensMapper->SetLookupTable(bwLut);

    vtkNew<vtkActor> lens;
    lens->SetMapper(lensMapper);

    // It is convenient to create an initial view of the data. The FocalPoint
    // and Position form a vector direction. Later on (ResetCamera() method)
    // this vector is used to position the camera to look at the data in
    // this direction.
    vtkNew<vtkCamera> aCamera;
    aCamera->SetViewUp(0, 0, -1);
    aCamera->SetPosition(0, -1, 0);
    aCamera->SetFocalPoint(0, 0, 0);
    aCamera->ComputeViewPlaneNormal();
    aCamera->Azimuth(30.0);
    aCamera->Elevation(30.0);

    // Create the renderer, the render window, and the interactor. The renderer
    // draws into the render window, the interactor enables mouse- and
    // keyboard-based interaction with the data within the render window.
    //
    vtkNew<vtkRenderer> aRenderer;
    vtkNew<vtkRenderWindow> renWin;
    renWin->AddRenderer(aRenderer);

    vtkNew<vtkRenderWindowInteractor> iren;
    iren->SetRenderWindow(renWin);

    // Actors are added to the renderer. An initial camera view is created.
    // The Dolly() method moves the camera towards the FocalPoint,
    // thereby enlarging the image.
    aRenderer->AddActor(lens);
    aRenderer->AddActor(skin);
    aRenderer->SetActiveCamera(aCamera);
    aRenderer->ResetCamera();
    aCamera->Dolly(1.5);

    // Set a background color for the renderer and set the size of the
    // render window (expressed in pixels).
    aRenderer->SetBackground(colors->GetColor3d("BkgColor").GetData());
    renWin->SetSize(640, 480);
    renWin->SetWindowName("TissueLens");

    // Note that when camera movement occurs (as it does in the Dolly()
    // method), the clipping planes often need adjusting. Clipping planes
    // consist of two planes: near and far along the view direction. The
    // near plane clips out objects in front of the plane; the far plane
    // clips out objects behind the plane. This way only what is drawn
    // between the planes is actually rendered.
    aRenderer->ResetCameraClippingRange();

    // Initialize the event loop and then start it.
    renWin->Render();
    iren->Initialize();
    iren->Start();

    return EXIT_SUCCESS;
}

insérez la description de l'image ici

Les références

1. Tranche de reconstruction bidimensionnelle vtk II
2. CurvedReformation
3. Référence de classe vtkProbeFilter
4. TissueLens

Je suppose que tu aimes

Origine blog.csdn.net/liushao1031177/article/details/122860254
conseillé
Classement