MITK Image介绍

这里写图片描述

Image直接继承自SlicedData。BaseData在MITK中相当于是其他Datatype的老妈。SlicedData继承了这个类后又在功能上做了细化,在类中包含了image slices, 引入了能够完整定义geometry的属性和函数。mitk::Image又进一步具体化,包含了multiple channels, volumes, slices以及额外的属性如image properties。

下面我们介绍三个不同的方面:
1. SlicedData and Geometry
2. ImageData
3. Image Properties

SlicedData and Geometry

作为Image的父类,引入了一个重要概念:Geometry,用来定义图像的空间属性:dimention和orientation。深入了解这一概念参照这里:Geometry Overview

ImageData

mitk::Image的实例化对象存储着实际的图像数据。理清下面这四个概念很重要:

  1. Channels,表示数据是哪种类型(比如说是灰度图像还是矢量图像)。每个channel包含一个或多个volume。
  2. Volumes, 含有特定类型的数据。一个volume由多个表示volume属性的ImageDataItem表示。每个volume由多个slices组成。
  3. Slices, 每一个slice含有一个二维图像。

mitk::Image含有一个指针成员m_CompleteData ,指向数据整体(所有volume)。当你想把一个图像数据拷贝至另一个图像数据里时,这个成员非常有用。

这里写图片描述

Image Properties

Properties是一组附加信息,主要用来保存DICOM信息。这个功能在BaseData类中就引入了。工作机制与哈希表类似,使用property key和properties的对应。更多请参考 BaseData::GetProperty() ,例子参照USImage::GetMetadata()。

获取图像数据

MITK中多个模块和plugin都可能工作在同一图像上,所以理解和管理正在进行的image access十分困难,因此image accessor的概念被引入。image accessor负责管理图像的access并保证数据一致性。每个图像都管理自己的image accessors。下面详细解释。

Image accessors

Image accessors提供获取图像数据的功能,它负责:
1. 监管:任何时间它都知道有多少个实例在访问某个部分的数据。
2. 一致性和线程安全性:上锁机制允许并行读图像,保证过程中数据的状态一致性。
3.可限制部分图像的获取:可限制仅能访问图像的某个部分(volume或slice)。这个部分由ImageDataItem表示。
4. 可使用pixel index:方便地获取图像像素值。

目前可实例化的image accessor类包括 mitk::ImageReadAccessor, mitk::ImageWriteAccessor和mitk::ImageVtkAccessor。mitk::ImageReadAccessor 和 mitk::ImageWriteAccessor提供对一个mitk::Image或 mitk::ImageDataItem的访问,并提供一个 (const) void *指针。 mitk::ImageVtkAccessor提供 legacy mode 下的VTK图像获取(不能实例化)。

这里写图片描述

如何access

尽管image accessor概念有点复杂,但使用起来很方便。先创建一个image accessor对象。image accessor的构造器需要一个指向mitk::Image的指针,指向图像某个部分的指针(mitk::ImageDataItem)则可选。由于构造器可能抛出 mitk::Exception,所以尽量使用try–catch语句。可能的错误包括无效图像、维度不对等等。

如果只需一个指向图像的指针,下面代码展示了如何获得一个const或 non-const指针。 mitk::ImageReadAccessor只提供了一个指向image data 的const void* 指针,而mitk::ImageWriteAccessor提供了一个 void*指针。

// we assume you already have an mitk::Image::Pointer image

try
{
  mitk::ImageReadAccessor readAccess(image, image->GetVolumeData(0));
  const void* cPointer = readAccess.GetData();

  mitk::ImageWriteAccessor writeAccess(image);
  void* vPointer = writeAccess.GetData();
}
catch(mitk::Exception& e)
{
  // deal with the situation not to have access
}

注意,write access完成后应显示调用Modified()函数。

访问图像数据更为方便的途径是mitk::ImagePixelReadAccessor和mitk::ImagePixelWriteAccessor。它们有基于pixel index的set和get方法。这两个都是模板类,需要事先知道pixel type和image dimension。

// we assume you already have an mitk::Image::Pointer image

try
{
  itk::Index<2> idx = {{ 12, 34 }};

  mitk::ImagePixelReadAccessor<short,2> readAccess(image, image->GetSliceData(2));
  short value = readAccess.GetPixelByIndex(idx);

  mitk::ImagePixelWriteAccessor<short,2> writeAccess(image, image->GetSliceData(4));
  writeAccess.SetPixelByIndex(idx, 42);
}
catch(mitk::Exception& e)
{
  // deal with the situation not to have access
}

Additional properties

image accessor构造器函数可选一些行为。使用枚举(比如mitk::ImageAccessorBase::ExceptionIfLocked)指明具体属性。如果请求的image part被锁住,ExceptionIfLocked将导致异常抛出。

try
{
  mitk::ImageReadAccessor imageAccess(image, image->GetSliceData(2), mitk::ImageAccessorBase::ExceptionIfLocked);
  const void* pointer = imageAccess.GetData();
}
catch(mitk::MemoryIsLockedException& e) {
  // do something else
}
catch(mitk::Exception& e) {
  // deal with the situation not to have access
}

克隆MITK image

mitk::Image::Pointer testMethod(const mitk::Image* image)
{
  mitk::Image::Pointer nIm = image->Clone();
  return nIm;
}

克隆还可人工完成,这需要复制Geometry,visual Data以及其他具体属性。最简单的方式是首先调用Image::Initialize(const Image * image),这会复制geometry,但不会复制data或各种属性。然后,复制图像data(比如用SetVolume),如有需要,用SetPropertyList(image->GetPropertyList())复制属性。

继承mitk Image

通常应该避免继承mitk::Image。原因是继承后的类可能无法与已经写好的各种filters愉快地合作。当然,如果你非要继承,还是查查相关文档,看看一些继承的例子为好。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值