VTK ノート - vtkProbeFilter プローブ クラス

vtkProbeFilter クラス

  vtkProbeFiltervtkProbeFilterこのクラスは、指定されたポイントでデータ値をサンプリングし、指定されたポイントでソース データのスカラー データ (スカラー値、ベクトル値) をフィルター処理することができるフィルター クラスです。このクラスは、入力フィルター ジオメトリと入力フィルタージオメトリを含む 2 種類の入力をサポートしますフィルタリングされるソース データ。指定されたポイント位置の値を計算するときに、内挿アルゴリズムが使用されます。vtkProbeFilterクラスは、指定された各ポイント位置のソース データを出力にコピーします。
  vtkProbeFilterこのクラスは、MPR 関数と同様に、3D ボリューム データ内のプレーンによって渡されるソース データをフィルター処理できます。
  vtkProbeFilterまた、データをリサンプリングしたり、あるデータDataSetセットを別のデータ セットに変換したりすることもできますDataSetvtkImageData例:非構造化グリッド ( ) はボリューム (3D) を使用して調査できvtkUnstructuredGrid、結果はボリューム レンダリング技術を使用して視覚化できます。または、線または曲線を使用してデータをプローブし、その線または曲線に沿って xy プロットを生成します。曲線再構成面投影の場合、それは CPR の機能です。
ここに画像の説明を挿入

図1: vtkProbeFilterが実現できる機能デモ

  vtkProbeFiltervtkProbeFilterクラスはセクションの再構成と表面の再構成を実現できます。クラスの出力はそうではないvtkImageDataことに注意してください。クラスに平面が与えられたvtkDataSet場合、不規則な点セットが与えられた場合は、クラスと同じレンダリング効果が生成されます。 + トポロジー、不規則な表面の再構築を生成します。vtkProbeFiltervtkImageReslice

公式サイト 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

ここに画像の説明を挿入ここに画像の説明を挿入ここに画像の説明を挿入
SweepLine返されたvtkPolygonData表示が行として表示される   場合、次のような影響があります。

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

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

ここに画像の説明を挿入
  入力を表示するとpolyline.vtk、白いグリッドが一方向の赤い曲線によって生成されていることがわかります。
ここに画像の説明を挿入

コードの読み取り

  main 関数
  1.vtkImageReader2クラスとvtkPolyDataReaderクラスを使用してファイルHeadMRVolume.mhd/HeadMRVolume.rawとファイルをそれぞれ解釈しますpolyline.vtkHeadMRVolume.mhd/HeadMRVolume.raw内部には CT シーケンスのセットがあり、ファイルはpolyline.vtkポリラインの幾何学的構造のコンテンツです。2.ポリラインの補間を
  使用して曲線を生成します   。3.使用方法は前のカーブからのもので、上の図に示すグリッドなどのサーフェス オブジェクトを生成します   。4. 2 つの入力を設定します: 入力 0 はサーフェス オブジェクト、入力 1 はデータ ソースです。5 .設定します。   データ ソース データの範囲に応じてマッピング テーブルクラスを設定し;   6.設定し;   7. レンダリング パイプラインを開始します;   ----------------------- ------------------------ -------------------------------------------- ------------------------ -------------------------------------------- ------------- ------------------------ SweetLine メソッド   1.生成する行数を計算する曲線上の点の数として を取得次の合計に従って列の方向を取得します。vtkSplineFilter
SweepLinevtkPolyData
vtkProbeFiltervtkPolyDatasurfaceimageReader->GetOutput()
imageReader->GetOutput()vtkWindowLevelLookupTableSetWindowSetLevel
vtkDataSetMapperSetLookupTableSetScalarRange(0, 255)


  
surfaceline->GetNumberOfPoints()distancecolsspacing;
  2.surface内部点の数を、ユニットの数を としてnumberOfPoints計算します;   3.クラス オブジェクトクラス オブジェクトを生成します;   4. 各行と列の点座標をトラバースして生成し、それらを ; に入力します; それぞれ隣接する 4 つの点ユニットを構成する5.オブジェクトの合計   を設定する   6.オブジェクトを返す; カーブから一方向にスキャンします。カーブから両端までスキャンすると、結果は CPR の機能と似ていますが、結果を平面上に配置する必要があります。次元画像。   このメソッドでは曲線を行 Row として使用し、Col 列を方向に拡張するため、結果を結果セットに変換します。データ 1 に従って、データ セットを変換しますrows * cols(rows - 1) * (cols - 1)
vtkPointspointsvtkCellArraypolys
pointsInsertNextCell(4, pts)
surfaceSetPoints(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;
        }
    }

  結果の画像は右に傾きます。
ここに画像の説明を挿入

公式ウェブサイト 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;
}

コードの読み取り

ここに画像の説明を挿入
設定lensClipSetValue0 にすると半球のグレースケールを完全に表示でき、500 に設定すると 500 未満の値は消去され、500 に設定すると 500 未満の値が消去されます。
ここに画像の説明を挿入
ここに画像の説明を挿入

平面が点とユニットで構成されている場合、平面のグレースケール画像 + ポリゴンのレンダリング効果を生成できます;スカラー CT 値の下限には制約があります
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;
}

ここに画像の説明を挿入

参考文献

1. vtk 2 次元再構成スライス II
2. CurvedReformation
3. vtkProbeFilter クラス リファレンス
4. TissueLens

おすすめ

転載: blog.csdn.net/liushao1031177/article/details/122860254