ITK 序列图像处理




#include "itkGDCMSeriesFileNames.h"
#include "itkImageSeriesReader.h"
#include "itkImageSeriesWriter.h"

#include "itkImageFileReader.h"//读取头文件
#include "itkImageFileWriter.h"//写入头文件
#include "itkGDCMImageIO.h"//ImageIo头文件
#include "itkIntensityWindowingImageFilter.h"//调窗处理头文件
#include "itkBinaryThresholdImageFilter.h"//二值门限处理头文件
#include "itkBinaryBallStructuringElement.h"//基本球形
#include "itkBinaryErodeImageFilter.h"//腐蚀头文件
#include "itkBinaryDilateImageFilter.h"//膨胀头文件
#include "itkGrayscaleFillholeImageFilter.h"//灰度图像孔洞填充
#include "itkBinaryFillholeImageFilter.h"//二值图像孔洞填充
#include "itkRescaleIntensityImageFilter.h"//像素值映射头文件
#include "itkGradientMagnitudeImageFilter.h"//梯度强度头文件
#include "itkMultiplyImageFilter.h"//图像相乘
#include "itkVotingBinaryHoleFillingImageFilter.h"
#include "itkVotingBinaryIterativeHoleFillingImageFilter.h"
#include "itkRecursiveGaussianImageFilter.h"
#include "itkConnectedThresholdImageFilter.h"//区域生长
#include "itkImage.h"
#include "itkCastImageFilter.h"//类型转换
#include "itkCurvatureFlowImageFilter.h"//平滑处理
#include "itkShiftScaleImageFilter.h"//取反

