VTK修炼之道14:图像处理_创建

来源:互联网 发布:linux 应用层驱动 编辑:程序博客网 时间:2024/05/17 23:23

1.引言:图像数据结构

数字图像文件内容由两个部分组成:图像头信息和数据。图像头信息定义了图像的基本信息,主要包括起点位置(Origin),像素间隔(space)和维数(dimension)。通过这三个参数即可以决定图像空间位置和规模。图像可以看做是空间中的一个规则网格,网格中的每个最小单元称之为一个像素(二维)或者体素(三维),这样网格在每个方向上的像素或者体素个数即为图像在该方向的维数。像素索引表示每个像素在图像网格中的位置,是图像内部的网格坐标。而在医学图像中,每个图像除了内部坐标外,还存在一个世界坐标。这个世界坐标依赖于成像设备。在医学图像中起点位置(Origin),像素间隔(space)和图像维数决定了世界坐标系。这样通过起点位置,像素间隔和像素索引即可计算每个像素的世界坐标位置。

图像数据即为图像像素的像素值,一般采用一维数组来表示和存储。已知像素索引和图像维数下,即可计算每个像素对应的像素值。通常图像的像素值为一个标量,例如一般灰度图像图像像素值也可以是一个向量,例如彩色图像;另外图像像素值还可以是张量,如梯度场图像。医学图像处理中大部分的图像都是灰度图像。
这里需要注意灰度图像的灰度值的数据类型,在一般的灰度图像处理中不需要考虑,因为其范围默认为0-255,可以采用一个unsigned char类型来表示。但是在医学图像处理中,256灰度级远远不能满足要求,因此灰度范围往往大于256级。常见的医学图像的像素数据类型为unsigned short,灰度范围为0-65536

2.采用Source创建源图像

VTK中内置多个创建图像的Source,利用这些Source可以快速的创建图像,其中以vtkImageCanvasSource2D为代表。该Source功能是创建一个画布(空白图像),并提供了多种几何图形(点、线段、圆、矩形以及图像等)的绘制填充功能。
#include <vtkAutoInit.h>      VTK_MODULE_INIT(vtkRenderingOpenGL);  #include<vtkSmartPointer.h>#include<vtkImageCanvasSource2D.h>#include<vtkImageData.h>#include<vtkImageActor.h>#include<vtkRenderer.h>#include<vtkRenderWindow.h>#include<vtkRenderWindowInteractor.h>#include<vtkInteractorStyleImage.h>int main(){vtkSmartPointer<vtkImageCanvasSource2D> canvas =vtkSmartPointer<vtkImageCanvasSource2D>::New();canvas->SetScalarTypeToUnsignedChar();canvas->SetNumberOfScalarComponents(1);canvas->SetExtent(0,100,0,100,0,0);canvas->SetDrawColor(0,0,0,0);canvas->FillBox(0,100,0,100);canvas->SetDrawColor(255,0,0,0);canvas->FillBox(20,40,20,40);canvas->Update();  //这一步还必不可少诶???//创建演员vtkSmartPointer<vtkImageActor> actor =vtkSmartPointer<vtkImageActor>::New();actor->SetInputData(canvas->GetOutput());//定义视窗double viewport[4] = {0,0,1,1};vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();renderer->SetViewport(viewport);renderer->AddActor(actor);renderer->ResetCamera();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("ImageCanvasSource2D");//设置窗口交互(演员-观众)vtkSmartPointer<vtkRenderWindowInteractor> rwi = vtkSmartPointer<vtkRenderWindowInteractor>::New();vtkSmartPointer<vtkInteractorStyleImage> style = vtkSmartPointer<vtkInteractorStyleImage>::New();rwi->SetInteractorStyle(style);rwi->SetRenderWindow(renderwindow);rwi->Initialize();rwi->Start();return 0;}
在上面代码中,首先定义了一个vtkImageCanvasSource2D的指针,然后设置画布的像素数据类型,像素成分数目和画布的大小。然后,在该画布中,利用FillBox绘制两个填充矩形,并通过SetDrawColor()来设置两个矩形的颜色。
代码运行结果为:

除了vtkImageCanvasSource2D外,vtkImageEllipsoidSource,该类根据指定的中心,各个轴的半径来生成一个前景为椭圆(球)的二值图像;vtkImageGaussianSource类生成一副像素值服从高斯分布的图像;vtkImageGridSource用于生成网格线图像;vtkImageNoiseSource生成一个像素值为随机数的噪声图像;vtkImageSinusoidSource生成的图像像素值由正弦函数决定。

