【VTK学習記-07】VTK画像表示(vtkImageViewer2は二次元画像表示、vtkImageActorは三次元画像レンダリング、vtkImageBlend画像融合)

学習チュートリアル: 「高度な VTK グラフィックスと画像開発」 Zhang Xiaodong、Luo Huoling
特別協力: Dongling Studio

5.2 VTK画像表示

5.2.1 vtkImageViewer2——二次元画像の表示

特に3次元画像のスライス表示に適しています。

例 - 3D 医療画像の特定のスライスを *.mhd 形式で表示する
ソース コード:

#include <vtkSmartPointer.h>
#include <vtkImageViewer2.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkMetaImageReader.h>

//测试图像:../data/brain.mhd  
int main()
{
    
    
	//使用vtkMetaImageReader读入一个*.mhd格式的图像
	vtkSmartPointer<vtkMetaImageReader>reader = vtkSmartPointer<vtkMetaImageReader>::New();
	reader->SetFileName("../data/brain.mhd");
	reader->Update();

	vtkSmartPointer<vtkImageViewer2>imageViewer = vtkSmartPointer<vtkImageViewer2>::New();
	imageViewer->SetInputConnection(reader->GetOutputPort());

	//显示切片
	vtkSmartPointer<vtkRenderWindowInteractor>renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
	imageViewer->SetupInteractor(renderWindowInteractor);

	imageViewer->SetColorLevel(500);//窗位
	imageViewer->SetColorWindow(2000);//窗宽
	imageViewer->SetSlice(40);//切片索引
	imageViewer->SetSliceOrientationToXY();//切片方向
	imageViewer->Render();

	imageViewer->GetRenderer()->SetBackground(1.0, 1.0, 1.0);
	imageViewer->SetSize(640, 480);
	imageViewer->GetRenderWindow()->SetWindowName("DisplayImageExample");

	renderWindowInteractor->Start();

	return 0;
}

操作結果:
ここに画像の説明を挿入します

5.2.2 vtkImageActor — 3D 画像レンダリング

テクスチャ マッピングは、表示のために画像をポリゴンにマッピングします。
vtkBMPReader を使用して画像を読み込んだ後、vtkImageActor、vtkRender、vtkRenderWindow、vtkRenderWindowInteractor を順に作成します。また、vtkInteractorStyleImage オブジェクトを定義し、それをレンダリング パイプラインにアセンブルする必要があります。
ソースコード:

#include <vtkSmartPointer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleImage.h>
#include <vtkRenderer.h>
#include <vtkBMPReader.h>
#include <vtkImageActor.h>


//测试图像:../data/lena.bmp
int main()
{
    
    
	//读取图片
	vtkSmartPointer<vtkBMPReader>reader = vtkSmartPointer<vtkBMPReader>::New();
	reader->SetFileName("../data/lena.bmp");
	reader->Update();

	//渲染管线
	vtkSmartPointer<vtkImageActor>imgActor = vtkSmartPointer<vtkImageActor>::New();
	imgActor->SetInputData(reader->GetOutput());

	vtkSmartPointer<vtkRenderer>renderer = vtkSmartPointer<vtkRenderer>::New();
	renderer->AddActor(imgActor);
	renderer->SetBackground(1.0, 1.0, 1.0);

	vtkSmartPointer<vtkRenderWindow>renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
	renderWindow->AddRenderer(renderer);
	renderWindow->SetSize(640, 480);
	renderWindow->Render();
	renderWindow->SetWindowName("DisplayImageExample2");

	vtkSmartPointer<vtkRenderWindowInteractor>renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
	vtkSmartPointer<vtkInteractorStyleImage> style = vtkSmartPointer<vtkInteractorStyleImage>::New();

	renderWindowInteractor->SetInteractorStyle(style);
	renderWindowInteractor->SetRenderWindow(renderWindow);
	renderWindowInteractor->Initialize();

	renderWindowInteractor->Start();

	return 0;

}

操作結果:
ここに画像の説明を挿入します

注: vtkImageActor が受け取る画像データ vtkImageData のピクセル タイプは unsigned char である必要があります。タイプが要件を満たしていない場合は、画像を表示する前に画像データ タイプを unsigned char に変換する必要があります。

コンパイル中にエラーが発生しました“vktSmartPointer”: 未声明的标识符解決策はこうなりました!VS でエラー行を削除し、メモ帳でまったく同じ行を書き直して、上に貼り付けると問題ありません。すばらしい!

5.2.3 vtkImageBlend—画像融合

画像の融合: 画像の不透明度を利用して画像を合成します。画像の融合を実現するには、クラス vtkImageBlend を使用します。vtkImageBlend は複数の画像入力を受け入れることができ、その出力画像は融合された画像です。

2 つの融合モード: 標準モード (デフォルト)、ブレンド モード
(1) 標準モード
(2) ブレンド モード
出力結果は不透明度を使用して正規化されます。

例: グレースケール画像を読み込み、バイナリ画像を生成し、画像を融合します (グレースケール画像とバイナリ画像の融合)。最後に、ウィンドウ内に 3 つの画像が表示されます。
ソースコード:

#include <vtkSmartPointer.h>
#include <vtkImageData.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleImage.h>
#include <vtkImageCanvasSource2D.h>
#include <vtkImageBlend.h>
#include <vtkJPEGReader.h>
#include <vtkImageActor.h>
#include <vtkImageCast.h>

