Advertisement

医学图像处理_医学图像处理案例(十二)——最小路径提取算法

阅读量:

今天将介绍人体血管中两点间最小路径提取的案例分析。1、最小路径提取算法 最小路径提取算法在多个研究领域具有广泛应用,在医学图像分析、机器人导航等领域表现突出。2008年,来自昆士兰科技大学的研究人员Dan Mueller开源了一种基于Fast Marching方法的最小路径提取算法,其原理如下:Fast Marching方法计算到达函数T的梯度时会形成与波前正交的方向,在这种情况下仅存在一个局部极小值即全局极小值.为了从给定种子(路径终点)反向传播至起点获取最短路径,起点与终点均被隐式地包含在到达函数T中.这一过程可采用梯度下降法及正阶梯度下降法实现.

68ffa7ae1e9ac1cc9148f40fbd879d25.png

2. 采用基于ITK的算法实现最小路径提取 Dan Mueller开发了基于ITK的最小路径提取算法,并提供了完整的C++源码可通过原文链接获取。该算法在实际应用中通常需要满足以下三个条件:首先, 需要采用归一化(0-1)的速度场生成到达场; 其次, 输入包括单个起点、单个终点以及一组或多组中间点(即航线附近的点); 最后, 需要搭配梯度下降方向进行优化以达到最速下降效果。此外, 该算法支持多种编程语言接口, 包括但不限于C++与Python两种主流语言, 文章随后提供了一个完整的C++示例, 并附上了Python安装指南。

复制代码
    // General includes#include #include // ITK includes#include "itkNumericTraits.h"#include "itkImage.h"#include "itkImageFileReader.h"#include "itkImageFileWriter.h"#include "itkPolyLineParametricPath.h"#include "itkNearestNeighborInterpolateImageFunction.h"#include "itkLinearInterpolateImageFunction.h"#include "itkArrivalFunctionToPathFilter.h"#include "itkSpeedFunctionToPathFilter.h"#include "itkPathIterator.h"#include "itkGradientDescentOptimizer.h"#include "itkRegularStepGradientDescentOptimizer.h"#include "itkIterateNeighborhoodOptimizer.h"#include "itkRescaleIntensityImageFilter.h"int example_gradientdescent(int argc, char* argv[]){  // Typedefs  constexpr unsigned int Dimension = 3;  using PixelType = float;  using OutputPixelType = unsigned char;  using ImageType = itk::Image< PixelType, Dimension >;  using ucharImagetype = itk::Image< OutputPixelType, Dimension >;  using OutputImageType = itk::Image< OutputPixelType, Dimension >;  using ReaderType = itk::ImageFileReader< ucharImagetype >;  using WriterType = itk::ImageFileWriter< OutputImageType >;  using PathType = itk::PolyLineParametricPath< Dimension >;  using PathFilterType = itk::SpeedFunctionToPathFilter< ImageType, PathType >;  using CoordRepType = PathFilterType::CostFunctionType::CoordRepType;  using PathIteratorType = itk::PathIterator< OutputImageType, PathType >;  try  {    // Get filename arguments    ReaderType::Pointer reader = ReaderType::New();    reader->SetFileName("10.nii.gz");    reader->Update();    typedef itk::RescaleIntensityImageFilter      rescaleIntensityType;    rescaleIntensityType::Pointer rescaleFilter = rescaleIntensityType::New();    rescaleFilter->SetInput(reader->GetOutput());    rescaleFilter->SetOutputMinimum(0.0);    rescaleFilter->SetOutputMaximum(1.0);    rescaleFilter->SetNumberOfThreads(NUM_THREADS);    rescaleFilter->Update();    // Read speed function    ImageType::Pointer speed = rescaleFilter->GetOutput();    speed->DisconnectPipeline();    // Create interpolator    using InterpolatorType = itk::LinearInterpolateImageFunction;    InterpolatorType::Pointer interp = InterpolatorType::New();    // Create cost function    PathFilterType::CostFunctionType::Pointer cost =      PathFilterType::CostFunctionType::New();    cost->SetInterpolator(interp);    // Create optimizer    using OptimizerType = itk::GradientDescentOptimizer;    OptimizerType::Pointer optimizer = OptimizerType::New();    optimizer->SetNumberOfIterations(1000);    std::cout << "GetLargestPossibleRegion:" << speed->GetLargestPossibleRegion() << std::endl;    // Create path filter    PathFilterType::Pointer pathFilter = PathFilterType::New();    pathFilter->SetInput(speed);    pathFilter->SetCostFunction(cost);    pathFilter->SetOptimizer(optimizer);    pathFilter->SetTerminationValue(2);    // Setup path points    PathFilterType::PointType start, end, way0;    //this is 2d image seed points    /*end[0] = 289; end[1] = 252;    start[0] = 232; start[1] = 490;    way0[0] = 194; way0[1] = 309;*/    //this is 3d image seed points    end[0] = 210; end[1] = 234; end[2] = 1;    start[0] = 191; start[1] = 178; start[2] = 169;    way0[0] = 218; way0[1] = 210; way0[2] = 192;    // Add path information    using PathInformationType = PathFilterType::PathInformationType;    PathInformationType::Pointer info = PathInformationType::New();    info->SetStartPoint(start);    info->SetEndPoint(end);    info->AddWayPoint(way0);    pathFilter->AddPathInformation(info);    // Compute the path    pathFilter->Update();    // Allocate output image    OutputImageType::Pointer output = OutputImageType::New();    output->SetRegions(speed->GetLargestPossibleRegion());    output->SetSpacing(speed->GetSpacing());    output->SetOrigin(speed->GetOrigin());    output->Allocate();    output->FillBuffer(itk::NumericTraits::Zero);    // Rasterize path    for (unsigned int i = 0; i < pathFilter->GetNumberOfOutputs(); i++)    {      // Get the path      PathType::Pointer path = pathFilter->GetOutput(i);      // Check path is valid      if (path->GetVertexList()->Size() == 0)      {        std::cout << "WARNING: Path " << (i + 1) << " contains no points!" << std::endl;        continue;      }      // Iterate path and convert to image      std::cout << path->GetVertexList()->Size() << std::endl;      for (int pathI = 0; pathI < path->GetVertexList()->Size(); pathI++)      {        std::cout << path->GetVertexList()->at(pathI);      }      PathIteratorType it(output, path);      for (it.GoToBegin(); !it.IsAtEnd(); ++it)      {        it.Set(itk::NumericTraits::max());      }    }    // Write output    WriterType::Pointer writer = WriterType::New();    writer->SetFileName("MinimalPath.nii.gz");    writer->SetInput(output);    writer->Update();  }  catch (itk::ExceptionObject & err)  {    std::cerr << "ExceptionObject caught !" << std::endl;    std::cerr << err << std::endl;    getchar();    return EXIT_FAILURE;  }}int main(int argc, char* argv[]){  return example_gradientdescent(argc, argv);}

Python安装指令:

复制代码
    pip install itk-minimalpathextraction

3、最小路径提取效果(2D与3D) 在DSA血管系统与CTA血管系统中分别进行了验证;其中图中显示的是血管原始图像;这些红色标记点即代表了最小路径提取的结果。

b4e4e12ef8d405c6f5d1f85664e4d08f.png
cd1a743619984a7915aecfb1086cece6.png

如果碰到任何问题,随时留言,我会尽量去回答的。

全部评论 (0)

还没有任何评论哟~