int main(int argc, char* argv[])
{


    //选择像素类型和图像维度,生成读写图片类型
    typedef   float           InternalPixelType;
    const     unsigned int    Dimension = 3;
    typedef itk::Image< InternalPixelType, Dimension >  InternalImageType;
    typedef itk::Image< signed short, Dimension >  InternalImageType1;
    
    typedef  float          OutputPixelType;
    const unsigned int      OutputDimension = 2;
    typedef itk::Image< OutputPixelType, OutputDimension > OutputImageType;


    //用图片类型作为参数实例化一个滤波器类型,通过调用实例化对象的 New()方式来创建的,并将结果指向itk::SmartPointers
    typedef  itk::ImageSeriesReader< InternalImageType > ReaderType;
    typedef  itk::ImageSeriesWriter<  InternalImageType1, OutputImageType  > WriterType;//自动在输入和输出之间转换

    ReaderType::Pointer reader = ReaderType::New();
    WriterType::Pointer writer = WriterType::New();
    //智能指针:


    //GDCMImageIO对象被作为读写滤波器使用的ImageIO的对象连接,找到合适的ImageIO类去执行IO操作的itk::ImageIOFactory机构
    typedef itk::GDCMImageIO             ImageIOType;
    ImageIOType::Pointer gdcmIO = ImageIOType::New();

    //文件生成器 GDCMSeriesFileNames将会搜索这个目录并生成DICOM文件名的序列
    typedef itk::GDCMSeriesFileNames     NamesGeneratorType;
    NamesGeneratorType::Pointer namesGenerator = NamesGeneratorType::New();
    namesGenerator->SetInputDirectory("D:/leg_dcm/");//输入目录

    //文件目录(地址)通过GetFileNames()返回
    const ReaderType::FileNamesContainer& filenames = namesGenerator->GetInputFileNames();
    reader->SetImageIO(gdcmIO);
    reader->SetFileNames(filenames);


    //异常处理是C++语言中的一个标准部分 出现异常课跳出程序
    //异常处理中加入输出,可现实异常类型*
    try
    {
        reader->Update();
    }
    catch (itk::ExceptionObject& excp)
    {
        std::cerr << "Exception thrown while writing the image" << std::endl;
        std::cerr << excp << std::endl;
        std::cout << "succed1 " << std::endl;
        system("pause");
        return EXIT_FAILURE;
    }


    //调窗处理
    //1.窗宽窗位是CT图像特有的概念,MRI图像中可没有此概念
    //2.CT 图像必须先转换成 HU值再做窗宽窗位调整
    //3.nii格式的图片自动将灰度值转化为HU值;dcm格式的图不会将原始数据自动转化为Hu
    //4.CT值和灰度值属于不同的概念.CT值属于医学领域的概念,通常称亨氏单位(hounsfield unit ,HU),反映了组织对X射线吸收程度
    //5.窗宽是CT图像上显示的CT值范围,窗位是窗的中心位置
    typedef itk::IntensityWindowingImageFilter<InternalImageType, InternalImageType >  IntensityFilterType;
    IntensityFilterType::Pointer intensityWindowing = IntensityFilterType::New();
    intensityWindowing->SetWindowMinimum(124);//最小窗值
    intensityWindowing->SetWindowMaximum(126);//最大窗值
    intensityWindowing->SetOutputMinimum(0);//
    intensityWindowing->SetOutputMaximum(255); // 
    intensityWindowing->SetInput(reader->GetOutput());
    intensityWindowing->Update();

    //二值门限
    typedef itk::BinaryThresholdImageFilter<InternalImageType, InternalImageType > ThresholdingFilterType;
    ThresholdingFilterType::Pointer thresholder = ThresholdingFilterType::New();
    thresholder->SetInput(intensityWindowing->GetOutput());
    thresholder->SetUpperThreshold(255);//上下阈值参数设定
    thresholder->SetLowerThreshold(250);
    thresholder->SetOutsideValue(0);//输出值设定,背景为0,前景为255
    thresholder->SetInsideValue(255);
    thresholder->Update();


    //获取图像尺寸
    InternalImageType::Pointer image = thresholder->GetOutput();
    InternalImageType::RegionType region = image->GetLargestPossibleRegion();
    InternalImageType::SizeType size = region.GetSize();
    std::cout << size << std::endl;
    std::cout << size[0] << std::endl;//三个维度尺寸
    std::cout << size[1] << std::endl;
    std::cout << size[2] << std::endl;

    //创建掩膜
    using ImageType5 = itk::Image<float, 3>;
    ImageType5::Pointer image1 = ImageType5::New();

    ImageType5::IndexType start; //创建itk::Index对象,用来指定图像起点位置
    start[0] = 0;
    start[1] = 0;
    start[2] = 0;
    ImageType5::SizeType size1;   //创建itk::Size对象,指定图像各方向大小
    size1[0] = size[0];
    size1[1] = size[1];
    size1[2] = size[2];
    ImageType5::RegionType region1; //创建图像区域,并设置起点和大小
    region1.SetSize(size1);
    region1.SetIndex(start);
    image1->SetRegions(region1);
    ImageType5::SpacingType spacing;  //定义像素间距
    spacing[0] = 0.589844;
    spacing[1] = 0.589844;
    spacing[2] = 5.0;
    image1->SetSpacing(spacing);
    ImageType5::PointType origin;     //定义像素原点
    origin[0] = -151;
    origin[1] = -151;
    origin[2] = -325;
    image1->SetOrigin(origin);

    image1->Allocate();   //分配内存
    image1->FillBuffer(itk::NumericTraits<signed short>::Zero); //初始化图像缓冲区

    //对像素赋值
    for (int i = 0; i < size1[0]; i++) //像素所在行
    {
        start[0] = i;
        for (int k = 0; k < size1[2]; k++)
        {

            start[2] = k;
            for (int j = 0; j < size1[1] / 100 * 80; j++) //像素所在列
            {
                start[1] = j;
                image1->SetPixel(start, 1);  //给指定位置设置像素值

            }
            for (int j = size1[1] / 100 * 80; j < size1[1]; j++) //像素所在列
            {
                start[1] = j;
                image1->SetPixel(start, 0);  //给指定位置设置像素值
            }



        }
    }
    for (int i = 0; i < size1[0]; i++) //像素所在行
    {
        start[0] = i;
        for (int k = 0; k < size1[2] - 78; k++)
        {

            start[2] = k;
            for (int j = 0; j < size1[1] / 100 * 84; j++) //像素所在列
            {
                start[1] = j;
                image1->SetPixel(start, 1);  //给指定位置设置像素值

            }
            for (int j = size1[1] / 100 * 84; j < size1[1]; j++) //像素所在列
            {
                start[1] = j;
                image1->SetPixel(start, 0);  //给指定位置设置像素值
            }



        }
    }

    //掩膜处理,提取感兴趣区域
    typedef itk::MultiplyImageFilter<InternalImageType, ImageType5, InternalImageType >FilterType2;
    FilterType2::Pointer multfilter = FilterType2::New();
    multfilter->SetInput1(image);
    multfilter->SetInput2(image1);
    try
    {
        multfilter->Update();
    }
    catch (itk::ExceptionObject& excep)
    {
        std::cerr << "Exception caught !" << std::endl;
        std::cerr << excep << std::endl;
        std::cout << "succed " << std::endl;
        system("pause");
        return EXIT_FAILURE;
    }

    //01取反
    typedef itk::ShiftScaleImageFilter< InternalImageType, InternalImageType >ShiftScaleType0;
    ShiftScaleType0::Pointer shiftScale_mask = ShiftScaleType0::New();
    shiftScale_mask->SetInput(multfilter->GetOutput());
    shiftScale_mask->SetShift(-1);
    shiftScale_mask->SetScale(-1);
    shiftScale_mask->Update();

        
    //平滑处理
    typedef itk::CurvatureFlowImageFilter< InternalImageType, InternalImageType > CurvatureFlowImageFilterType;
    CurvatureFlowImageFilterType::Pointer smoothing = CurvatureFlowImageFilterType::New();
    smoothing->SetInput(shiftScale_mask->GetOutput());
    smoothing->SetNumberOfIterations(6);
    smoothing->SetTimeStep(0.625);
    smoothing->Update();


    //区域生长法
    typedef itk::ConnectedThresholdImageFilter< InternalImageType, InternalImageType > ConnectedFilterType;
    ConnectedFilterType::Pointer connectedThreshold = ConnectedFilterType::New();
    const InternalPixelType lowerThreshold = -1;//提取区域上下门限阈值
    const InternalPixelType upperThreshold = 1;
    connectedThreshold->SetLower(lowerThreshold);
    connectedThreshold->SetUpper(upperThreshold);
    connectedThreshold->SetReplaceValue(255);//设置提取区域像素值,其余区域默认为0
    InternalImageType::IndexType  index;//选取种子点
    index[0] = 0;
    index[1] = 0;
    index[2] = 0;
    connectedThreshold->SetSeed(index);
    connectedThreshold->SetInput(smoothing->GetOutput());
    connectedThreshold->Update();


    //01取反
    typedef itk::ShiftScaleImageFilter< InternalImageType, InternalImageType >ShiftScaleType0;
    ShiftScaleType0::Pointer shiftScale_mask1 = ShiftScaleType0::New();
    shiftScale_mask1->SetInput(connectedThreshold->GetOutput());
    shiftScale_mask1->SetShift(-1);
    shiftScale_mask1->SetScale(-1);
    shiftScale_mask1->Update();


    //形态学处理
    //用于二值图像的构造成员
    typedef itk::BinaryBallStructuringElement< InternalPixelType, 3  > StructuringElementType;
    StructuringElementType  structuringElement;
    structuringElement.SetRadius(1);   //领域大小为3*3*3
    structuringElement.CreateStructuringElement();

    typedef itk::BinaryErodeImageFilter <InternalImageType, InternalImageType, StructuringElementType >  ErodeFilterType;// 腐蚀,需要用输入、输出图像类型和构造成员实例化
    ErodeFilterType::Pointer  binaryErode = ErodeFilterType::New();
    binaryErode->SetInput(shiftScale_mask1->GetOutput());
    binaryErode->SetKernel(structuringElement);
    binaryErode->SetErodeValue(255);
    binaryErode->Update();


    //类型转换
    typedef itk::CastImageFilter< InternalImageType, InternalImageType1 > CastingFilterType;
    CastingFilterType::Pointer caster = CastingFilterType::New();
    caster->SetInput(binaryErode->GetOutput());
    caster->Update();


    //输出文件夹
    const char* outputDirectory = "D:/sus7/";
    itksys::SystemTools::MakeDirectory(outputDirectory);
    //设置输出文件夹
    namesGenerator->SetOutputDirectory(outputDirectory);
    writer->SetFileNames(namesGenerator->GetOutputFileNames());
    //用原来的文件头
    writer->SetMetaDataDictionaryArray(reader->GetMetaDataDictionaryArray());
    writer->SetInput(caster->GetOutput());
    writer->SetImageIO(gdcmIO);
    try
    {
        writer->Update();
        //writer->UpdateLargestPossibleRegion();
    }
    catch (itk::ExceptionObject& excep)
    {
        std::cerr << "Exception caught !" << std::endl;
        std::cerr << excep << std::endl;
        std::cout << "succed " << std::endl;
        system("pause");
        return EXIT_FAILURE;
    }

    system("pause");
    return EXIT_SUCCESS;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值