oop animation graph datatables ansible db2 Fries seo外包优化 vue绑定class android项目实例 mysql在线测试 pcie高速固态硬盘 内存计算 java 注解 python类 java正则 java中继承 java介绍 java中的队列 配置java开发环境 java匿名对象 javac java版本查看 javascript基础 莫愁脚本 圣剑世界 华为一键root工具 su版本转换器 js轮播图代码 网络文件服务器 mpg格式转换 骰子表情 电脑cmd命令大全 ps制作表格 暴力猴插件 xapk安装器 骰子gif c程序 抠图教程 win98序列号
当前位置: 首页 > 学习教程  > 编程语言

ITK 定义原点和间距 Defining Origin and Spacing

2020/9/19 15:44:05 文章标签:

尽管ITK可用于执行一般图像处理任务,但该工具包的主要目的是处理医学图像数据。在这方面,关于图像的附加信息被认为是必须的。特别是与像素之间的物理间距和图像在空间中的位置有关的信息在某些世界坐标系中是极其重要的。

图4.1说明了与itk::Image相关的主要几何概念。在这个图中,圆圈被用来代表像素的中心。假设像素的值存在为一个
位于像素中心的狄拉克函数。像素间距是在像素中心之间测量的,可以在每个维度上是不同的。图像原点与图像中第一个像素的坐标相关联。对于这个简化的示例,体素格与物理空间方向完全对齐,因此图像方向是一个恒等映射。如果立体像素点阵样本相对于物理空间进行旋转,则图像的方向将包含一个旋转矩阵。

图像间距用一个固定数组表示,其大小与图像的维数相匹配。为了手动设置图像的间距,必须创建相应类型的数组。
然后,数组中的元素应该用相邻像素中心之间的间距进行初始化。下面的代码演示了itk::Image类中处理间距和原点的可用方法。

 

#include "ItkImage.h"


static itk::Image<unsigned short, 3>::IndexType GetIndexFromMouseClick()
{
    itk::Image<unsigned short, 3>::IndexType LeftEyeIndex;
    LeftEyeIndex[0] = 60;
    LeftEyeIndex[1] = 127;
    LeftEyeIndex[2] = 93;
    return LeftEyeIndex;
}


