超声三维重建算法研究

超声三维重建算法

在三维超声弹性成像中,三维重建是将二维弹性图转化成三维超声弹性图的关键一步。三维重建算法按照其原理的不同可以分为三类:基于像素的三维重建算法(PBM)基于体素的三维重建算法(VBM)基于函数的三维重建算法(FBM)

阿远学长在今天给大家详细讲解一下关于基于像素的算法理论。

基于像素的算法(PBM)

基于像素的三维重建算法也被称为**“用像素找体素”**的方法,其基本流程包括两个阶段:像素分布和体素填补。

第一阶段是像素分布阶段,将二维图像序列上的像素点通过坐标转换映射到三维成像空间中的对应位置,并将该像素值赋值给体素;第二阶段是体素填补阶段,遍历三维成像空间中所有的体素,找出空体素,再通过插值算法来填补空体素。

像素分布阶段,将原始的二维超声图像上的像素点通过坐标转换映射到三维成像空间中的对应位置,并将该像素值赋值给对应的体素。这个过程中,每个像素点都被转换到了三维空间中,它们的灰度值就相当于是对应位置的超声数据。

体素填补阶段,会遍历标准网格中的每一个体素,如果当前体素是一个空体素,则搜索当前空体素的一定邻域范围,根据邻域内的体素计算当前空体素的灰度值。如果某个空体素的邻域范围内都没有出现非空体素,则保留当前空体素的值。这个过程中,对于没有被像素映射到的体素,会使用插值算法来填补缺失的灰度值,从而获得一个完整的三维超声图像。

通过这两个阶段的处理,像素分布阶段负责将二维超声图像转化为三维数据,而体素填补阶段则处理了三维数据中的空洞部分,最终生成了一个完整的三维超声图像。这种方法可以实现超声图像的三维重建,为医学诊断提供了可靠的图像基础。

PNN 算法是典型的 PBM 算法 ,如图所示.

PNN算法示意图

我们知道三维网格中体素大小是自定义的,当相邻两帧 B 超图像的间距大于单位体素大小时,三维网格中会存在一些空体素点。因此需要对这些灰度值为零的体素进行插值,常用的一种插值方法是根据最近邻的非空体素灰度值对当前体素进行赋值,这种办法简单而且直接,可以应用于一些对重建图像质量不高的临床应用中;还可以对空体素点邻域范围内的非空体素值求平均,这种方法需要搜寻三维邻域空间,数据计算量比较大,它所需要的插值计算时间根据我们选择的邻域范围大小而定,邻域范围比较大的话所需的时间就长,反之亦然;还有一种插值方法是根据当前体素两边最近的 B 超图像横断方向上的两个非空体素进行加权平均得到。不管是哪一种插值算法,都只是对空体素点灰度值的一种近似计算,因此多多少少会带来一些误差,有时候还会带来一些伪影,比如某个切平面上的体素中既有直接从二维超声图像直接映射得到的,也有通过邻域体素求平均计算得来的,这种情况下,体素与体素之间就会出现明显的分界线。

常用的空体素插值方法有两种,第一种是将二维超声图像序列中的每一个像素点映射到三维空间中的某个体素,然后遍历三维体素阵列,若遇到某一个体素为空值,则搜索其3×3×3 邻域内的所有体素点,若其中有一半体素的灰度值非空,则将这些体素求平均值或者中值赋给当前空体素点,否则向外扩展邻域空间范围到 5×5×5 大小,若其中有一半体素的灰度值非空,则使用如上方法计算空体素的灰度值,否则设置该体素的灰度值为零。

第二种是将二维超声图像序列中的每一个像素点映射到三维空间上的体素中,遍历体素阵列,如果体素灰度值不为零,则遍历该体素的某个邻域范围内的所有体素,计算邻域体素与该体素的距离,将距离的倒数作为权值乘以该体素灰度值赋给邻域内的体素点,若邻域体素非空,则累加该体素的灰度值和权值,当遍历完整个三维网格,求每一个体素的平均灰度值,即为插值计算的体素灰度值。

基于体素的三维重建算法

基于体素的三维重建算法也被称为**“用体素找像素”**,其基本思想是遍历三维成像空间中每个体素,根据体素的位置找出二维图像序列中对应的像素值(一个或多个)。

然后再按照一定的插值算法,将像素值赋值给体素。

该算法遍历一个预先定义好的三维标准晶格(比如一个三维空间长方体)中的每一个体素(长方体内部的小体积),根据不同的计算方法,可以分为基于体素的赋值方法和基于体素的插值方法。

基于体素的赋值方法在体素附近搜索一个相关像素点,将该像素点的像素值赋给当前体素;

而基于体素的插值算法则在体素邻域内搜索多个像素点,并使用一些插值公式计算当前体素的值。

基于体素的赋值算法会依次遍历预先定义好的三维标准晶格中的每一个体素,在体素邻域范围内搜索一个相关像素点,并将该像素点的值赋给当前体素。

这种算法主要有:VNN 算法,它是经典的 VBM 算法之一,如图所示,VNN遍历三维网格中的每一个体素,将距离体素最近的像素点的灰度值赋给该体素。