//测试图像:../data/lena-gray.jpg
int main()
{
    
    
	//读入灰度图像      
	vtkSmartPointer<vtkJPEGReader>reader = vtkSmartPointer<vtkJPEGReader>::New();
	reader->SetFileName("../data/lena-gray.jpg");
	reader->Update();

	//生成二值图像      
	vtkSmartPointer<vtkImageCanvasSource2D>imageSource = vtkSmartPointer<vtkImageCanvasSource2D>::New();
	imageSource->SetNumberOfScalarComponents(1);
	imageSource->SetScalarTypeToUnsignedChar();
	imageSource->SetExtent(0, 512, 0, 512, 0, 0);
	imageSource->SetDrawColor(0.0);
	imageSource->FillBox(0, 512, 0, 512);
	imageSource->SetDrawColor(255.0);
	imageSource->FillBox(100,400,100,400);
	imageSource->Update();

	//融合图像:两个输入(0:灰度图像;1:二值图像)
	vtkSmartPointer<vtkImageBlend>imageBlend = vtkSmartPointer<vtkImageBlend>::New();
	//imageBlend->SetInputData(0, (vtkDataObject*)reader->GetOutput());
	//imageBlend->SetInputData(1, (vtkDataObject*)imageSource->GetOutput()); // 这样写不能显示融合图像
	imageBlend->AddInputData(reader->GetOutput());
	imageBlend->AddInputData(imageSource->GetOutput()); //修改为Add,然后取消编号就ok
	imageBlend->SetOpacity(0, 0.4);
	imageBlend->SetOpacity(1, 0.6);  //用于设置对应id号的图像不透明度的大小
	imageBlend->Update();

	//显示三组图像
	//(1)创建actors
	vtkSmartPointer<vtkImageActor>originalActor1 = vtkSmartPointer<vtkImageActor>::New();
	originalActor1->SetInputData(reader->GetOutput());

	vtkSmartPointer<vtkImageActor>originalActor2 = vtkSmartPointer<vtkImageActor>::New();
	originalActor2->SetInputData(imageSource->GetOutput());

	vtkSmartPointer<vtkImageActor>blendActor = vtkSmartPointer<vtkImageActor>::New();
	blendActor->SetInputData(imageBlend->GetOutput());

	//(2)定义viewport范围 (xmin,ymin,xmax,ymax)
	double leftViewport[4] = {
    
     0.0,0.0,0.33,1.0 };
	double midViewport[4] = {
    
     0.33,0.0,0.66,1.0 };
	double rightViewport[4] = {
    
     0.66,0.0,1.0,1.0 };

	//(3)创建渲染示例renderers
	vtkSmartPointer<vtkRenderer>originalRenderer1 = vtkSmartPointer<vtkRenderer>::New();
	originalRenderer1->SetViewport(leftViewport);
	originalRenderer1->AddActor(originalActor1);
	originalRenderer1->ResetCamera();
	originalRenderer1->SetBackground(1.0, 1.0, 1.0);

	vtkSmartPointer<vtkRenderer>originalRenderer2 = vtkSmartPointer<vtkRenderer>::New();
	originalRenderer2->SetViewport(midViewport);
	originalRenderer2->AddActor(originalActor2);
	originalRenderer2->ResetCamera();
	originalRenderer2->SetBackground(1.0, 1.0, 1.0);

	vtkSmartPointer<vtkRenderer>blendRenderer = vtkSmartPointer<vtkRenderer>::New();
	blendRenderer->SetViewport(rightViewport);
	blendRenderer->AddActor(blendActor);
	blendRenderer->ResetCamera();
	blendRenderer->SetBackground(1.0, 1.0, 1.0);

	//(4)创建渲染窗口renderWindow
	vtkSmartPointer<vtkRenderWindow>renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
	renderWindow->AddRenderer(originalRenderer1);
	renderWindow->AddRenderer(originalRenderer2);
	renderWindow->AddRenderer(blendRenderer);
	renderWindow->SetSize(640, 320);
	renderWindow->Render();
	renderWindow->SetWindowName("ImageBlendExample");

	//(5)创建交互RenderWindowInteractor以及交互样式
	vtkSmartPointer<vtkRenderWindowInteractor>renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
	vtkSmartPointer<vtkInteractorStyleImage> style = vtkSmartPointer<vtkInteractorStyleImage>::New();
	renderWindowInteractor->SetInteractorStyle(style);
	renderWindowInteractor->SetRenderWindow(renderWindow);
	renderWindowInteractor->Initialize();
	renderWindowInteractor->Start();

	return 0;
}

操作結果:
ここに画像の説明を挿入します

問題: Fusion 画像が表示されない
エラー メッセージ:vtkCompositeDataPipeline (00000201D3E32960): Input for connection index 0 on input port index 1 for algorithm vtkImageBlend(00000201D3E1F930) is of type vtkImageData, but a vtkImageStencilData is required.

エラー修正の参照: VTK Notes-Image Fusion-02-vtkImageBlend Class
注: VTK のバージョンには互換性がないため、SetInput() が使用できなくなります。

  • パイプ接続を確立したい場合は、SetInputConnection()、GetOutputPort()を使用します。
  • 独立したデータセットを処理したい場合は、SetInputData() を使用します。

おすすめ

転載: blog.csdn.net/m0_51141265/article/details/132825554