int main(int, char* [])
{
    constexpr unsigned int Dimension = 3;
    using ImageType = itk::Image<unsigned short, Dimension>;

    ImageType::Pointer image = ImageType::New();

    //初始化图片区域
    const ImageType::SizeType size = { {200,200,200} };
    const ImageType::IndexType start = { {0,0,0} };

    /*以上两句话可以写成如下来初始化图片区域
    ImageType::SizeType size;
    size[0] = 200;
    size[1] = 200;
    size[2] = 200;

    ImageType::IndexType start;
    start[0] = 0;
    start[1] = 0;
    start[2] = 0;
    */

    //定义起始索引和图像大小之后,这两个参数用于创建一个itk::ImageRegion对象
    //该对象基本上封装了这两个概念 
    //该区域由初始索引和图像大小初始化
    ImageType::RegionType region;
    region.SetSize(size);
    region.SetIndex(start);


    //像素数据分配
    image->SetRegions(region);
    //将缓冲区初始化为零
    image->Allocate(true);

    //图像间距用一个固定数组表示,其大小与图像的维数相匹配
    ImageType::SpacingType spacing;

    //单位(例如,mm,英寸等)是由应用程序定义的
    spacing[0] = 0.33; // spacing along X
    spacing[1] = 0.33; // spacing along Y
    spacing[2] = 1.20; // spacing along Z

    //可以使用SetSpacing()方法将数组分配给图像
    image->SetSpacing(spacing);

    //使用GetSpacing()方法从图像检索间距信息
    //此方法返回对FixedArray的引用
    //然后可以使用返回的对象读取数组的内容
    //注意,使用const关键字表示不会修改数组
    const ImageType::SpacingType& sp = image->GetSpacing();

    std::cout << "Spacing=";
    std::cout << sp[0] << "," << sp[1] << "," << sp[2] << std::endl;

    //下面的代码演示了如何创建和分配适合初始化映像源的变量
    //第一个像素的中心在N-D的坐标
    ImageType::PointType newOrigin;
    newOrigin.Fill(0.0);
    image->SetOrigin(newOrigin);

    //还可以使用GetOrigin()方法从图像中检索原点
    // 这将返回对一个点的引用
    //该引用可用于读取数组的内容
    //再次注意,使用const关键字表示不会修改数组内容
    const ImageType::PointType& origin = image->GetOrigin();
    std::cout << "Origin = ";
    std::cout << origin[0] << ", " << origin[1] << ", " << origin[2] << std::endl;

    //下面的代码演示了如何创建和分配适合用标识初始化图像方向的变量
    //第一个像素的中心在N-D的坐标
    ImageType::DirectionType direction;
    direction.SetIdentity();
    image->SetDirection(direction);

    //还可以使用GetDirection()方法从图像中检索方向
    //这将返回一个对矩阵的引用
    //该引用可用于读取数组的内容
    //再次注意,使用const关键字表示不能修改矩阵内容
    const  ImageType::DirectionType & direct = image->GetDirection();

    std::cout << "Direction=" << std::endl;
    std::cout << direct << std::endl;

    //一旦图像样本的间距、原点和方向被初始化,图像将正确地从物理空间坐标映射像素索引
    //下面的代码说明了如何将物理空间中的点映射到图像索引中,以便读取最近像素的内容
    //首先,必须声明itk::Point类型
    //点类型被模板化在用于表示坐标的类型和空间的维度上
    //在这种特殊情况下,点的维数必须与图像的维数匹配
    using PointType = itk::Point<double, ImageType::ImageDimension>;
    PointType point;
    point[0] = 1.45; // x 坐标
    point[1] = 7.21; // y 坐标
    point[2] = 9.28; // z 坐标


    //须提供一个索引对象来接收映射的结果
    //可以使用在图像类型中定义的IndexType实例化索引对象
    ImageType::IndexType pixelIndex;

    //image类的TransformPhysicalPointToIndex()方法将计算最接近所提供点的像素索引
    //该方法检查该索引是否包含在当前缓冲的像素数据中
    //该方法返回一个布尔值,指示结果索引是否位于缓冲区域内
    //当方法的返回值为false时,不应使用输出索引

    const bool isInside = image->TransformPhysicalPointToIndex(point, pixelIndex);

    //如果TransformPhysicalPointToIndex()方法返回True时
    if (isInside)
    {
        //GetPixel()和SetPixel()是访问像素数据的效率非常低的方法
        ImageType::PixelType pixelValue;
        pixelValue = image->GetPixel(pixelIndex);
        pixelValue += 5;
        image->SetPixel(pixelIndex, pixelValue);
    }

    //GetIndexFromMouseClick()为自定义方法,终端用户使用鼠标界面手动选择体素索引位置
    const ImageType::IndexType LeftEyeIndex = GetIndexFromMouseClick();
    ImageType::PointType LeftEyePoint;
    //TransformIndexToPhysicalPoint()方法:
    //从一个离散索引(在索引空间中)获得一个物理点(在原点和间隔信息来自的空间中)
    image->TransformIndexToPhysicalPoint(LeftEyeIndex, LeftEyePoint);

    std::cout << "===========================================" << std::endl;
    std::cout << "The Left Eye Location is " << LeftEyePoint << std::endl;

    /*这是一个矩阵
     P1          O1        D1,1  D1,2  D1,3           S1 0 0           I1
     P2    =     O2    +   D2,1  D2,2  D2,3      ∗    0 S2 0      ∗    I2
     P3          O3        D3,1  D3,2  D3,3           0 0 S3           I3
    */
    //一个Dimendion*Dimension的double类型的矩阵
    using MatrixType = itk::Matrix<double, Dimension, Dimension>;
    MatrixType SpacingMatrix;
    //矩阵中填充数值
    SpacingMatrix.Fill(0.0F);
    //得到数据放到ImageSpacing数组中
    const ImageType::SpacingType& ImageSpacing = image->GetSpacing();

    SpacingMatrix(0, 0) = ImageSpacing[0];
    SpacingMatrix(1, 1) = ImageSpacing[1];
    SpacingMatrix(2, 2) = ImageSpacing[2];

    const ImageType::DirectionType& ImageDirectionCosines = image->GetDirection();
    const ImageType::PointType& ImageOrigin = image->GetOrigin();

    //这段代码我也有点不太明白
    using VectorType = itk::Vector<double, Dimension>;
    VectorType LeftEyeIndexVector;
    LeftEyeIndexVector[0] = LeftEyeIndex[0];
    LeftEyeIndexVector[1] = LeftEyeIndex[1];
    LeftEyeIndexVector[2] = LeftEyeIndex[2];
    ImageType::PointType LeftEyePointByHand = ImageOrigin + ImageDirectionCosines * SpacingMatrix * LeftEyeIndexVector;

    return EXIT_SUCCESS;
}

 

 

 

 

 


本文链接: http://www.dtmao.cc/news_show_200301.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?