vtkProbeFilter クラス
vtkProbeFilter
vtkProbeFilter
このクラスは、指定されたポイントでデータ値をサンプリングし、指定されたポイントでソース データのスカラー データ (スカラー値、ベクトル値) をフィルター処理することができるフィルター クラスです。このクラスは、入力フィルター ジオメトリと入力フィルタージオメトリを含む 2 種類の入力をサポートします。フィルタリングされるソース データ。指定されたポイント位置の値を計算するときに、内挿アルゴリズムが使用されます。vtkProbeFilter
クラスは、指定された各ポイント位置のソース データを出力にコピーします。
vtkProbeFilter
このクラスは、MPR 関数と同様に、3D ボリューム データ内のプレーンによって渡されるソース データをフィルター処理できます。
vtkProbeFilter
また、データをリサンプリングしたり、あるデータDataSet
セットを別のデータ セットに変換したりすることもできますDataSet
。vtkImageData
例:非構造化グリッド ( ) はボリューム (3D) を使用して調査できvtkUnstructuredGrid
、結果はボリューム レンダリング技術を使用して視覚化できます。または、線または曲線を使用してデータをプローブし、その線または曲線に沿って xy プロットを生成します。曲線再構成面投影の場合、それは CPR の機能です。
vtkProbeFilter
vtkProbeFilter
クラスはセクションの再構成と表面の再構成を実現できます。クラスの出力はそうではないvtkImageData
ことに注意してください。クラスに平面が与えられたvtkDataSet
場合、不規則な点セットが与えられた場合は、クラスと同じレンダリング効果が生成されます。 + トポロジー、不規則な表面の再構築を生成します。vtkProbeFilter
vtkImageReslice
例
公式サイト 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.vtk
。HeadMRVolume.mhd/HeadMRVolume.raw
内部には CT シーケンスのセットがあり、ファイルはpolyline.vtk
ポリラインの幾何学的構造のコンテンツです。2.ポリラインの補間を
使用して曲線を生成します 。3.使用方法は前のカーブからのもので、上の図に示すグリッドなどのサーフェス オブジェクトを生成します 。4. 2 つの入力を設定します: 入力 0 はサーフェス オブジェクト、入力 1 はデータ ソースです。5 .設定します。 データ ソース データの範囲に応じてマッピング テーブルクラスを設定し、; 6.設定し、; 7. レンダリング パイプラインを開始します; ----------------------- ------------------------ -------------------------------------------- ------------------------ -------------------------------------------- ------------- ------------------------ SweetLine メソッド 1.生成する行数を計算する曲線上の点の数として を取得し、次の合計に従って列の方向を取得します。vtkSplineFilter
SweepLine
vtkPolyData
vtkProbeFilter
vtkPolyData
surface
imageReader->GetOutput()
imageReader->GetOutput()
vtkWindowLevelLookupTable
SetWindow
SetLevel
vtkDataSetMapper
SetLookupTable
SetScalarRange(0, 255)
surface
line->GetNumberOfPoints()
distance
cols
spacing
;
2.surface
内部点の数を、ユニットの数を としてnumberOfPoints
計算します; 3.クラス オブジェクトとクラス オブジェクトを生成します; 4. 各行と列の点座標をトラバースして生成し、それらを ; に入力します; それぞれ隣接する 4 つの点ユニットを構成する5.オブジェクトの合計 を設定する 6.オブジェクトを返す; カーブから一方向にスキャンします。カーブから両端までスキャンすると、結果は CPR の機能と似ていますが、結果を平面上に配置する必要があります。次元画像。 このメソッドでは曲線を行 Row として使用し、Col 列を方向に拡張するため、結果を結果セットに変換します。データ 1 に従って、データ セットを変換します。rows * cols
(rows - 1) * (cols - 1)
vtkPoints
points
vtkCellArray
polys
points
InsertNextCell(4, pts)
surface
SetPoints(points)
SetPolys(polys)
surface
SweepLine
vtkProbeFilter
vtkImageData
SweepLine
direction
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;
}
コードの読み取り
設定lensClip
をSetValue
0 にすると半球のグレースケールを完全に表示でき、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