使用算术运算的自定义增强#
本节向您展示如何通过在 DALI Pipeline 中使用带算术运算的表达式来实现自定义增强。
混合图像#
我们将创建一个 pipeline,以几种不同的方式混合图像。为了轻松可视化结果,我们创建了以下文件列表,其中包含猫和狗的图片
cats.txt
dogs.txt
导入#
从必要的导入开始。
[1]:
from nvidia.dali.pipeline import Pipeline
import nvidia.dali.fn as fn
import nvidia.dali.types as types
from nvidia.dali.types import Constant
显式使用的运算符#
该 pipeline 将使用两个
readers.file
来创建两个批次的张量,一个包含猫,一个包含狗。我们还需要一个
decoders.image
来解码加载的图像。对于两个输入,您都需要
resize
运算符。算术运算符在张量之间应用逐点运算,并要求它们具有匹配的形状和大小。
在此示例中,使用了 400 x 400 的图像。
我们可能想要在 pipeline 中声明的最后一个运算符是
Cast
运算符,用于将数据转换回所需的类型。
带有自定义增强的图#
以下是初始步骤
加载两个输入批次。
解码两个输入。
将输入调整为相同大小。
现在,我们有两个变量 dogs
和 cats
,它们代表两个批次的等尺寸图像。我们可以使用一些权重混合这些图像,并通过使用以下公式将像素强度降低一半
(0.4 * cats + 0.6 * dogs) / 2
在这里,我们使用了 Python 立即值作为算术表达式中的常量输入。
使用 dali.types.Constant 指示类型#
我们也可以更加注意我们使用的类型,并以
uint16
执行所有计算。
输入为 uint8
,并且使用标记为 uint16
的常量进行计算会将结果提升为 uint16
。有关更多信息,请参阅“DALI 二进制算术运算符 - 类型提升”教程。
我们还可以使用
//
除法,这使我们能够保持结果的整数类型。
(Constant(4).uint16() * cats + Constant(6).uint16() * dogs) // Constant(20).uint16()
我们返回两个输入,并且结果已强制转换回
uint8
。
[2]:
pipe = Pipeline(batch_size=1, num_threads=4, device_id=0, seed=42)
with pipe:
cats_jpegs, _ = fn.readers.file(
device="cpu", file_root="../../data/images", file_list="cats.txt"
)
dogs_jpegs, _ = fn.readers.file(
device="cpu", file_root="../../data/images", file_list="dogs.txt"
)
images = fn.decoders.image(
[cats_jpegs, dogs_jpegs], device="cpu", output_type=types.RGB
)
cats, dogs = fn.resize(images, resize_x=400, resize_y=400)
blend_float = (0.4 * cats + 0.6 * dogs) / 2
blend_uint16 = (
Constant(4).uint16() * cats + Constant(6).uint16() * dogs
) // Constant(20).uint16()
pipe.set_outputs(
cats,
dogs,
fn.cast_like(blend_float, cats),
fn.cast_like(blend_uint16, cats),
)
运行 Pipeline#
创建 pipeline 的实例并构建它。为了简化结果显示,我们使用
batch_size = 1
。
[3]:
pipe.build()
我们将使用一个简单的辅助函数来显示图像。
对于更大的批次,可以调整 data_idx
以显示不同的样本。output_titles
将用于设置 pipeline 输出的标题。
[4]:
import matplotlib.pyplot as plt
def display(output, titles, cpu=True):
data_idx = 0
fig, axes = plt.subplots(len(output) // 2, 2, figsize=(15, 15))
if len(output) == 1:
axes = [axes]
for i, out in enumerate(output):
img = out.at(data_idx) if cpu else out.as_cpu().at(data_idx)
axes[i // 2, i % 2].imshow(img)
axes[i // 2, i % 2].axis("off")
axes[i // 2, i % 2].set_title(titles[i])
output_titles = [
"Cat",
"Dog",
"(0.4 * Cat + 0.6 * Dog) / 2",
"(Constant(4).uint16() * Cat + Constant(6).uint16() * Dog) // "
"Constant(20).uint16()",
]
我们将运行并显示结果。
您可以多次运行此单元格以查看不同图像的结果。
[5]:
output = pipe.run()
display(output, output_titles)
