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

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血管系统中分别进行了验证;其中图中显示的是血管原始图像;这些红色标记点即代表了最小路径提取的结果。


如果碰到任何问题,随时留言,我会尽量去回答的。
全部评论 (0)
还没有任何评论哟~
