前言
在阅读肺结节CT图像处理的相关论文时,注意到很多作者都使用的是一款软件Mevislab。Mevislab是一款用于图像处理,尤其是医疗CT图像领域的,快速原型开发平台,做学术研究和个人学习是免费自由使用的(可自由开发的模块有限),
商业环境下使用时收费的。我曾发邮件咨询过,大概每年2万2(2017年3月份)。下图是工作台样例:
官网地址:Mevislab
论坛地址:Mevislab论坛 ,很多问题自这里可以咨询,论坛活跃用户不多,一般可能要隔两天才有人回,可能是时差。
一 特点
多平台支持:Mac,Linux,Windows
模块多:当前有920多标准模块,总共有3000多(包括360多ITK模块、1470个VTK模块、),基本涵盖了所有的图像处理模块,比如腐蚀、膨胀、阈值分割、区域增长等。在实际做图像处理时,直接拉模块连起来就可以。
支持脚本:目前支持python和C++,可以在工作台里直接调用python(使用RunPythonScripts模块)。C++ 可以直接重新定义mevislab内置的模块,或者自己重写一个模块。
自由高效:摸熟之后,你会发现它的高效、简洁,模块之间自由组合(流程上下衔接)
强大:强大的体现是,2D,3D(官方说法可以支持6D)都可以处理。尤其是3D渲染,简直神器,即刻呈现处理效果。
二 使用
2.1 基本使用
首先,构建一个最基本的图像处理流程
其中ImageLoad
,Threshold
,SoView2D
这三个模块可以在任务栏的module
中搜索找到,或者直接搜索框里输入即可得到。我们可以在图中看到不同的module有不同的颜色,接口处的形状也不同,有尖三角,有半圆形,它们代表不同的意义。具体的请参考官方文档,本文重点不讨论这个。
常规的图像处理流程包括,载入图像,处理算法,展现模块。其中载入图像模块如上图ImageLoad
,可以载入普通JPEG
2.2 基本模块
模块类型
类型 | 外形 | 特征 |
---|---|---|
ML模块(蓝色) | 基于分页的,命令驱动的体素处理 | |
开放的素材模块(可以用来组合和协助构建处理过程)(绿色) | 视觉场景图(3D),名称转换,所有模块以So(scene object)开头 | |
宏模块(棕色) | 组合其他模块类型,允许层次继承和脚本交互 |
连接器
外观 | 形状 | 定义 |
---|---|---|
三角形 | ML 图像 | |
半圆形 | 场景素材 | |
方形 | 基本对象:指向数据结构的指针 |
链接
类型 | 外观 | 特征 |
---|---|---|
数据链接(连接器链接) | 连接器之间的直接链接。不同的连接器会有不同的颜色,蓝色的为ML,绿色的为开放素材,棕色的为基本类型 | |
参数链接(域链接) | 模块之间或模块内部的参数的链接形成的链接 |
三 实现一个轮廓过滤
假设我们的轮廓过滤步骤为: 载入图像a–>均值化[b]–>形态学膨胀操作[c]–>求差值[b,c]–>查看图像
在Mevislab的工作台新建网络,并载入模块LoadImage
,Convolution
,Morphology
,Arithmetic2
。这些模块可以直接在搜索框搜索到。将这些模块按照如下图连接起来,连接操作鼠标左键点击模块的连接点,然后拖到下一个模块,松开即可。
参数调整
调整参数时,双击模块面板,有些隐含的参数需要右击面板–>show autopanel
。如果想让模块A中的参数param_a赋值给模块B中的参数param_b,在A面板中点击param_a拖住(可以看到此时面板中的param_a处出现了一个蓝色的箭头),拉到面板B中的参数param_b处(也看到蓝色箭头激活)。如何保持参数同步(模块之间参数赋值),示例如下:
其他参数设置参考下图:
四 图像操作和处理
4.1 图像操作
ImageLoad
:打开图像,格式可以为DICOM
,TIFF
,DICOM/TIFF
,RAW
,LUMISYS
,PNM
,Analyze
,PNG
,JPEG
LocalImage
:与ImageLoad
类似,载入的是相对于Mevislab安装位置或当前网络位置的图像ImageSave
:存储图像,以DICOM
,TIFF
,DICOM/TIFF
,RAW
,LUMISYS
,PNM
,Analyze
,PNG
,JPEG
这些格式
4.2 图像属性
Info
:展示当前连接的输入图像的信息,比如图像尺寸,page size,体素size,总容积,世界矩阵等。MinMaxScan
:扫描输入并更新输出图像的最大最小值,可以改变数据类型。ImagePropertyConvert
:允许自由改变图像的page size,最大、最小值、数据类型、世界矩阵ImageStatistics
:计算输入图像体素的一些统计特性。
4.3 基本图像处理
SubImage
:从输入图像中基于体素、世界坐标的起止,尺寸抽取子图。也可以用于抽取比输入图像更大的区域Resample3D
:在3D图像的任意平面抽样,有17个filter可以使用。Reformat
:将图像重新格式化为一副引用图像,或者通过SoView2D/SoOrthoView2D
创建重新格式化的叠加。Scale
:将图像缩放到一个指定间隔,来源和目标缩放间隔可以自定义。Arithmetic1
:对一副图像做算术运算。比如Add
操作,则是对图像中体素的每个值加上一个常量。Arithmetic2
:对两幅图像做算数运算。比如Add
操作,则是将图像1中每个体素的值加到图像2上。Mask
: 用图像2中的mask对图像1进行mask操作。(有Mask模块中有不同选项)TestPattern
:基于指定的尺寸,page size,数据类型和模式生成一副测试图像AddNoise
: 基于标量输入图像产生噪音数据,比如高斯噪音、盐粒噪音等。
4.4 过滤器
Convolution
:标准卷积,比如均值卷积,高斯卷积,拉普拉斯卷积和Sobel。ExtendedConvolution
:提供与标准卷积类似的过滤器,但是更加灵活的Kernel size和kernel geometryRank
: 基于秩的卷积,比如最小、最大、中值、Rank、indexMorphology
: 形态学操作,比如腐蚀和膨胀CalculateGradient
:计算输入图像每个体素周围的值得坡度(梯度)
4.5 分割
Threshold
: 将图像转换为二值图像,根据阈值IntervalThreshold
: 通过过滤掉在指定值域范围的像素值来处理一副图像,在值域范围外的可以指定其他值或者为0。RegionGrowing
:区域增长算法,提供简单的基于阈值或间隔的 1D/2D/3D/4D的区域增长算法。需要设置阈值或间隔和最少一个种子节点。RegionGrowingMacro
:是RegionGrowing
的宏拓展,添加了自定义的marker 编辑。ComputeConnectedComponents
:在2D/3D灰度图上进行连通组件分析。
4.6 可视化
2D可视化
View2D
: 以2D切片的形式查看3D图像。View2DExtensions
: 封装了一系列的viewer,这些viewer都是常用于连接2D viewer的拓展,包括以切片形式查看、放大缩小、窗口调整。SoView2D
: 在2D viewer中呈现一个容积(volume)图像的一个切片。SoRenderArea
:提供一个开放的Inventor(素材)渲染器和Mevislab窗口内部的事件处理机制。SoView2DOverlay
: 将一副2D图像与另外一副混合。SoView2DPosition
: 显示2Dviewer 中最近点击的位置,显示形式可以自定义为圆形、空间矩形或叉叉。SoView2DRectangle
: 在2D viewer中交互式的绘制或调整一个2D矩形。虽然此模块名称带2D,其实也可以操作3D。SoMouseGrabber
:抓取Inventor sence中的鼠标事件并将其转化为float类型的x,y域。SoKeyGrabber
:监听Inventor sence种的键盘事件,并触发依赖于不同键盘key按压操作的field。OrthoView2D
: 提供一个2D view来展现三个正交视图方向的输入图像。SoOrthoView2D
: 在2D viewer中渲染一副体素(volume)图像的正交切片SynchroView2D
: 提供两个2D viewer,它们通过其世界坐标轴同步。
3D 视图
SoGVRVolumeRenderer
:一个基于八卦的渲染器,允许3D/4D图像的高质量体素渲染。此模块继承自允许设置渲染参数的拓展模块集合。SoExaminerViewer
: 提供开放的Inventor渲染和Mevislab窗口内部的时间操作。开放Inventor渲染比如背景色、透明度类型、绘画风格等。View3D
:直接3D查看图像。SoBackground
: 渲染开放Inventor sence中背景色的颜色坡度。
4.7 LookUp Table
此模块用于编辑网络中其他模块的参数(此模块后续再补充,没怎么用)
ApplyLUT
:在输入图像上应用lookup table(LUT)。输入图像中的体素值用作LUT索引值,LUT实体值被缩放到最大实体参数,并存储到输出图像。SoLUTEditor
:允许编辑RGBA LUT 并输出MLLut对象。
4. 8 Markers
XMarkerListContainer
:存储了XMarker对象列表为XMarkerList对象。其内容可以呈现,编辑和保存。一个XMarker对象由一个6D Position,一个3D Vector,一个Type,一个Name属性组成。SoView2DMarkerEditor
: 允许在2D 视图上交互式放置、编辑和展现markers。So3DMarkerEditor
: 在3D中呈现markers并提供可能的交互式编辑markers。
4.9 Curves
ProfileCurve
:从一副图像的任意数据维度抽取概要轮廓,通过沿着指定的线路读取输入图像的体素值。SoDiagram2D
:呈现2D曲线,比如时间序列,灰度缩放概要,直方图等。
4.10 Contours
CSOManager
:允许编辑CSOs和CSOGroup设置参数和默认参数,以及维持CSO和CSOGroup的整齐度。SoCSO3DVis
:在3D中某个CSOList中的CSOs以Open Inventor sence开启可视化。需要对input可用的CSOList(比如通过CSOManager)CSOIsoGenerator
:允许以固定的ISO值对整幅图生成iso轮廓。需要一个可用填充值的CSOList(比如CSOManager)SoView2DCSOExtensibleEditor
:允许编辑和拖拽CSOs。与CSOManager,一个CSO子编辑器和输出用的2D Viewer结合使用,SoCSOSplineEditor
:允许徒手或一个点一个点的生成CSOs。SoCSOEllipseEditor
:允许生成椭圆或圆形CSO。
4.10 Surface objects
SoWEMRenderer
:将一个WEM渲染为一个Open Inventor senceWEMIsoSurface
:以固定阈值生成标量体积图像的ISO表面WEMSmooth
: 使用一个表面平滑(拉普拉斯)来平滑WEM,或者表面的平滑。SoView2DWEMEditor
: 在特定球形范围交互式WEM表面变形。
五 创建 Open Inventor Scene
此模块主要利用Mevislab提供的各种自木块来构建各类视图模型,Open Inventor是一个面向对象的3D开发工具。Inventor scenes以场景图的形式组织。一个场景图由代表即将绘制的3D对象的节点,3D对象的属性,与其他节点结合的节点组成层次树,其他如摄像机、灯光等组成。
注意Open Inventor中的遍历路径如下,这对于如何构建场景图很关键。
Open Inventor模块的函数有:
Draggers and manipulators
Group nodes
Light sources
Transformations
Cameras
3D viewers
Geometric objects (Spheres, Cones, 3D Text, Nurbs, Triangle Meshes, etc.)
Object properties (Textures, Colors, Materials, etc.)
注意:在ML模块中模块的域值更新是同步的,但是在Open Inventor中是异步的,更改值之后会先存储在延迟队列中。
关于如何构建这些场景,示例图如下:
你可以将Mevislab当做一个3D建模工具玩。
六 构建宏模块
宏模块可以通过MDL(Mevislab Definition Lanague)和python或JavaScript脚本实现。宏的功能与其他模块类似,可以理解为一系列完成某种功能的模块的集合被封装成了一个模块。
构建一个宏模块,你需要走如下三步。
6.1 构建宏
首先,你得把一系列用于完成特定任务的模块串起来定义好,放入工作台。如下图:
定义好之后将网络存储在某个位置,比如命名为test_macro.mlab。
然后选择File
→ Project Wizard
并选择 Macro
。然后设置宏的一些参数,其中打星号的是必须的。
然后下一步,选择Network File name
时选择刚保存test_macro.mlab。点击创建之后会自动创建如下文件
此时,即可在搜索栏搜到刚刚定义的宏模块。
6.2 给宏添加宏参数和面板
右键点击刚刚创建的宏的面板选择related files,选择mevislab_macro.script编辑此脚本。此脚本包含了区域:
interface:定义宏的输入输出。
Commands:定义在此宏的某些field活动时要执行的脚本文件
window: 定义了宏的面板,在面板上设置参数。
参考示例:
1 | Interface { |
6.3 python脚本
上一步的scipt脚本中,Command所使用的test_macro.py需要编写。示例如下:
1 | # ----------------------------------------------------------------------------- |
注意观察,python脚本中如何调用和控制参数。其中的ctx
是默认的上下文,它可以访问当前网络中任何其他模块的任何field。比如此处的SoCone.height
,其中的SoCone
是一个模块,height是该模块的一个field,如果它有其他实例名example_name,则使用example_name.height也可以直接访问。 此处通过ctx.field("SoCone.height").value
访问值,而ctx.field("SoCylinder.height").value = shaftLength
来改变值。
七 渲染
其实Mevislab用起来只是快速实现模型,但是无法用于生产环境,处理速度太慢。平常用它来做渲染还是不错的,做3D渲染几乎不逊色于一般的3D建模软件。