VTK修炼之道20:图像基本操作_图像类型转换

1.vtkImageCast

图像数据类型转换在数字图像处理中会被频繁地用到。一些常用到的图像算子(例如梯度算子)在计算时出于精度的考虑,会将结果存储为float或者double类型。但是在图像显示时,一般需要图像为unsigned char类型。

VTK中最常用到的是VTKImageCast类型。其使用方法如下:

vtkSmartPointer<vtkImageCast> imgCast =
vtkSmartPointer<vtkImageCast>::New();
imgCast->SetInput( (vtkDataObject*)reader->GetOutput() );
imgCast->SetOutputScalarTypeToFloat();
imgCast->Update();
当我们需要把图像转换成不同的类型进行计算时,只需要把SetOutputScalarTypeToXXX()设置成相应的输出类型即可。

需要注意的是,这个类中还有一个变量是ClampQverflow,用来标识是否组要截断数据。默认情况下,该变量值为0;当设置为1时,输出的像素值不能超过输出类型的最大值。超过时会自动截断到最大值。

此外还需要知道的就是,这个类进行类型转换时,只是将类型进行强制转换,而没有进行比例的缩放,因此使用起来会比较受限,因此VTK中时不推荐使用这个类的,例如一副double类型的图像,图像值的范围[-1,1]。如果需要将图像转化为unsigned char类型,这种方法是不可行的!

2.vtkImageShiftScale

这个类时用起来要比上一类更加的灵活。他可以指定偏移和比例参数来对输入图像数据进行操作,例如一副double类型的图像,其数值范围为[-1,1],如果将其转换为unsigned char类型,需要设置shift=+1,Scale=127.5;那么输入图像的数据-1可以被映射为(-1+1)*127.5=0;+1可以被映射为(1+1)*127.5=255。具体使用方法如下所示:


vtkSmartPointer<vtkImageShiftScale> ShiftScale =
vtkSmartPointer<vtkImageShiftScale>::New();
ShiftScale->SetInputConnection(img->GetOProducerPort());
ShiftScale->SetOutputScalarTypeToUnsignedChar();
ShiftScale->SetShift(1);
ShiftScale->SetScale(127.5);
ShiftScale->Update();

3.实验源码


#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL);

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

int main()
{
	vtkSmartPointer<vtkMetaImageReader> reader =
		vtkSmartPointer<vtkMetaImageReader>::New(); //读*.mhd文件
	reader->SetFileName("brain.mhd");
	reader->Update();
	//第一种类型转换方案
	vtkSmartPointer<vtkImageCast> imgCast =
		vtkSmartPointer<vtkImageCast>::New();
	imgCast->SetInputData( (vtkDataObject *) reader->GetOutput() );
	imgCast->SetOutputScalarTypeToFloat();
	//第二种类型转换方案
	vtkSmartPointer<vtkImageShiftScale> imgShiftScale =
		vtkSmartPointer<vtkImageShiftScale>::New();
	imgShiftScale->SetInputData((vtkDataObject*)reader->GetOutput());
	imgShiftScale->SetOutputScalarTypeToFloat();

	vtkSmartPointer<vtkImageViewer2> imgViewer =
		vtkSmartPointer<vtkImageViewer2>::New();
	imgViewer->SetInputConnection(imgCast->GetOutputPort());

	vtkSmartPointer<vtkRenderWindowInteractor> rwi =
		vtkSmartPointer<vtkRenderWindowInteractor>::New();
	imgViewer->SetupInteractor(rwi);

	imgViewer->SetColorLevel(500);
	imgViewer->SetColorWindow(2000);
	imgViewer->SetSlice(20);
	imgViewer->SetSliceOrientationToXY();
	imgViewer->Render();

	/*imgViewer->GetRenderer()->ResetCamera();
	imgViewer->Render();*/
	imgViewer->GetRenderer()->SetBackground(1.0, 1.0, 1.0);
	imgViewer->SetSize(640, 480);
	imgViewer->GetRenderWindow()->SetWindowName("ImageTypeTrans");

	rwi->Start();
	return 0;
}

4.参考资料

1.《C++ primer》
2.《The VTK User’s Guide – 11thEdition》
3.《The Visualization Toolkit – AnObject-Oriented Approach To 3D Graphics (4th Edition)》
4.  张晓东, 罗火灵. VTK图形图像开发进阶[M]. 机械工业出版社, 2015.

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要在 VTK 中显示 pcl::PointCloud<pcl::PointXYZRGB>::Ptr 类型的点云数据,需要先将其转换为 VTK 中的数据类型。可以使用 PCL 中的 vtkSmartPointer、vtkPolyData、vtkPoints、vtkUnsignedCharArray 等类来实现。以下是一个简单的示例代码: ```c++ #include <pcl/point_types.h> #include <pcl/point_cloud.h> #include <pcl/io/pcd_io.h> #include <vtkSmartPointer.h> #include <vtkPolyData.h> #include <vtkPoints.h> #include <vtkUnsignedCharArray.h> #include <vtkPolyDataMapper.h> #include <vtkActor.h> #include <vtkRenderWindow.h> #include <vtkRenderer.h> #include <vtkRenderWindowInteractor.h> int main(int argc, char** argv) { // 读取点云数据 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>); pcl::io::loadPCDFile<pcl::PointXYZRGB>("cloud.pcd", *cloud); // 创建 VTK 点云数据 vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New(); vtkSmartPointer<vtkUnsignedCharArray> colors = vtkSmartPointer<vtkUnsignedCharArray>::New(); colors->SetNumberOfComponents(3); colors->SetName("Colors"); for (size_t i = 0; i < cloud->size(); i++) { pcl::PointXYZRGB point = cloud->points[i]; points->InsertNextPoint(point.x, point.y, point.z); colors->InsertNextTupleValue(point.rgb); } vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New(); polydata->SetPoints(points); polydata->GetPointData()->SetScalars(colors); // 创建 VTK 渲染对象 vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New(); mapper->SetInputData(polydata); vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New(); actor->SetMapper(mapper); vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New(); renderer->AddActor(actor); vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New(); renderWindow->AddRenderer(renderer); vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New(); interactor->SetRenderWindow(renderWindow); // 显示点云数据 renderWindow->Render(); interactor->Start(); return 0; } ``` 代码中,首先读取点云数据,然后创建 VTK 点云数据,并将 PCL 点云数据转换为 VTK 点云数据。接着,创建 VTK 渲染对象,并将点云数据添加到渲染对象中。最后,显示点云数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值