【问题标题】:How to reshape the dimension of data cube in DM with script如何使用脚本重塑 DM 中数据立方体的维度
【发布时间】:2016-09-26 11:40:27
【问题描述】:

我有一个尺寸为 1024*1024 的图像存储在 HDF5 文件中,该文件被视为切片厚度为 1 的数据立方体,(因此存储的尺寸为 1024*1024*1)。我使用 Niermann HDF5 插件 (https://github.com/niermann/gms_plugin_hdf5) 导入数据。导入后数据立方体变为1*1024*1024,显示为1像素宽、1024像素高、1024个切片图像。

在考虑重新实现插件之前,我想问一下,有没有什么办法可以“重塑”数据(如“Numpy.reshape”中的),以便正确处理维度?

谢谢!

【问题讨论】:

  • 我认为命令 Slice2() 可能会有所帮助,但我仍然无法按照“DM 脚本手册”中的说明和示例进行操作
  • 感谢您提供非常有用的链接。

标签: dm-script


【解决方案1】:

如果您不喜欢 icol、irow 和这些表达式,另一个优雅的解决方案是只使用流对象。

image ReShape3D( image input, number sx, number sy, number sz )
{
    // Perform testing
    number nPix=1
    for ( number d=0; d<input.ImageGetNumDimensions(); d++ )
        nPix *= input.ImageGetDimensionsize(d)

    if ( sx*sy*sz < nPix ) Throw( "Input image larger than provided shape." )
    if ( sx*sy*sz > nPix ) Throw( "Input image smaller than provided shape." )

    image reShaped := input.Imageclone()
    reShaped.ImageResize(3,sx,sy,sz)
    object dStream = NewStreamFromBuffer(0)
    ImageWriteImageDataToStream(input,dStream,0)
    dStream.StreamSetPos(0,0)
    ImageReadImageDataFromStream(reShaped,dStream,0)
    return reshaped
}

Image before := RealImage("Before",4,10,20,30)
before = random()
Image after := ReShape3D( before,20,10,30 )
before.ShowImage()
after.ShowImage()

【讨论】:

  • 流式处理似乎是处理 i/o 的好方法 :-)
【解决方案2】:

如果您的输入/输出数组大小在维度上不匹配(这样slice 将不起作用),那么您还可以使用以下命令将数据“流式传输”进出 1D:

number sx = 4   
number sy = 5   
number sz = 2   

image oneLine := RealImage( "1D",4, sx*sy*sz )
oneLine = icol
oneLine.ShowImage()

image reShape1Dto3D := RealImage( "1D->3D", 4, sx, sy, sz )
reShape1Dto3D = oneLine[icol + iwidth*irow + iwidth*iheight*iplane, 0 ]
reShape1Dto3D.ShowImage()

image reShape3Dto1D := RealImage( "3D->1D", 4, sx*sy*sz )
reShape3Dto1D[icol + iwidth*irow + iwidth*iheight*iplane, 0 ] = reShape1Dto3D
reShape3Dto1D.ShowImage()

这里的技巧是,您可以使用方括号来处理图像表达式中的单个值。在 3D 图像中为 [X,Y,Z],在 2D 图像中为 [X,Y],在 1D 图像中为 [X,0]。 [*]

内部变量icolirowiplane被计算表达式的X、Y、Z坐标替换,而iwidthiheightidepth被替换为尺寸大小求值的表达式。

求值表达式的大小是多少?它由该行中唯一的“已知大小”图像定义 - 左侧或右侧,因此

reShape1Dto3D = oneLine[ icol + iwidth*irow + iwidth*iheight*iplane, 0 ]

在表达式的左侧成为 reShape1Dto3D 的所有像素的 X/Y/Z 循环。对于每个三元组 (X/Y/Z),该值取自 oneLine 的计算位置。

完全一样的用在

reShape3Dto1D[ icol + iwidth*irow + iwidth*iheight*iplane, 0 ] = reShape1Dto3D

但是这里的循环再次超过了 reShape1Dto3D 的大小,因为那是行中“已知大小”的图像,即使它在右侧。

* 这种方式不支持更高维度,因为 [T,L,B,R] 已用于子区域。

【讨论】:

    【解决方案3】:

    用“DM脚本手册”中的例子多试几次后,想出了一个方法:

    image out = in.slice2(0,0,0, 1,1024,1, 2,1024,1)
    

    即输出2d图像在x-y方向使用Slice2()命令对输入图像的y-z平面进行投影。

    【讨论】:

    • 这会起作用,但它会复制数据(仅此而已)。如果您只想解决该区域,您可能需要考虑使用image out := in.slice2(0,0,0, 1,1024,1, 2,1024,1),或使用image out := in.slice2(0,0,0, 1,1024,1, 2,1024,1).ImageClone() 创建克隆(包括标签、校准等)
    猜你喜欢
    • 2022-07-18
    • 1970-01-01
    • 1970-01-01
    • 2014-02-05
    • 1970-01-01
    • 2020-10-30
    • 1970-01-01
    • 2014-05-27
    • 1970-01-01
    相关资源
    最近更新 更多