“转换图像格式”用于将具有给定格式的图像转换为另一种格式。它处理颜色规格、格式和深度转换。该算法还支持输入范围转换,例如,当需要将 unsigned char
\([0,255]\) 图像映射到 signed short
\([-32768,32767]\) 范围时。
彩色输入 | 灰度输出 |
---|---|
![]() | ![]() |
有关实现该算法的限制、约束和后端的列表,请查阅以下函数的参考文档
函数 | 描述 |
---|---|
vpiSubmitConvertImageFormat | 将图像内容转换为所需的格式,可选择缩放和偏移。 |
该算法实现为逐像素转换函数,该函数读取输入像素,应用依赖于转换的一系列变换,并将结果写入输出图像中的相同位置。用户输入包括:
有几种类型的转换可用:
可用的颜色格式有:
可用的单通道灰度格式有:
当存储的信息不表示为颜色时(例如温度、速度等),应使用非彩色格式。对于转换,它们被视为具有扩展范围的灰度。
下表显示了可用于转换的输入和输出图像类型组合。
输入 |
---|
输出 |
以下部分描述了输入值如何转换为输出值。通常,这些转换相当于颜色规格、深度、通道顺序(交换)、添加或删除 Alpha 通道、降采样或升采样变换。这些表示为由以下定义的基本处理块组成的转换管道。
通道深度转换由名为“depth”的块表示,并由以下子管道定义:
depth | \(=\) | range | \(\rightarrow\) | round | \(\rightarrow\) | clamp/cast |
\[ f(x) = \text{scale} \times x + \text{offset} \]
如果 scale==1
且 offset==0
,则会采取快捷方式,并且不执行任何操作(甚至不转换为浮点)。
round(0.5) == 1.0
和 round(-0.5) == -1.0
。static_cast
一样,将输入强制转换为输出类型。下溢和溢出的行为将如 C 规范所述(包括未定义的行为)。当已知输入范围适合输出并且需要最大性能时,使用此选项。当应用于多个通道(如 RGB)时,该操作在每个通道上独立执行。
这由以下块表示:
swizzle |
它用于置换(或交换)输入类型的通道顺序。用于从/到可以多种方式表示的颜色规格进行转换,例如 RGB 和 BGR。颜色规格转换函数假定预定的通道顺序。为了使用它们,必须重新排序通道。
对于 RGB \(\leftrightarrow\) YUV 转换,VPI 使用 ITU-R BT.601 625 行规范。它与 JPEG 文件交换格式 (JFIF) 使用的 standard 相同。
为了精确地建立转换,让我们定义以下常量:
\begin{align} K_r &= 0.299 \\ K_g &= 0.587 \\ K_b &= 0.114 \\ K_{c_b} &= 1.772 \\ K_{c_r} &= 1.402 \\ \end{align}
为了表示方便,我们假设 \(U\) 和 \(V\) 分别对应于 \(C_b\) 和 \(C_r\)。此假设并非普遍成立。
转换块可以定义为:
rgb2yuv |
\begin{align} Y(r,g,b) &= \text{round}(r K_r + g K_g + b K_b)\big|^{255}_{0} \\ C_b(r,g,b) &= \text{round}((-r K_r - g K_g + b (1 - K_b )) / K_ {c_b} + 128)\big|^{255}_{0} \\ C_r(r,g,b) &= \text{round}((r (1-K_r) - g K_g - b K_b) / K_{c_r} + 128)\big|^{255}_{0} \end{align}
这些函数期望 \(r,g,b \in [0,255]\)
yuv2rgb |
\begin{align} R(y,c_b,c_r) &= \text{round}(y+K_{c_r}(c_r-128))\big|^{255}_{0} \\ G(y,c_b,c_r) &= \text{round}(y-[K_b K_{c_b} (c_b-128) + K_r K_{c_r} (c_r-128)] / K_g)\big|^{255}_{0} \\ B(y,c_b,c_r) &= \text{round}(y + K_{c_b} (c_b - 128))\big|^{255}_{0} \end{align}
这些函数期望 \(y,c_b,c_r \in [0,255]\)
符号 \(X\big|^{N} _ {M} \) 表示将 X 的下溢和溢出分别钳制为 M 和 N。
round
函数遵循 此处 的定义。
从 RGB 到灰度的转换遵循与从 RGB 到 YUV 的转换相同的规范,但仅返回亮度分量。因此,使用 此处 定义的相同常量。
rgb2gray |
\[ Y(r,g,b) = \text{round}(K_r \times r + K_g \times g + K_b \times b)\big|^{255}_{0} \]
对于从灰度到 RGB 的转换,则非常简单:
gray2rgb |
\[ f(x) = (x,x,x) \]
对于包含子采样平面的图像格式,如 VPI_IMAGE_FORMAT_NV12,需要以下块定义:
2x 降采样 |
\[ D[x,y] = S[2x,2y] \]
2x 升采样 |
\[ D[x,y] = S[\lfloor x/2 \rfloor, \lfloor y/2 \rfloor] \]
根据输入和输出像素类型(即,是否需要删除或添加 Alpha 通道),可以使用以下块:
alpha |
本节定义了输入像素如何转换为输出像素。它使用上一节中定义的基本转换块。
输入 | \(\rightarrow\) | depth | \(\rightarrow\) | 输出 |
输入 | \(\rightarrow\) | depth | \(\rightarrow\) | Y 平面 | \(\searrow\) |
(128,128) | \(\rightarrow\) | UV 平面 | \(\nearrow\) |
输出 |
输入 | \(\rightarrow\) | Y 平面 | \(\rightarrow\) | depth | \(\rightarrow\) | 输出 |
输入 | \(\rightarrow\) | depth | \(\rightarrow\) | gray2rgb | \(\rightarrow\) | swizzle | \(\rightarrow\) | alpha | \(\rightarrow\) | 输出 |
输入 | \(\rightarrow\) | swizzle | \(\rightarrow\) | alpha | \(\rightarrow\) | rgb2gray | \(\rightarrow\) | depth | \(\rightarrow\) | 输出 |
输入 | \(\rightarrow\) | swizzle | \(\rightarrow\) | alpha | \(\rightarrow\) | depth | \(\rightarrow\) | rgb2yuv |
\(\nearrow\) | Y 平面 | \(\searrow\) | ||
\(\searrow\) | UV 平面 | \(\rightarrow\) | 2x 降采样 | \(\nearrow\) |
输出 |
输入 | \(\rightarrow\) | swizzle | \(\rightarrow\) | alpha | \(\rightarrow\) | depth | \(\rightarrow\) | rgb2yuv |
\(\nearrow\) | Y 平面 | \(\searrow\) |
\(\searrow\) | UV 平面 | \(\nearrow\) |
输出 |
输入 |
\(\nearrow\) | Y 平面 | \(\searrow\) | ||
\(\searrow\) | UV 平面 | \(\rightarrow\) | 2x 升采样 | \(\nearrow\) |
yuv2rgb | \(\rightarrow\) | depth | \(\rightarrow\) | swizzle | \(\rightarrow\) | alpha | \(\rightarrow\) | 输出 |
输入 |
\(\nearrow\) | Y 平面 | \(\searrow\) |
\(\searrow\) | UV 平面 | \(\nearrow\) |
yuv2rgb | \(\rightarrow\) | depth | \(\rightarrow\) | swizzle | \(\rightarrow\) | alpha | \(\rightarrow\) | 输出 |
有关更多信息,请参阅 VPI - 视觉编程接口 的 “C API 参考” 部分中的 转换图像格式。
有关如何使用下表中的性能信息,请参阅 算法性能表。
在比较测量结果之前,请查阅 比较算法运行时间。
有关性能基准测试方式的更多信息,请参阅 性能基准测试。
clamp
转换策略,但下表显示了即使对于 cast
策略的性能数据。内部它仍然使用 clamp。在 VIC 上,即使它支持 cast
也不会有任何区别。