基于体素的插值算法搜索三维体积阵列中的每一个体素的邻域范围,将邻域内的多个相关像素点通过某种插值计算得出当前体素的灰度值。

针对超声图像特点,目前使用较多的插值算法有:线性插值算法(LI)、距离加权算法(DW)、中值滤波算法(MF)和轨迹跟踪算法(PT)。

本节主要对距离加权算法(DW)进行叙述:

距离加权(DW)算法是经典的 VBM 算法之一。该算法遍历三维成像空间中每个体素,体素的灰度值由其周边邻域的所有像素值加权平均计算而得,加权系数为像素与体素距离的倒数。

数学表达式为:
I ( V c ) = ∑ k = 1 n W k I ( V p k ) ∑ k = 1 n W k I(V_c)=\frac{\sum\limits_{k=1}^n W_k I(V_p^k)}{\sum\limits_{k=1}^n W_k} I(Vc)=k=1nWkk=1nWkI(Vpk)
W k = 1 d k W_k=\dfrac{1}{d_k} Wk=dk1

其中 I ( V c ) I(V_c) I(Vc)表示当前体素的像素值, I ( V p k ) I(V_p^k) I(Vpk)为体素邻域内的第 k 个像素值, W k W_k Wk为其对应的权重, d k d_k dk为其对应的距离。

邻域的形状常见有球体、正方体等等,也有使用经过该体素的两条法线找到与其距离最近的两帧二维超声图像(分布于该体素两侧),记录法线和超声图像的交点和距离,并在两帧二维超声图像中找距离最近的像素值加权平均来赋值,如图所示。

DW算法相关示意图

DW 算法的关键是设置合适的邻域大小。如果邻域设置的太大,则参与加权平均的像素点过多,导致成像结果平滑过度;如果邻域设置的太小,则可能有些体素周围邻域的像素值都为零,导致这些体素未被赋值,最终三维重建结果中存在断层。

还有很多基于 DW 的改进算法,这些算法的基本思想相同,区别主要在于加权均值的计算。

其中距离平方加权(SDW)算法先对邻域内各个像素点根据其与当前体素的距离倒数求加权值,其权值计算公式如下:
W k = 1 ( d k + α ) 2 W_k=\dfrac{1}{\left(d_k+\alpha\right)^2} Wk=(dk+α)21

其中 d k d_k dk表示当前体素到邻域像素点的距离 α \alpha α 表示邻域像素对当前体素数值影响的
大小
。最后对加权后的像素灰度值求中值,作为当前体素的灰度值。

自适应距离加权(ADW)算法则是在 SDW 算法基础上又做了改进,其权值计算公式如下所示:
W k = 1 ( d k + a e − b σ 2 / μ ) 2 W_k=\dfrac{1}{\left(d_k+ae^{-b\sigma^2/\mu}\right)^2} Wk=(dk+aebσ2/μ)21
其中 d k d_k dk同样表示当前体素到邻域像素点的距离, σ 2 \sigma^2 σ2 μ \boldsymbol{\mu} μ分别表示邻域范围内所有像素点灰度值的方差和均值。其中 a a a b b b 均为自定义的可调节权重参数

该算法在一定程度上保可以留超声图像的部分边缘细节,重建效果相较于上述的 DW 和 SDW 方法稍好一些。

  • 9
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
可以使用VTK中的vtkImageData和vtkMarchingCubes等类进行超声图像的三维重建。以下是基本示例代码: ```python import vtk # 读取超声图像数据 reader = vtk.vtkDICOMImageReader() reader.SetDirectoryName("path/to/dicom/files") reader.Update() # 创建vtkImageData数据 imageData = vtk.vtkImageData() imageData.SetDimensions(reader.GetOutput().GetDimensions()) imageData.AllocateScalars(vtk.VTK_UNSIGNED_SHORT, 1) imageData.SetSpacing(reader.GetOutput().GetSpacing()) imageData.SetOrigin(reader.GetOutput().GetOrigin()) imageData.GetPointData().SetScalars(reader.GetOutput().GetPointData().GetScalars()) # 进行等值面提取和渲染 contourFilter = vtk.vtkMarchingCubes() contourFilter.SetInputData(imageData) contourFilter.ComputeNormalsOn() contourFilter.SetValue(0, 1000) # 设置等值面的值 mapper = vtk.vtkPolyDataMapper() mapper.SetInputConnection(contourFilter.GetOutputPort()) actor = vtk.vtkActor() actor.SetMapper(mapper) actor.GetProperty().SetColor(1.0, 1.0, 1.0) # 设置渲染颜色 # 创建渲染窗口和渲染器 renderer = vtk.vtkRenderer() renderer.AddActor(actor) renderer.SetBackground(0.0, 0.0, 0.0) # 设置背景颜色 renderWindow = vtk.vtkRenderWindow() renderWindow.AddRenderer(renderer) renderWindow.SetWindowName("Ultrasound 3D Reconstruction") # 创建交互器 interactor = vtk.vtkRenderWindowInteractor() interactor.SetRenderWindow(renderWindow) # 启动渲染器和交互器 renderWindow.Render() interactor.Start() ``` 当然,这只是基本示例,如果要进行更复杂的超声图像处理和可视化,还需要进一步了解和学习VTK中的其他类和方法。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值