3.直接创建一幅图像

VTK中可以手动生成图像,然后根据需要进行像素赋值。
#include <vtkAutoInit.h>      VTK_MODULE_INIT(vtkRenderingOpenGL);  #include <vtkSmartPointer.h>#include <vtkImageData.h>#include <vtkImageActor.h>#include <vtkRenderer.h>#include <vtkRenderWindow.h>#include <vtkRenderWindowInteractor.h>#include <vtkInteractorStyle.h>#include <vtkInformation.h>int main(){//vtk的新版本在vtkImageData类中取消了SetScalarTypeToUnsignedChar()方法;//现在仅能用如下方法设置://static void SetScalarType(int, vtkInformation* meta_data);vtkSmartPointer<vtkImageData> img =vtkSmartPointer<vtkImageData>::New();vtkSmartPointer<vtkInformation> info =vtkSmartPointer<vtkInformation>::New(); img->SetDimensions(16,16,1);img->SetScalarType(VTK_UNSIGNED_CHAR,info);img->SetNumberOfScalarComponents(1,info);//每个像素需要表示的组份 =1是指标量图img->AllocateScalars(info);//很重要unsigned char *ptr = NULL;ptr = (unsigned char*)img->GetScalarPointer();for(int i=0; i<16*16*1; i++){*ptr ++ = i%256;}///////////////启动渲染引擎vtkSmartPointer<vtkImageActor> actor =vtkSmartPointer<vtkImageActor>::New();actor->SetInputData(img);double viewport[4] = {0,0,1,1};vtkSmartPointer<vtkRenderer> render =vtkSmartPointer<vtkRenderer>::New();render->SetViewport(viewport);render->AddActor(actor);render->ResetCamera();render->SetBackground(1,1,1);vtkSmartPointer<vtkRenderWindow> window =vtkSmartPointer<vtkRenderWindow>::New();window->AddRenderer(render);window->SetSize(640,480);window->Render();window->SetWindowName("CreateVTKImageData");vtkSmartPointer<vtkRenderWindowInteractor> rwi = vtkSmartPointer<vtkRenderWindowInteractor>::New();vtkSmartPointer<vtkInteractorStyle> style =vtkSmartPointer<vtkInteractorStyle>::New();rwi->SetInteractorStyle(style);rwi->SetRenderWindow(window);rwi->Initialize();rwi->Start();return 0;}
首先定义vtkImageData指针,然后指定图像的维数,而图像的原点和像素间隔则都是采用默认值,因此不需要设置。SetScalarType指定图像的每个像素值的数据类型为unsigned char,SetNumberOfScalarComponents则指定了每个像素值的数据成分为1,每个像素值为1个标量值参数设置完毕后,调用AllocateScalars()分配内存,生成图像数据。图像生成后,默认所有像素值为0。可以通过访问图像数据数组来设置每个像素值,GetScalarPointer()即返回图像的数据数组(图像数据数组都采用一维数组),然后根据图像的大小,访问每个像素并为其赋值。生成的图像如下所示:

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.

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 财鼠跑到家里了怎么办 被老鼠咬出血了怎么办 家里飞了个蝙蝠怎么办 家里进了只蝙蝠怎么办 房间里有蟋蟀叫怎么办 油桶被老鼠咬了怎么办 美的库卡7年半后怎么办 深成指b跌光了怎么办 车贩子不办过户怎么办 荣威750v6很耗油怎么办 荣威550没电了怎么办 4s店倒闭贷款车怎么办 在单位有人整你怎么办 力帆620噪音大是怎么办 离职证明不给开怎么办 交离职报告不批怎么办 比亚迪s7噪音大怎么办 比亚迪f3噪音大怎么办 买房首付差10万怎么办 车贷合同没给我怎么办 车内老是有灰尘怎么办 车在北京怎么办进京证 五证合一后社保怎么办 五证齐全烂尾了怎么办 5万罚款交不起怎么办 炼铅环保手续要怎么办 贴膏药过敏红肿太痒了怎么办 没工作想贷款5万怎么办 燃气管超过2米了怎么办 建行燃气卡丢了怎么办 周浦燃气卡丢了怎么办 长沙燃气卡丢了怎么办 郑州燃气卡丢了怎么办 租房燃气卡丢了怎么办 洛阳燃气卡丢了怎么办 零线火线都带电怎么办 档案里年龄错了怎么办 档案年龄大了怎么办呢 吃菌子致幻了怎么办 野外吃了毒蘑菇怎么办 头顶头发稀少怎么办头顶头发稀