最近我计划操作一堆图像,目标是从那里提取特定的切片子集,例如只有偶数或奇数或任意索引,然后将它们保存到另一个数据集中。
在DM中,“音量”菜单中有许多有用的功能,但不幸的是,它们无法满足我想要的效果。
我只是想知道这个想法是否可以通过脚本来实现。
非常感谢您的帮助。
答案 0 :(得分:0)
有两种方法可以解决这个问题,其中一种方法仅适用于高达3D的数据,通常比另一种慢,但更灵活。 正如您一直要求任意子采样,我从该选项开始,但第二个选项更有可能为您提供所需内容:正交,常规子采样。
如果您赶时间,简短的回答是:使用SliceN
命令。
可以解决图像数据(
img
)中的各个像素位置 使用符号
- 的1D数据
img[ X, 0 ]
...用于位置X
- 的2D数据
img[ X, Y ]
...用于位置X/Y
- 的3D数据
img[ X, Y, Z ]
...用于位置X/Y/Z
请注意,即使这个地址是单个数字,结果也是 1x1 或 1x1x1 的表达式,而不是标量数字,因此你不能做:number num = img[10,4]
但是,你可以使用一个小技巧来使用任何将表达式转换为单个数字的函数,如f.e.总和。所以可以:number num = sum(img[10,4])
那么这与你的问题有何关系?好吧,在上面的表达式中,我们使用标量值X
,Y
和Z
,结果表达式是大小 1x1 和的表达式1x1x1 ,但
您可以在此注释中使用任意大小的表达式
X
,Y
,Z
,只要它们都是表达式 相同的大小。生成的寻址数据具有此大小,其值由相应的坐标引用。
通过以下示例,这将变得更加清晰。从简单的一维示例开始:
image img1D := RealImage( "TestData", 4, 100 )
image coord := RealImage( "Coordinates", 4, 10 )
img1D = 1000 + icol // Just sum test data
coord = trunc(100*Random()) // random integer 0-99
image subImg := img1D[coord,0]
img1D.ShowImage()
coord.ShowImage()
subImg.ShowImage()
我们的testdata(img1D
)这里只是一个1000到1099的线性图,使用icol
表达式,在每个像素处表示像素X坐标。
坐标图像(coord
)包含0到99之间的随机整数值。
魔法'发生在subImg
。我们使用coord
图像作为X坐标的表达式。该图像的大小为 10(x1),因此输出表达式的大小为 10(x1),我们会在显示之前将其分配给图像subImg
。
请注意,我们构建的表达式实际上只是指向图像的数据。我们可以使用该表达式来替换更改数据中的这些点,而不是将其显示为新图像,使用:
img1D[coord,0] = 0
从这里开始,可以直接将示例扩展到2D:
image img2D := RealImage( "TestData", 4, 30, 30 )
image coordX := RealImage( "Coordinates X", 4, 10 )
image coordY := RealImage( "Coordinates Y", 4, 10 )
img2D = 10000 + icol + irow * 100
coordX = trunc(30*Random())
coordY = trunc(30*Random())
img2D[coordX,coordY] = 0
coordX.ShowImage()
coordY.ShowImage()
img2D.ShowImage()
...和3D:
image img3D := RealImage( "TestData", 4, 30, 30, 30 )
image coordX := RealImage( "Coordinates X", 4, 10 )
image coordY := RealImage( "Coordinates Y", 4, 10 )
image coordZ := RealImage( "Coordinates Y", 4, 10 )
img3D = 10000 + icol + irow * 100 + iplane * 1000
coordX = trunc(30*Random())
coordY = trunc(30*Random())
coordZ = trunc(30*Random())
img3D[coordX,coordY,coordZ] = 0
coordX.ShowImage()
coordY.ShowImage()
coordZ.ShowImage()
img3D.ShowImage()
不幸的是,它在此结束。
您无法再在4D或5D数据中执行此类寻址,因为已定义具有4个参数的表达式以将2D数据中的矩形区域作为
处理img[T,L,B,R]
可以使用命令
SliceN
及其简化变体Slice1
,Slice2
和Slice3
来解决沿数据维方向的数据子集。
在处理数据时,SliceN
命令可能是我最喜欢的语言命令之一。起初看起来很吓人,但它很直接。
让我们从1D提取的简化版本Slice1
开始。
要使用
Slice1
命令从任何数据中提取一维数据到3D,您需要以下( - 这些正是命令使用的7个参数 - ):
- 数据来源
- 源头的起点
- 抽样方向
- 采样长度
- 采样步长
你唯一需要知道的是:
- 起始点始终定义为
X,Y,Z
三元组,即使数据源仅为2D或1D。
0
用于不需要的人 尺寸。- 方向作为尺寸指数给出:0 = X,1 = Y,2 = Z
- 步长可以是负数以指示相反的方向
- 指定的抽样必须包含在源数据中。
(您不能'推断')
因此,提取3D数据集的一维数据的一个非常简单的示例是:
number sx = 20
number sy = 20
number sz = 20
image img3D := RealImage( "Spectrum Image", 4, sx, sy, sz )
img3D = 5000000 + icol + irow * 100 + iplane * 10000
number px = 5
number py = 7
image spec1D := Slice1( img3D, px,py,0, 2,sz,1 )
ShowImage( img3D )
ShowImage( spec1D )
这个例子在处理" 3D光谱图像时显示了分析显微镜中非常典型的情况。数据:提取" 1D频谱"在特定的空间位置。
该示例针对空间点px,py
执行了该操作。从该位置(px,py,0
)开始,它沿Z方向(2
)对数据的所有像素(sz
)进行采样,步长为{{1 }}
注意,该命令会再次在源数据中返回表达式,并且您也可以使用它来设置值,只需使用fe:
1
使用命令Slice1( img3D, px,py,0, 2,sz,1 ) = 0
和Slice2
扩展2D和3D数据非常简单。您可以分别定义两个或三个,而不是定义一个输出方向。每个都有三个数字:方向,长度,步长。
以下示例提取"图像平面" " 3D光谱图像":
Slice3
以下示例"旋转" 3D图像:
number sx = 20
number sy = 20
number sz = 20
image img3D := RealImage( "Spectrum Image", 4, sx, sy, sz )
img3D = 5000000 + icol + irow * 100 + iplane * 10000
number pz = 3
image plane2D := Slice2( img3D, 0,0,pz, 0,sx,1, 1,sy,1 )
ShowImage( img3D )
ShowImage( plane2D )
你可以通过这些进行各种旋转,镜像,分类 命令。如果你想要充分的灵活性来获得任何表达式 5D从任何源数据到5D,那么你需要最多才多艺
number sx = 6 number sy = 4 number sz = 3 image img3D := RealImage( "Spectrum Image", 4, sx, sy, sz ) img3D = 1000 + icol + irow * 10 + iplane * 100 image rotated := Slice3( img3D, 0,0,0, 0,sx,1, 2,sz,1, 1,sy,1 ) ShowImage( img3D ) ShowImage( rotated )
命令。
它的工作方式完全相同,但您需要指定源数据的维度和输出表达式的维度。然后,开始'需要使用源数据维度建议的坐标来定义点,并且每个输出维度需要一个三元组规范。
对于SliceN
尺寸的源数据,并希望输出N
尺寸,您需要:M
个参数。
作为一个例子,让我们提取"平面"来自" 4D衍射图像的特定空间位置"数据,用于在2D扫描的每个空间位置存储2D图像:
2 + N + 3*M