第5章 VTK画像処理
学習チュートリアル: 「高度な VTK グラフィックスと画像開発」 Zhang Xiaodong、Luo Huoling
特別協力: Dongling Studio
5.3 VTKイメージの基本操作
5.3.1 画像情報へのアクセスと変更
(1) vtkImageData - 画像情報アクセス
vtkImageData は、画像の基本情報を取得するための複数の関数を提供します。これらの関数は通常、Set または Get に対応する情報名を加えた形式で名前が付けられます。
例:
bmp形式の2次元画像を読み込み、取得した画像寸法、画像原点、画素間隔情報を表示します。
ソースコード:
#include <vtkSmartPointer.h>
#include <vtkImageData.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkImageViewer2.h>
#include <vtkBMPReader.h>
//测试图像:../data/lena.bmp
int main()
{
//读取bmp图像
vtkSmartPointer<vtkBMPReader>reader = vtkSmartPointer<vtkBMPReader>::New();
reader->SetFileName("../data/lena.bmp");
reader->Update();
//获取图像信息
int dims[3];
reader->GetOutput()->GetDimensions(dims);
std::cout << "图像维数" << dims[0] << " " << dims[1] << " " << dims[2] << std::endl;
double origin[3];
reader->GetOutput()->GetOrigin(origin);
std::cout << "图像原点" << origin[0] << " " << origin[1] << " " << origin[2] << std::endl;
double spacing[3];
reader->GetOutput()->GetSpacing(spacing);
std::cout << "像素间隔" << spacing[0] << " " << spacing[1] << " " << spacing[2] << std::endl;
//显示图像
vtkSmartPointer<vtkImageViewer2>imageViewer = vtkSmartPointer<vtkImageViewer2>::New();
imageViewer->SetInputConnection(reader->GetOutputPort());
vtkSmartPointer<vtkRenderWindowInteractor>renWinInter = vtkSmartPointer<vtkRenderWindowInteractor>::New();
imageViewer->SetupInteractor(renWinInter);
imageViewer->Render();
imageViewer->GetRenderer()->ResetCamera();
imageViewer->Render();
imageViewer->GetRenderer()->SetBackground(1.0, 1.0, 1.0);
imageViewer->SetSize(640, 480);
imageViewer->GetRenderWindow()->SetWindowName("GetImageInformationExample");
renWinInter->Start();
return 0;
}
結果:
注: VTK では、2 次元画像であっても 3 次元画像であっても、vtkImageData によって表されるため、画像の次元はプログラム内で dims[3] として定義されます。
(2) vtkChangeImageInformation——画像情報の変更
vtkChangeImageInformation は、イメージ情報を変更するためのパイプライン内のフィルターとして使用できます。画像の原点、ピクセル間隔、範囲を変更したり、画像の移動や拡大縮小などの操作も実行できます。
vtkImageData には基本的な画像情報も設定できる Set 関数が複数用意されていますが、画像フィルターの出力画像情報を変更した後、フィルターを更新すると画像情報は元の値に戻ります。
ソースコード:
#include <vtkSmartPointer.h>
#include <vtkImageViewer2.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkBMPReader.h>
#include <vtkImageChangeInformation.h>
#include <vtkImageData.h>
//测试图像:../data/lena.bmp
int main()
{
//读取图像
vtkSmartPointer<vtkBMPReader>reader = vtkSmartPointer<vtkBMPReader>::New();
reader->SetFileName("../data/lena.bmp");
reader->Update();
int dims[3];
double origin[3];
double spacing[3];
//查看图像原始信息
reader->GetOutput()->GetDimensions(dims);
std::cout << "原图像维数" << dims[0] << " " << dims[1] << " " << dims[2] << std::endl;
reader->GetOutput()->GetOrigin(origin);
std::cout << "原图像原点" << origin[0] << " " << origin[1] << " " << origin[2] << std::endl;
reader->GetOutput()->GetSpacing(spacing);
std::cout << "原图像像素间隔" << spacing[0] << " " << spacing[1] << " " << spacing[2] << std::endl;
//修改图像
vtkSmartPointer<vtkImageChangeInformation>changer = vtkSmartPointer<vtkImageChangeInformation>::New();
changer->SetInputData(reader->GetOutput());
changer->SetOutputOrigin(100, 100, 0); //将图像原点置为(100,100)
changer->SetOutputSpacing(5, 5, 1);
changer->SetCenterImage(1);//该函数的作用是将(0,0,0)置为图像的中心。将会覆盖上述设置的SetOutputOrigin(100, 100, 0)
changer->Update();
//查看图像修改后信息
changer->GetOutput()->GetDimensions(dims);
std::cout << "修改后图像维数:" << dims[0] << " " << dims[1] << " " << dims[2] << std::endl;
changer->GetOutput()->GetOrigin(origin);
std::cout << "修改后图像原点:" << origin[0] << " " << origin[1] << " " << origin[2] << std::endl;
changer->GetOutput()->GetSpacing(spacing);
std::cout << "修改后像素间隔:" << spacing[0] << " " << spacing[1] << " " << spacing[2] << std::endl;
//显示修改后的图像
vtkSmartPointer<vtkImageViewer2> imageViewer = vtkSmartPointer<vtkImageViewer2>::New();
imageViewer->SetInputConnection(changer->GetOutputPort());
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
imageViewer->SetupInteractor(renderWindowInteractor);
imageViewer->Render();
imageViewer->GetRenderer()->ResetCamera();
imageViewer->Render();
imageViewer->GetRenderer()->SetBackground(1.0, 1.0, 1.0);
imageViewer->SetSize(640, 480);
imageViewer->GetRenderWindow()->SetWindowName("ImageChangeInformationExample");
renderWindowInteractor->Start();
return 0;
}
結果:
5.3.2 画像ピクセル値のアクセスと変更
画像のピクセル値へのアクセスと変更は、最も一般的に使用される操作です。VTK では 2 つのメソッドが提供されます。
(1) vtkImageData のデータ配列に直接アクセス - GetScalarPointer() 関数を通じてデータ配列ポインタを取得します。
vtkImageData は、データ配列ポインターを取得するための GetScalarPointer() 関数を提供します。この関数には 3 つの形式があります。
//根据给定的像素索引得到指定的像素值,返回的是第(x,y,z)个像素值的地址
virtual void *GetScalarPointer(int coordinates[3]);
virtual void *GetScalarPointer(int x,int y,int z);
//返回图像数据数组的头指针,根据头指针可以依次访问索引像素
virtual void *GetScalarPointer();
例:
画像の100×100サイズの領域を黒に設定します。
ソースコード:
#include <vtkSmartPointer.h>
#include <vtkImageViewer2.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkBMPReader.h>
#include <vtkImageData.h>
//测试图像:../data/lena.bmp
int main()
{
//读取图像
vtkSmartPointer<vtkBMPReader> reader = vtkSmartPointer<vtkBMPReader>::New();
reader->SetFileName("../data/lena.bmp");
reader->Update();
//图像大小
int dims[3];
reader->GetOutput()->GetDimensions(dims);
//获取图像的元组组分数(是灰度图、梯度图、还是RGB图)
int nbOfComp;
nbOfComp = reader->GetOutput()->GetNumberOfScalarComponents();
//三重循环遍历像素点
for (int k = 0; k < dims[2]; k++)
{
for (int j = 0; j < dims[1]; j++)
{
for (int i = 0; i < dims[0]; i++)
{
if (i < 100 && j < 100)
{
//GetScalarPointer返回的是void类型,因此需要根据图像的实际类型进行强制转换。
//如果是RGB图,获取R值地址
unsigned char * pixel = (unsigned char *)(reader->GetOutput()->GetScalarPointer(i, j, k));
*pixel = 0;
*(pixel + 1) = 0; //(pixel + 1)即为G值的地址
*(pixel + 2) = 0; //(pixel + 2)即为B值的地址
}
}
}
}
vtkSmartPointer<vtkImageViewer2> imageViewer = vtkSmartPointer<vtkImageViewer2>::New();
imageViewer->SetInputConnection(reader->GetOutputPort());
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
imageViewer->SetupInteractor(renderWindowInteractor);
imageViewer->Render();
imageViewer->GetRenderer()->ResetCamera();
imageViewer->Render();
imageViewer->GetRenderer()->SetBackground(1.0, 1.0, 1.0);
imageViewer->SetSize(640, 480);
imageViewer->GetRenderWindow()->SetWindowName("VisitImagePixelDirectlyExample");
renderWindowInteractor->Start();
return 0;
}
結果:
注:
GetScalarPointer() 関数は void * タイプを返します。これは、画像の実際のタイプに基づいてキャストする必要があります。データ型がわからない場合は、画像データ型を特定のデータ型にキャストしてから走査することもできます。
RGB 画像およびベクトル画像のピクセルを変更する場合は、ピクセル タプルのコンポーネントの数に従ってそれらにアクセスする必要があります。まず、(i, j, k) 番目のピクセルの R 値のアドレスにアクセスし、そのアドレスに 1 を加算して、後続の G 値と B 値にアクセスします。
(2) vtkImageIterator - 画像ピクセルにアクセスする反復子メソッド
このクラスはテンプレート クラスであり、使用する場合は、反復画像のピクセル タイプと反復領域のサイズを指定する必要があります。
例:
bmp形式の画像を読み込み、画像の300×300の領域のピクセル値を反転します。
ソースコード:
#include <vtkSmartPointer.h>
#include <vtkImageViewer2.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkBMPReader.h>
#include <vtkImageData.h>
#include <vtkImageIterator.h>
//测试图像:../data/lena.bmp
int main()
{
//1.读取图像
vtkSmartPointer<vtkBMPReader> reader = vtkSmartPointer<vtkBMPReader>::New();
reader->SetFileName("../data/lena.bmp");
reader->Update();
//2.迭代访问像素值 二重循环
//定义一个子区域,不能超过图像范围(xmin,xmax,ymin,ymax,zmin,zmax)
//根据图像类型unsigned char定义一个图像迭代器it,两个参数(要访问的图像,要访问的图像子区域)
int subRegion[6] = {
0,300,0,300,0,0 };
vtkImageIterator<unsigned char>it(reader->GetOutput(), subRegion);
//判断迭代器是否结束,即该图像子区域的像素点是否全被遍历
while (!it.IsAtEnd())
{
unsigned char *inSI = it.BeginSpan(); //该点像素的第一个组分
unsigned char *inSIEnd = it.EndSpan(); //该点像素的最后一个组分
//判断当前像素的元组Tuple是否迭代完毕
while (inSI != inSIEnd)
{
*inSI = 255 - *inSI;
++inSI; //不断迭代当前像素的组分
}
it.NextSpan(); //该像素点组分迭代完毕后,继续迭代下个像素的组分元组
}
//3.显示图像
vtkSmartPointer<vtkImageViewer2> imageViewer = vtkSmartPointer<vtkImageViewer2>::New();
imageViewer->SetInputConnection(reader->GetOutputPort());
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
imageViewer->SetupInteractor(renderWindowInteractor);
imageViewer->Render();
imageViewer->GetRenderer()->ResetCamera();
imageViewer->Render();
imageViewer->GetRenderer()->SetBackground(1.0, 1.0, 1.0);
imageViewer->SetSize(640, 480);
imageViewer->GetRenderWindow()->SetWindowName("VisitImagePixelIterativelyExample");
renderWindowInteractor->Start();
return 0;
}
結果:
5.3.3 画像タイプの変換
(1) vtkImageCast - 最も単純な型変換フィルターですが、推奨されません
使用方法は以下の通り、SetOutputScalarTypeToxxx()
対応する出力タイプに設定するだけです。
このクラスには、データを切り詰める必要があるかどうかを識別するために使用される変数 ClampOverflow もあります。デフォルトでは、この変数の値は 0 です。値が 1 に設定されている場合、出力ピクセル値は最大値を超えることはできません出力タイプの値を入力すると、自動的に最大値に切り捨てられます。
そのため、型変換を行う場合、プロポーショナルスケーリングを行わずに強制的にデータを変換するだけのクラスとなり、用途が限定されており、VTKでは推奨しておりません。
vtkSmartPointer<vtkImageCast>imageCast=vtkSmartPointer<vtkImageCast>::New();
imageCast->SetInput((vtkDataObject*)reader->GetOutput());
imageCast->SetOutputScalarTypeToFloat();
imageCast->Update();
(2) vtkImageShiftScale - オフセットおよびスケールパラメータを指定します
vtkImageShiftScale は、入力イメージ データを操作するオフセットおよびスケール パラメーターを指定できます。
例: double 型の画像、値の範囲は [-1,1]、unsigned char 型に変換する場合、シフト値を +1 に、スケール係数を 127.5 に設定する必要があります。その場合、入力データは次のようになります。 -1 マッピングは (-1+1)×127.5=0 ですが、+1 は (+1+1)×127.5=255 にマッピングされます。具体的なコードは次のとおりです。
vtkSmartPointer<vtkImageShiftScale>shiftScaleFilter=vtkSmartPointer<vtkImageShiftScale>::New();
shiftScalarFilter->SetInputConnection(image->GetProducerPort());
shiftScalarFilter->SetOutputScalarTypeToUnsignedChar();
shiftScalarFilter->SetShift(1); //设置偏移量
shiftScalarFilter->SetScale(127.5); //设置缩放值
shiftScalarFilter->Update();
注:
このクラスには変数 ClampOverflow もあり、その値が 1 の場合、出力値が出力タイプの最大値を超える場合、自動的に切り捨てられます。たとえば、出力タイプは unsigned char で、値の範囲は 0 ~ 255 です。出力ピクセルが 257 の場合、このクラスは次のようになります。自動的に 255 に切り捨てられます。デフォルトでは、変数 ClampOverflow の値は 0 です。このとき、出力値が 257 で出力型が unsigned char の場合、クラスは切り捨てずにオーバーフローします。最終的な値は 2 です。
5.3.4 画像のカラーマッピング
(1)vtkImageLuminance——グレースケールマッピング
vtkImageLuminance は、RGB カラー イメージを単一コンポーネントのグレースケール イメージに変換する役割を果たします。マッピング式は次のとおりです。
この式は、RGB カラーの明るさを計算するために使用されます。
このクラスの使用コードは次のとおりです。
vtkSmartPointer<vtkImageLuminance>luminanceFilter=vtkSmartPointer<vtkImageLuminance>::New();
luminanceFilter->SetInputConnection(reader->GetOutputPort());
luminanceFilter->Update();
(2) vtkImageExtractComponents - 色成分の抽出
カラー画像の各色成分を抽出するこのクラスを使用する場合、抽出する成分の順序番号を設定する必要があります。
(3) vtkImageMapToColors - カラーマッピング
画像のカラー マッピングの原理は、まずカラー ルックアップ テーブルを生成し、次に画像ピクセルのスカラー値に基づいてカラー ルックアップ テーブル内で対応する色を見つけ、元のピクセル値を新しいカラー値で置き換えます。VTK は、vtkImageMapToColors
画像のカラー マッピングを実装してvtkLookUpTable
カラー ルックアップ テーブルを生成するために使用されます。
//读入灰度图像
vtkSmartPointer<vtkJPEGReader>reader=vtkSmartPointer<vtkJPEGReader>::New();
reader->SetFileName("../data/lena.jpg");
//生成颜色查找表
vtkSmartPointer<vtkLookupTable>colorTable=vtkSmartPointer<vtkLookupTable>::New();
colorTable->SetRange(0.0,255.0);//设置要映射的标量数据的范围
colorTable->SetHueRange(0.1,0.5);//设置HSV颜色空间的Hue值范围,最大范围[0,1]
colorTable->SetValueRange(0.6,1.0);//设置HSV颜色空间的Value值范围,最大范围[0,1]
colorTable->Build();//生成颜色查找表
//根据颜色查找表来查找新颜色,并替换
vtkSmartPointer<vtkImageMapToColors>colorMap=vtkSmartPointer<vtkImageMapToColors>::New();
colorMap->SetInputConnection(reader->GetOutputPort());
colorMap->SetLookupTable(colorTable);//设置相应的颜色查找表
colorMap->Update();
(4)vtkImageAppendComponents——色合成
複数のグレースケール画像を 1 つのカラー画像に結合します。vtkImageAppendComponents クラスはカラー イメージの合成に使用でき、入力として 3 つのグレースケール イメージを必要とします。
単一チャンネルの二値画像と同様に、3 つのチャンネルを重ね合わせてカラー画像を形成することができ、重ね合わされた画像のピクセルの 3 つの値がその点の RGB 値となり、色を合成できます。3 つのチャネルは異なる順序で積み重ねられ、異なる色で表示されます。
5.3.5 領域抽出
(1) vtkExtractVOI - 対象領域の抽出
ユーザー指定の領域範囲に基づいてサブイメージを抽出します。このフィルターの入力と出力は両方とも vktImageData であるため、結果を画像として直接保存できます。
2 つの入力を受け取る必要がある vtkExtractVOI オブジェクトを定義します。1 つは元の画像データで、もう 1 つは抽出領域のサイズです。
//获取图像大小
int dims[3];
reader->GetOutput()->GetDimensions(dims);
//设定提取的区域大小(xmin,xmax,ymin,ymax,zmin,zmax)
vtkSmartPointer<vtkExtractVOI>extractVOI=vtkSmartPointer<vtkExtractVOI>::New();
extractVOI->SetInputConnection(reader->GetOutputPort());
extractVOI->SetVOI(dims[0]/4.,3.*dims[0]/4.,dims[1]/4.,3.*dims[1]/4.,0,0);
extractVOI->Update();
(2) vtkImageReslice——3D画像部分抽出(×)
vtkImageReslice は、3 次元画像内の点と任意の方向に平行な平面を抽出できます。
(3) 拡張 - マウスをスライドして 3 次元画像スライスを切り替えます (×)
5.3.6 ヒストグラム統計 (×)
VTK のクラスは、vtkImageAccumulate
ヒストグラム統計関数を実装するために使用されます。各コンポーネントの数値範囲を個別の間隔に分割し、各グレースケール間隔のピクセル数をカウントします。入出力はすべて vtkImageData 型なので、ヒストグラムも画像とみなすことができます。入力画像のピクセル データ型は任意ですが、最大 3 つのコンポーネント ピクセル タイプがサポートされ、出力画像のピクセル データ型は int 型です。
(1) グレースケール画像のヒストグラム (×)
グレースケール イメージにこのフィルターを使用すると、1 次元のイメージが生成されます。
(2) カラー画像ヒストグラム(×)
カラー画像には 3 つのカラー チャネルがあるため、ヒストグラムを個別に計算するには 3 つの RGB チャネル データを抽出する必要があります。
5.3.7 画像のリサンプリング
画像のリサンプリングとは、幾何学的変換後に新しい画像を形成するために、必要な位置ピクセルまたはピクセル間隔に従ってデジタル画像をリサンプリングすることを指します。
リサンプリング後、画像のサイズが変わります。リサンプリングされた画像の寸法が元の画像より小さい場合、それはダウンサンプリングと呼ばれ、リサンプリングされた画像の寸法が元の画像より大きい場合、それはアップサンプリングと呼ばれます。vtkImageShrink3D
クラスを使用して画像のダウンサンプリングを実装できます。vtkImageMagnify
クラスを使用して画像のアップサンプリングを実装できます。
ダウンサンプリングでは各方向のサンプリング レートを設定する必要があり、サンプリング レートが大きいほど画像がぼやけます。アップサンプリングの原理はダウンサンプリングの原理と同じですが、サンプリング点の数を増やすことで画像の次元が増加する点が異なります。
サンプリングレートは20、つまり20段階で選択されるため、512×512の画像をサンプリングレート20×20でダウンサンプリングすると、画像のサイズは25×25となります。
ソースコード:
#include <vtkSmartPointer.h>
#include <vtkImageData.h>
#include <vtkImageShiftScale.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleImage.h>
#include <vtkRenderer.h>
#include <vtkImageActor.h>
#include <vtkBMPReader.h>
#include <vtkImageShrink3D.h>
#include <vtkImageMagnify.h>
//测试图像:../data/lena.bmp
int main()
{
//读入图像
vtkSmartPointer<vtkBMPReader>reader = vtkSmartPointer<vtkBMPReader>::New();
reader->SetFileName("../data/lena.bmp");
reader->Update();
int originalDims[3];
reader->GetOutput()->GetDimensions(originalDims);
std::cout << "原图图像维数 :" << originalDims[0] << " " << originalDims[1] << " " << originalDims[2] << std::endl;
double originalSpace[3];
reader->GetOutput()->GetSpacing(originalSpace);
std::cout << "原图图像像素间隔 :" << originalSpace[0] << " " << originalSpace[1] << " " << originalSpace[2] << std::endl;
//降采样
vtkSmartPointer<vtkImageShrink3D>shrinkFilter = vtkSmartPointer<vtkImageShrink3D>::New();
shrinkFilter->SetInputConnection(reader->GetOutputPort());
shrinkFilter->SetShrinkFactors(20, 20, 1);
shrinkFilter->Update();
int shrinkDims[3];
shrinkFilter->GetOutput()->GetDimensions(shrinkDims);
std::cout << "降采样图像维数 :" << shrinkDims[0] << " " << shrinkDims[1] << " " << shrinkDims[2] << std::endl;
double shrinkSpace[3];
shrinkFilter->GetOutput()->GetSpacing(shrinkSpace);
std::cout << "降采样图像像素间隔:" << shrinkSpace[0] << " " << shrinkSpace[1] << " " << shrinkSpace[2] << std::endl;
//升采样
vtkSmartPointer<vtkImageMagnify> magnifyFilter = vtkSmartPointer<vtkImageMagnify>::New();
magnifyFilter->SetInputConnection(reader->GetOutputPort());
magnifyFilter->SetMagnificationFactors(10, 10, 1);
magnifyFilter->Update();
int magnifyDims[3];
magnifyFilter->GetOutput()->GetDimensions(magnifyDims);
std::cout << "升采样图像维数 :" << magnifyDims[0] << " " << magnifyDims[1] << " " << magnifyDims[2] << std::endl;
double magnifySpace[3];
magnifyFilter->GetOutput()->GetSpacing(magnifySpace);
std::cout << "升采样图像像素间隔:" << magnifySpace[0] << " " << magnifySpace[1] << " " << magnifySpace[2] << std::endl;
//显示三张图像(原图、降采样、升采样)
vtkSmartPointer<vtkImageActor>originalActor = vtkSmartPointer<vtkImageActor>::New();
originalActor->SetInputData(reader->GetOutput());
vtkSmartPointer<vtkImageActor>shrinkActor = vtkSmartPointer<vtkImageActor>::New();
shrinkActor->SetInputData(shrinkFilter->GetOutput());
vtkSmartPointer<vtkImageActor>magnifyActor = vtkSmartPointer<vtkImageActor>::New();
magnifyActor->SetInputData(magnifyFilter->GetOutput());
double originalViewport[4] = {
0.0, 0.0, 0.33, 1.0 };
double shrinkViewport[4] = {
0.33, 0.0, 0.66, 1.0 };
double magnifyViewport[4] = {
0.66, 0.0, 1.0, 1.0 };
vtkSmartPointer<vtkRenderer> originalRenderer = vtkSmartPointer<vtkRenderer>::New();
originalRenderer->SetViewport(originalViewport);
originalRenderer->AddActor(originalActor);
originalRenderer->ResetCamera();
originalRenderer->SetBackground(1.0, 1.0, 1.0);
vtkSmartPointer<vtkRenderer> shrinkRenderer = vtkSmartPointer<vtkRenderer>::New();
shrinkRenderer->SetViewport(shrinkViewport);
shrinkRenderer->AddActor(shrinkActor);
shrinkRenderer->ResetCamera();
shrinkRenderer->SetBackground(1.0, 1.0, 1.0);
vtkSmartPointer<vtkRenderer> magnifyRenderer = vtkSmartPointer<vtkRenderer>::New();
magnifyRenderer->SetViewport(magnifyViewport);
magnifyRenderer->AddActor(magnifyActor);
magnifyRenderer->ResetCamera();
magnifyRenderer->SetBackground(1.0, 1.0, 1.0);
vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(originalRenderer);
renderWindow->AddRenderer(shrinkRenderer);
renderWindow->AddRenderer(magnifyRenderer);
renderWindow->SetSize(640, 320);
renderWindow->Render();
renderWindow->SetWindowName("ImageShrinkMagnifyExample");
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
vtkSmartPointer<vtkInteractorStyleImage> style = vtkSmartPointer<vtkInteractorStyleImage>::New();
renderWindowInteractor->SetInteractorStyle(style);
renderWindowInteractor->SetRenderWindow(renderWindow);
renderWindowInteractor->Initialize();
renderWindowInteractor->Start();
return 0;
}
結果:
5.3.8 画像操作
(1) vtkImageMathematics - 数学的演算
vtkImageMathematics は、基本的な単項および二項数学演算を提供します。2 値数学演算では、両方の入力画像が同じピクセル データ タイプと色成分を持つ必要があります。2 つのイメージのサイズが異なる場合、出力イメージの範囲は 2 つの入力イメージの範囲を結合したものとなり、原点とピクセル間隔は最初の入力イメージと一致します。
(2) vtkImageLogic - 論理演算
vtkImageLogic は、ブール論理演算用に 1 つまたは 2 つのイメージを受け入れます。このクラスは、主に AND、OR、XOR、NAND、NOR、NOT をサポートします。二項演算子を選択する場合、2 つの入力イメージは同じタイプである必要があります。
5.3.9 画像の二値化
バイナリ イメージとラベル イメージは、イメージ セグメンテーションでよく使用される 2 種類のイメージです。バイナリ イメージの各ピクセルには、0 と 255 の 2 つの値しかありません。0 はイメージの背景を表し、255 はイメージの前景を表します。
画像の二値化: グレースケールの閾値を設定し、画像内の閾値以下のピクセル値を背景として設定し、閾値より上のピクセル値を前景として設定して、二値画像を取得します。vtkImageThreshold クラスを通じて実装されます。
vtkSmartPointer<vtkJPEGReader> reader = vtkSmartPointer<vtkJPEGReader>::New();
reader->SetFileName("../data/lena-gray.jpg");
reader->Update();
vtkSmartPointer<vtkImageThreshold> thresholdFilter = vtkSmartPointer<vtkImageThreshold>::New();
thresholdFilter->SetInputConnection(reader->GetOutputPort());
//取大于100的所有像素输出值为255,而小于100的像素输出值为0
thresholdFilter->ThresholdByUpper(100);//取大于100的灰度范围为有效范围
thresholdFilter->SetInValue(255);//设置有效范围内的输出值为255
thresholdFilter->SetOutValue(0);//设置有效范围外的输出值为0