wordpress首页调用文章数量,广州推动优化防控措施落地,网站改版优化,广州做网站哪里好VTK医学图像处理---vtkImageData类
目录
VTK医学图像处理---vtkImageData类
简介#xff1a;
1 Mricro软件的安装和使用
(1) Mricro安装
(2) Mricro转换DICOM为裸数据
2 从硬盘读取数据到vtkImageData
3 vtkImageData转RGB或RGBA格式
4 练习
总结 简介#xff1a;…VTK医学图像处理---vtkImageData类
目录
VTK医学图像处理---vtkImageData类
简介
1 Mricro软件的安装和使用
(1) Mricro安装
(2) Mricro转换DICOM为裸数据
2 从硬盘读取数据到vtkImageData
3 vtkImageData转RGB或RGBA格式
4 练习
总结 简介 对于医学图像来说vtkImageData是使用频率非常高的类因为医学图像通常为较为规则的矩形或容积类型三维而vtkImageData类主要就是用于存储此类数据的vtk中相关算法比如阈值、缩放等的输入和输出也是vtkImageData类熟练掌握vtkImageData类非常重要。 vtkDICOMImageReader类读取文件夹中的DICOM文件后DICOM数据也存储在vtkImageData类中本篇博文将跳过vtkDICOMImageReader类直接从硬盘读取数据到vtkImageData类中以增强大家对vtkImageData类的熟悉。 由于DICOM格式非常负责有专门的开源库对DICOM文件进行解析比如DCMTK(DCMTK - dicom.offis.de)我们不打算详细介绍DICOM标准因此我们将借助一个免费的软件Mricro建议大家学会使用给软件不管是开发还是做科研都非常有用来将DICOM文件转换为原始数据采用C语言从硬盘读取原始数据到vtkImageData类中。 本博文主要包括为 Mricro的安装和使用从硬盘读取数据到vtkImageData类vtkImageData类的详细介绍。
1 Mricro软件的安装和使用
下载地址MRIcro software guide (sc.edu)
打开网页后点击下图中红色方框中的链接开始下载。 (1) Mricro安装
下载后解压会看到下面的图标双击安装提出是否安装选择是一路默认安装详细步骤如下图 (2) Mricro转换DICOM为裸数据 在开始栏中搜索Mricro或从所有应用程序里面找到Mricro启动启动后的界面为 DICOM数据下载地址【免费】VTK-医学图像处理博文中需要的DICOM测试数据资源-CSDN文库
下载DICOM数据解压在Mricro软件的菜单项中选择 Import--Convert foreign to Analyze跳出选择对话框。 在Number of Files中要输入待转换的DICOM文件张数 例如这里我们转换10张就在该输入框内填写10记得勾选 Open sequential files:ignore filename选项然后点击 Select。 在Conversion Options框中继续点击 OK 这里有时候会跳出一个或两个提示框不用管它点击OK继续 到 Select 对话框后随便选中一张待转换的DICOM文件然后再文件名中输入要保存为裸数据的名称点击 打开。 单击 打开后会跳出导出保存框在保存框中输入要保存的名称点击 保存按钮进行保存。 打开DicomFiles所在文件夹会发现里面多了两个文件test.hdr和 test.img
其中 test.hdr文件中保存的数据的长宽高空间位置等信息
test.img文件中就是纯粹的裸数据接下来我们将读取test.img中的数据到vtkImageData中。
双击test.hdr用Mricro软件打开它在软件的左侧可以看到test.img中的数据长为512宽为512一共有10张图像数据类型为short。 2 从硬盘读取数据到vtkImageData 老规矩先看下代码也可以拷贝到自己的项目中运行下
#define _CRT_SECURE_NO_WARNINGS#include vtkImageMapToWindowLevelColors.h
#include vtkImageActor.h
#include vtkImageMapper3D.h
#include vtkImageData.h
#include vtkNew.h
#include vtkDICOMImageReader.h
#include vtkRenderWindow.h
#include vtkRenderWindowInteractor.h
#include vtkRenderer.h
#include vtkCamera.h
int ImageSlice 0;
void main()
{vtkNewvtkImageData imageData;imageData-SetDimensions(512, 512, 10);imageData-SetSpacing(.49, .49, .7);imageData-SetOrigin(0.0, 0.0, 0.0);imageData-AllocateScalars(VTK_SHORT, 1);void *ptr imageData-GetScalarPointer();size_t bSize 512 * 512 * 10;FILE* pFile fopen(D:\\DicomFiles\\test.img,rb);if (NULL pFile)return;fread(ptr, sizeof(short), bSize, pFile);fclose(pFile);int* ext imageData-GetExtent();// map the input image through a lookup table and window / level itvtkNewvtkImageMapToWindowLevelColors windowLevel;windowLevel-SetWindow(1000);windowLevel-SetLevel(800);windowLevel-SetInputData(imageData);//vtkImageActor: draw an image in a rendered 3D scenevtkNewvtkImageActor imageActor;imageActor-SetDisplayExtent(ext[0], ext[1], ext[2], ext[3], ImageSlice, ImageSlice);imageActor-GetMapper()-SetInputConnection(windowLevel-GetOutputPort());// The renderer generates the image which is then displayed on the render window.vtkNewvtkRenderer renderer;renderer-AddActor(imageActor);renderer-SetBackground(.2,.2,.2);vtkCamera *cam renderer-GetActiveCamera();if (cam){// 获取物体在三维空间中的原点XYZ范围和中心//vtkImageData* idata reader-GetOutput();vtkImageData* idata imageData;double* origins idata-GetOrigin(); // 三维坐标中的起点double* bounds idata-GetBounds(); // 包围盒的xyz范围double* center idata-GetCenter(); // 中心cam-SetFocalPoint(center);cam-SetPosition(center[0], center[1], center[2] - bounds[5]); // -1 if medical ?cam-SetViewUp(0, 1, 0);cam-SetClippingRange(0.1,1000);renderer-ResetCamera();}// The render window is the actual GUI window that appears on the computer screenvtkNewvtkRenderWindow renderWindow;renderWindow-SetSize(512, 512);renderWindow-AddRenderer(renderer);renderWindow-SetWindowName(Dicom Image);// The render window interactor captures mouse events// and will perform appropriate camera or actor manipulation// depending on the nature of the events.vtkNewvtkRenderWindowInteractor interactor;interactor-SetRenderWindow(renderWindow);// This starts the event loop and as a side effect causes an initial render.renderWindow-Render();interactor-Start();
}主要修改的代码如下 vtkNewvtkImageData imageData;imageData-SetDimensions(512, 512, 10);imageData-SetSpacing(.49, .49, .7);imageData-SetOrigin(0.0, 0.0, 0.0);imageData-AllocateScalars(VTK_SHORT, 1);void *ptr imageData-GetScalarPointer();size_t bSize 512 * 512 * 10;FILE* pFile fopen(D:\\DicomFiles\\test.img,rb);if (NULL pFile)return;fread(ptr, sizeof(short), bSize, pFile);fclose(pFile); SetDimensions 函数主要用来设置图像的长宽高信息
SetSpacing 是像素间距图像的512 - 1* 0.49 就是图像宽的实际尺寸
SetOrigin 是图像在世界坐标中的位置
AllocateScalars有两个参数第一个参数指定数据类型16bit short;第二个参数1是 一个像素是有一个元素组成对于BMP位图来说一个像素是有RGB/RGBA组成的
AllocateScalars 同时还分配内存空间
GetScalarPointer函数可以获取分配内存空间的地址有了地址有了数据的大小就可以直接从硬盘读取裸数据了。读取的代码用C语言来写的这里就不解释了。
运行结果如下 3 vtkImageData转RGB或RGBA格式
接下来我们增加了个一个Convert2RGB函数用户将vtkImageData中的数据转换为RGB格式的数据并保存的硬盘然后用Mricro打开查看。
完整源代码如下
#define _CRT_SECURE_NO_WARNINGS#include vtkImageMapToWindowLevelColors.h
#include vtkImageActor.h
#include vtkImageMapper3D.h
#include vtkImageData.h
#include vtkNew.h
#include vtkDICOMImageReader.h
#include vtkRenderWindow.h
#include vtkRenderWindowInteractor.h
#include vtkRenderer.h
#include vtkCamera.h
#include vtkWindowLevelLookupTable.h
int ImageSlice 0;void Convert2RGB(vtkImageData* pData);void main()
{vtkNewvtkImageData imageData;imageData-SetDimensions(512, 512, 10);imageData-SetSpacing(.49, .49, .7);imageData-SetOrigin(0.0, 0.0, 0.0);imageData-AllocateScalars(VTK_SHORT, 1);void *ptr imageData-GetScalarPointer();size_t bSize 512 * 512 * 10;FILE* pFile fopen(D:\\DicomFiles\\test.img,rb);if (NULL pFile)return;fread(ptr, sizeof(short), bSize, pFile);fclose(pFile);Convert2RGB(imageData);int* ext imageData-GetExtent();// map the input image through a lookup table and window / level itvtkNewvtkImageMapToWindowLevelColors windowLevel;windowLevel-SetWindow(1000);windowLevel-SetLevel(800);windowLevel-SetInputData(imageData);//vtkImageActor: draw an image in a rendered 3D scenevtkNewvtkImageActor imageActor;imageActor-SetDisplayExtent(ext[0], ext[1], ext[2], ext[3], ImageSlice, ImageSlice);imageActor-GetMapper()-SetInputConnection(windowLevel-GetOutputPort());// The renderer generates the image which is then displayed on the render window.vtkNewvtkRenderer renderer;renderer-AddActor(imageActor);renderer-SetBackground(.2,.2,.2);vtkCamera *cam renderer-GetActiveCamera();if (cam){// 获取物体在三维空间中的原点XYZ范围和中心//vtkImageData* idata reader-GetOutput();vtkImageData* idata imageData;double* origins idata-GetOrigin(); // 三维坐标中的起点double* bounds idata-GetBounds(); // 包围盒的xyz范围double* center idata-GetCenter(); // 中心cam-SetFocalPoint(center);cam-SetPosition(center[0], center[1], center[2] - bounds[5]); // -1 if medical ?cam-SetViewUp(0, 1, 0);cam-SetClippingRange(0.1,1000);renderer-ResetCamera();}// The render window is the actual GUI window that appears on the computer screenvtkNewvtkRenderWindow renderWindow;renderWindow-SetSize(512, 512);renderWindow-AddRenderer(renderer);renderWindow-SetWindowName(Dicom Image);// The render window interactor captures mouse events// and will perform appropriate camera or actor manipulation// depending on the nature of the events.vtkNewvtkRenderWindowInteractor interactor;interactor-SetRenderWindow(renderWindow);// This starts the event loop and as a side effect causes an initial render.renderWindow-Render();interactor-Start();
}void Convert2RGB(vtkImageData* pData)
{void *ptr pData-GetScalarPointer();vtkNewvtkWindowLevelLookupTable table;table-SetWindow(1000);table-SetLevel(800);table-Build();table-BuildSpecialColors();long iCount 512 * 512;void *rgbPtr malloc(iCount * 3);unsigned char *desPtr (unsigned char *)rgbPtr;table-MapScalarsThroughTable2(ptr, desPtr, VTK_UNSIGNED_SHORT, iCount, VTK_LUMINANCE, VTK_RGB);FILE* pFile fopen(color2.img, wb);if (!pFile)return;fwrite(rgbPtr, 1, iCount * 3, pFile);fclose(pFile);free(rgbPtr);}
打开源代码所在文件夹会发现多了一个color2.img打开Mricro软件将 color2.img拖到Mricro软件中发现打开后是乱码这是由于Mricro软件左侧的参数信息不正确。 将左侧X Y Z分别填入512 512 1
将Data选中 24-bit rgb
然后点击菜单中的HeaderSave header; 保存完成后双击 color2.hdr,打开显示结果如下 在这里例子中我们只保存了一张RGB而图像是有10张的请自己动手把10张图像全部保存成为RGB数据练习一下。
4 练习
1用vtkImageData读取一张BMP图像并显示
2将相机的位置这是在现在位置的反方向对比下显示结果
3将vtkImageData中的数据重新保存一份用Mricro软件打开查看是否正确
总结