索引和切片#
DALI 数据节点可以使用熟悉的 Python 语法进行索引和切片,用于数组索引 x[sel]
,其中 x
是 DALI 数据节点,sel
是选择。选择可以是索引或切片。
索引#
最简单的情况是使用常量索引进行标量索引
images = fn.decoders.image(...)
sizes = fn.sizes(images) # height, width, channels
height = sizes[0]
width = sizes[1]
上面的代码片段从表示图像大小的 3 元素张量中提取宽度和高度。
注意
批次维度是隐式的,不能被索引。在此示例中,索引广播到整个批次。有关每个样本的索引,请参阅使用运行时值进行索引。
有关可以访问批次中不同样本数据的运算符,请参阅 fn.permute_batch()
。
从末尾索引#
负索引可用于从末尾开始索引张量。 -1 的索引表示最后一个元素
channels = sizes[-1] # channels go last
widths = sizes[-2] # widths are the innermost dimension after channels
使用运行时值进行索引#
使用常量进行索引通常是不够的。 使用 DALI,您可以使用其他计算的结果来访问张量元素。 在下面的示例中,我们使用运行时定义的索引来访问张量中随机位置的元素
raw_files = fn.readers.file(...)
length = raw_files.shape()[0]
# calculate a random index from 0 to file_length-1
random_01 = fn.random.uniform(range=(0, 1)) # random numbers in range [0..1)
index = fn.floor(random_01 * length) # calculate indices from [0..length)
# cast the index to integer - required for indexing
index = fn.cast(index, dtype=dali.types.INT64)
# extract a random byte
random_byte = raw_files[index]
在这里,将从每个样本中提取随机索引处的字节。index
是一个数据节点,表示一批标量值,每个样本一个。 这些值中的每一个都用作 raw_files
中相应样本的索引。
注意
索引必须是 CPU 运算符的结果。
切片#
要提取多个值(或切片),可以使用 Python 列表切片语法
header = raw_files[:16] # extract 16-byte headers from files in the batch
如果省略切片的开头,则切片从 0 开始。 如果省略结尾,则切片在给定轴的末尾结束。 负索引可用于切片的开头和结尾。 任何一端可以是常量、运行时值(DataNode)或可以跳过。
多维选择#
对于多维数据,您可以指定多个逗号分隔的选择。 如果选择是索引,则从输出中删除相应的维度
images = fn.decoders.image(jpegs, device="mixed") # RGB images in HWC layout
red = images[:,:,0]
green = images[:,:,1]
blue = images[:,:,2]
red
、green
、blue
是 2D 张量。
即使切片的长度为 1,切片也会保留切片的维度
green_with_channel = images[:,:,1:2] # the last dimension is kept
当索引和切片多维数据时,可以省略尾部维度。 这等效于将全范围切片传递给所有尾部维度
wide = letterboxed[20:-20,:,:] # slice height, keep width and channels
wide = letterboxed[20:-20,:] # this line is equivalent to the previous one
wide = letterboxed[20:-20] # ...and so is this one
注意
另请参阅 fn.crop()
和 fn.slice()
,了解为图像处理量身定制的操作。
步长切片#
正向和负向步进也可以使用与 numpy 数组相同的语义来实现。 这可以在多个维度上完成。
reversed = array[::-1] every_second = array[::2] every_second_reversed = array[::-2] quarter_resolution = image[::2, ::2]
添加维度#
特殊值 dali.newaxis
可以用作索引。 此值在输出中创建一个大小为 1 的新维度
trailing_channel = grayscale[:,:,dali.newaxis]
leading_channel = grayscale[dali.newaxis]
布局说明符#
DALI 张量可以具有布局说明符,它会影响某些运算符如何解释数据 - 通常,图像将具有 "HWC"
布局。
当将标量索引应用于轴时,该轴将从输出中删除,同时删除此轴的布局名称
image = ... # layout HWC
first_row = image[0] # layout WC
last_col = image[:,-1] # layout HC
red = image[:,:,0] # layout HW
可以通过将其传递给 dali.newaxis
来为新创建的维度添加名称
image = ... # layout is HWC
single_frame_video = image[dali.newaxis("F")] # layout is FHWC