如何用脚本重塑DM中数据立方体的维度
How to reshape the dimension of data cube in DM with script
我有一张尺寸为 1024*1024 的图像存储在 HDF5 文件中,该文件被视为切片厚度为 1 的数据立方体(因此存储的尺寸为 1024*1024*1)。我使用 Niermann HDF5 插件 (https://github.com/niermann/gms_plugin_hdf5) 导入数据。导入后数据立方体变为1*1024*1024,显示为1像素宽,1024像素高,1024张切片图片
在考虑重新实现插件之前,我想问一下,有什么办法可以"reshape"数据(比如"Numpy.reshape"),这样尺寸就可以了妥善处理?
谢谢!
经过多次尝试"DM scripting handbook"中的例子,得出了一个方法:
image out = in.slice2(0,0,0, 1,1024,1, 2,1024,1)
也就是说,x-y 中的输出二维图像使用 Slice2() 命令在输入图像的 y-z 平面上进行投影。
如果您的 input/output 数组大小在维度上不匹配(这样 slice
将不起作用),那么您还可以 'stream' 使用以下:
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]。 [*]
内部变量icol
、irow
、iplane
被计算表达式的X、Y、Z坐标替换,而iwidth
、iheight
和 idepth
替换为计算表达式的维度大小。
计算的表达式的大小是多少?它由行中 "known size" 的唯一图像定义 - 左侧或右侧,因此
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 的大小,因为那是行中 "known size" 的图像,即使它在右侧.
* 这种方式不支持更高的维度,因为 [T,L,B,R] 已经用于子区域。
如果你不喜欢 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()
我有一张尺寸为 1024*1024 的图像存储在 HDF5 文件中,该文件被视为切片厚度为 1 的数据立方体(因此存储的尺寸为 1024*1024*1)。我使用 Niermann HDF5 插件 (https://github.com/niermann/gms_plugin_hdf5) 导入数据。导入后数据立方体变为1*1024*1024,显示为1像素宽,1024像素高,1024张切片图片
在考虑重新实现插件之前,我想问一下,有什么办法可以"reshape"数据(比如"Numpy.reshape"),这样尺寸就可以了妥善处理?
谢谢!
经过多次尝试"DM scripting handbook"中的例子,得出了一个方法:
image out = in.slice2(0,0,0, 1,1024,1, 2,1024,1)
也就是说,x-y 中的输出二维图像使用 Slice2() 命令在输入图像的 y-z 平面上进行投影。
如果您的 input/output 数组大小在维度上不匹配(这样 slice
将不起作用),那么您还可以 'stream' 使用以下:
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]。 [*]
内部变量icol
、irow
、iplane
被计算表达式的X、Y、Z坐标替换,而iwidth
、iheight
和 idepth
替换为计算表达式的维度大小。
计算的表达式的大小是多少?它由行中 "known size" 的唯一图像定义 - 左侧或右侧,因此
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 的大小,因为那是行中 "known size" 的图像,即使它在右侧.
* 这种方式不支持更高的维度,因为 [T,L,B,R] 已经用于子区域。
如果你不喜欢 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()