您可以采用两种方法,其中一种仅适用于高达 3D 的数据,并且通常比另一种慢,但更灵活。
正如您一直在要求 arbitrary 子采样,我从该选项开始,但第二个选项更有可能为您提供您想要的:orthogonal, regular subsampling .
如果您赶时间,简短的回答是:使用SliceN 命令。
1) 使用表达式(任意子采样)
图像数据中的单个像素位置 (img) 可以被处理
使用符号
-
img[ X, 0 ] ... 用于位置 X 的一维数据
-
img[ X, Y ] ... 用于位置 X/Y 的二维数据
-
img[ X, Y, Z ] ... 用于位置 X/Y/Z 的 3D 数据
请注意,即使这涉及单个数字,结果也是大小为 1x1 或 1x1x1 的 表达式 而不是标量数字,因此你不能这样做:number num = img[10,4]
但是,您可以使用一些小技巧来使用任何将表达式转换为单个数字的函数,例如 f.e.总和。所以你可以做到:number num = sum(img[10,4])
那么这与您的问题有什么关系?嗯,在上面的表达式中,我们使用了标量值X、Y和Z,得到的表达式是大小为1x1和1x1x1的表达式,但是
您可以在此表示法中使用任意大小的表达式,如X、Y、Z,只要它们都是表达式 em>相同大小。生成的寻址数据具有此大小,并通过相应坐标引用值。
通过下面的示例,这将变得更加清晰。从一个简单的 1D 示例开始:
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()
我们的测试数据 (img1D) 只是使用 icol 表达式从 1000 到 1099 的线性图,该表达式在每个像素处表示该像素的 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]
2) 使用 SliceN(正交子采样)
可以使用命令SliceN 及其简化变体Slice1、Slice2 和Slice3 来处理沿数据维度方向的数据子集。
SliceN 命令可能是我在处理数据时最喜欢的语言命令之一。一开始看起来很吓人,但它是直截了当的。
让我们从一维提取的简化版本Slice1 开始。
要使用Slice1 命令从任何高达 3D 的数据中提取 1D 数据,您需要以下内容(-这些正是该命令使用的 7 个参数-):
除此之外,您唯一需要知道的是:
- 起点总是定义为
X,Y,Z 三元组,即使数据源只是二维或一维。
0 用于不需要的
尺寸。
- 方向作为维度索引给出:0 = X、1 = Y、2 = Z
- 步长可以为负值以指示相反的方向
- 指定的采样必须包含在源数据中。
(您不能“外推”)
因此,提取 3D 数据集的 1D 数据的一个非常简单的示例是:
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。
请注意,该命令再次在源数据中返回一个 表达式,您也可以使用它来设置值,只需使用 f.e.:
Slice1( img3D, px,py,0, 2,sz,1 ) = 0
使用命令 Slice2 和 Slice3 扩展 2D 和 3D 数据非常简单。您可以分别定义 two 或 three,而不是定义 one 输出方向。每个都有三组数字:方向、长度、步长。
以下示例提取“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 )
以下示例“旋转”了 3D 图像:
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 )
您可以使用这些进行各种旋转、镜像、分箱
命令。如果您想要充分的灵活性来获得任何表达式
5D 从任何源数据到 5D,那么您需要最通用的
SliceN 命令。
它的工作原理完全相同,但您需要同时指定源数据的维度和输出表达式的维度。然后,需要使用源数据维度所建议的尽可能多的坐标来定义“起点”,并且您需要为每个输出维度指定一个三元组。
对于N 维度的源数据并想要M 维度的输出,您需要:2 + N + 3*M 参数。
例如,让我们从“4D 衍射图像”数据中提取特定空间位置的“平面”,该数据在 2D 扫描的每个空间位置存储 2D 图像:
number sx = 9
number sy = 9
number kx = 9
number ky = 9
image img4D := RealImage( "Diffraction Image", 4, sx, sy, kx, ky )
img4D = 50000 + icol + irow * 10 + idimindex(2)*100 + idimindex(3)*1000
number px = 3
number py = 4
image img2D := SliceN( img4D, 4, 2, px,py,0,0, 2,kx,1, 3,ky,1 )
ShowImage( img4D )
ShowImage( img2D )