ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

CANN ops-cv RGB2YUV422 算子详解:RGB 图像到 YUV422(YUYV)色彩空间转换的接口、公式与 SIMT 实现

CANN ops-cv RGB2YUV422 算子详解:RGB 图像到 YUV422(YUYV)色彩空间转换的接口、公式与 SIMT 实现 CANN ops-cv RGB2YUV422 算子详解RGB 图像到 YUV422YUYV色彩空间转换的接口、公式与 SIMT 实现【免费下载链接】ops-cv本项目是CANN提供的图像处理、目标检测相关的算子库实现网络在NPU上加速计算。项目地址: https://gitcode.com/cann/ops-cv导读本文围绕 CANN ops-cv 仓库中的rgb2yuv422算子位于 experimental/image/rgb2yuv422展开完整讲解其功能定义、BT.601 色彩转换公式、ACLNN 两层调用接口、参数与约束、shape 推断规则以及基于 SIMT 编程模型的 NPU kernel 实现原理。读者阅读后可以掌握在 Ascend 950 系列产品上调用aclnnRgb2yuv422完成 RGB→YUV422 转换的完整方案并理解算子从 Graph 定义、Host 侧推断到 Kernel 执行的底层链路。一、算子功能与背景rgb2yuv422是一个图像预处理算子功能为将 RGB 图像转换为 YUV422 色彩空间并以 YUYV 打包格式输出。其转换流程分为两步基于ITU-R BT.601 标准矩阵完成 RGB → YUV444 的转换对色度分量 U/V 进行水平 2:1 子采样每两个水平相邻像素共享一对 U/V最终按YUYV顺序交替打包输出。从仓库中的贡献说明README.md可知该算子由 CANN-BOT SIMT 于 2026/06 从 ops-math 迁移至 ops-cv属于实验性experimental目录下的算子当前仅支持 Ascend 950PR/Ascend 950DT 产品Atlas A2/A3 及早期 Atlas 系列产品均不支持。这一平台约束在算子定义rgb2yuv422_def.cpp中体现为只为ascend950注册了 AICore 配置。在典型的视觉处理流水线中该算子常作为 YUV 数据通路的前置转换环节将摄像头或解码器得到的 RGB 帧转为 YUV422 后供下游编解码或 NPU 上的色度相关算子使用。二、转换公式与数据精度2.1 float16/float32 输入归一化公式对于 float16 / float32 输入使用标准的 BT.601 系数矩阵Y/U/V 的计算公式为Y 0.29900 · R 0.58700 · G 0.11400 · B U -0.16874 · R - 0.33126 · G 0.50000 · B V 0.50000 · R - 0.41869 · G - 0.08131 · B2.2 uint8 输入含 128 偏移公式对于 uint8 输入U/V 分量额外加上 128 偏移将色度信号从有符号区间搬移到 0~255 的无符号区间Y 0.29900 · R 0.58700 · G 0.11400 · B U -0.16874 · R - 0.33126 · G 0.50000 · B 128 V 0.50000 · R - 0.41869 · G - 0.08131 · B 128这两组公式在 kernel 源码rgb2yuv422_simt.h的ComputeYUV内联函数中被逐字实现其中if constexpr (std::is_same_vT, uint8_t)分支即为 uint8 特有的 128 偏移逻辑而测试侧的 golden 参考实现tests/golden.py使用 float64 精度按同一组系数计算用作比对基准。2.3 uint8 输出的取整与饱和处理uint8 场景下浮点计算结果在写回前需经过饱和 就近取整处理。kernel 中的CastBackuint8_t特化实现如下rgb2yuv422_simt.h先用fminf/fmaxf将结果裁剪到[0, 255]再用nearbyintf做四舍五入round-half-to-even后转换为 uint8。golden 脚本中对应的np.clip(np.round(yuv422), 0, 255)与之保持一致的语义。float16 输入则通过__float2half转回 half 精度float32 直接透传。三、算子参数说明rgb2yuv422共包含 2 个张量参数与 1 个属性参数参数表如下源自 README.md 参数说明章节参数名输入/输出/属性描述数据类型数据格式x输入RGB 图像张量。NHWC 格式: shape[..., H, W, 3]NCHW 格式: shape[..., 3, H, W]。UINT8、FLOAT16、FLOATNDy输出YUV422 (YUYV 打包) 张量。NHWC 格式: shape[..., H, W, 2]NCHW 格式: shape[..., 2, H, W]。UINT8、FLOAT16、FLOATNDdata_format属性输入数据的通道排列格式。NHWC 表示通道在最后一维NCHW 表示通道在倒数第三维3D 输入时在第一维。默认值为 NHWC。String-各参数的要点说明x输入通道维大小固定为 3R、G、B 三个通道输出 y 的通道维变为 2分别存放 Y 与 U/V。注意输出在通道维大小上从 3 变为 2但H、W 以及 batch 等维度保持不变——YUV422 子采样只压缩色度在水平方向的采样率并不改变分辨率维度。y输出dtype 与输入严格一致uint8→uint8、float16→float16、float32→float32该一致性由 Graph 侧的数据类型推断强制保证见下节。data_format属性可选值仅有NHWC与NCHW两种默认NHWC。在算子定义文件rgb2yuv422_def.cpp中以Attr(data_format).AttrType(OPTIONAL).String(NHWC)声明属于可选属性缺省时取默认值。四、约束说明使用该算子需满足以下约束README.md 约束说明章节输入至少为 3 维rank ≥ 3通道维大小必须为 3NHWC 下为最后一维NCHW 下为 3D 输入的第一维或 ≥4D 输入的倒数第三维输入 dtype 支持 uint8、float16、float32输出 dtype 与输入一致data_format 必须为 NHWC 或 NCHW仅支持 Ascend 950PR/Ascend 950DT 产品。这些约束并非仅停留在文档层面在 Host 侧 shape 推断rgb2yuv422_infershape.cpp中均有硬性校验rank 3、data_format非法、channelDim ! 3三种情况都会直接返回GRAPH_FAILED。对应的 Host 侧单测test_rgb2yuv422_infershape.cpp覆盖了这些校验分支。五、ACLNN 两层调用接口与调用示例在 CANN 的算子调用体系中该算子对外暴露标准的ACLNN 两层接口原型见 docs/aclnnRgb2yuv422.md声明见 aclnn_rgb2yuv422.h。5.1 GetWorkspaceSize 接口第一层接口用于获取 workspace 大小并创建执行器aclnnStatus aclnnRgb2yuv422GetWorkspaceSize( const aclTensor* x, const char* dataFormat, const aclTensor* y, uint64_t* workspaceSize, aclOpExecutor** executor );5.2 执行接口第二层接口在指定 stream 上真正执行算子aclnnStatus aclnnRgb2yuv422( void* workspace, uint64_t workspaceSize, aclOpExecutor* executor, const aclrtStream stream );5.3 完整调用示例以 4×8×3batch4, H8, W3 的 NHWCuint8 输入为例标准调用流程如下docs/aclnnRgb2yuv422.md 调用示例#include aclnnop/aclnn_rgb2yuv422.h int64_t xShape[] {4, 8, 3}; aclDataType dataType ACL_UINT8; aclFormat format ACL_FORMAT_ND; uint64_t workspaceSize 0; aclOpExecutor* executor nullptr; aclnnRgb2yuv422GetWorkspaceSize(x, NHWC, y, workspaceSize, executor); void* workspaceAddr nullptr; if (workspaceSize 0) { aclrtMalloc(workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST); } aclnnRgb2yuv422(workspaceAddr, workspaceSize, executor, stream); aclrtSynchronizeStream(stream);从 op_api/rgb2yuv422.cpp 的底层实现可以看到该算子当前不额外申请 workspaceworkspaceSize返回 0且输出张量 y 的 shape 与 dtype 均由执行器依据输入 x 自动分配executor-AllocTensor(yShape, x-GetDataType())因此调用方按示例写法申请一个空 workspace 即可安全执行。5.4 返回值错误码错误码触发条件ACLNN_SUCCESS正常执行ACLNN_ERR_PARAM_NULLPTRx 或 y 为空指针ACLNN_ERR_PARAM_INVALIDdtype 不在支持列表中、data_format 不为 NHWC/NCHW、通道维不等于 3、rank 3六、从定义到执行的底层链路为了让读者对算子有完整的源码级认知这里梳理rgb2yuv422在仓库中的完整实现链路各环节均有对应源码文件6.1 算子定义OpDefrgb2yuv422_def.cpp 完成算子的注册声明输入 xREQUIRED、输出 yREQUIRED、属性 data_formatOPTIONAL默认 NHWC并为ascend950平台注册 AICore 配置。值得注意的是其配置启用了DynamicRankSupportFlag(true)与DynamicShapeSupportFlag(true)即支持动态 rank 与动态 shape输入 shape 无需在编译期固定。6.2 数据类型与 shape 推断数据类型推断rgb2yuv422_graph_infer.cpp直接令输出 y 的 dtype 等于输入 x 的 dtype保证输入输出类型一致。Shape 推断rgb2yuv422_infershape.cpp保持 rank 与各非通道维不变仅将通道维从 3 改写为 2。NHWC 下输出 shape 为[..., H, W, 2]NCHW 下 3D 输入输出为[2, H, W]≥4D 输入输出为[..., 2, H, W]。6.3 Host 侧 Tilingtiling 阶段arch35/rgb2yuv422_tiling.cpp负责计算核数、按行切分任务产出 rgb2yuv422_tiling_data.h 中定义的Rgb2yuv422TilingData结构包含needCoreNum、totalRows、perCoreRows、W、outerDims、dataFormat、pairsPerRow等字段。对应单测见 test_rgb2yuv422_tiling.cpp。6.4 Kernel 侧 SIMT 实现Kernel 入口op_kernel/rgb2yuv422.cpp根据 tiling 中的调度模式分发到 NHWCschMode 0或 NCHWschMode 1两条路径核心计算在 rgb2yuv422_simt.h 中实现其关键设计包括线程组织half 输入使用 512 线程/块uint8 与 float32 使用 1024 线程/块THREADST常量折叠。像素对并行由于 YUV422 按每 2 个水平像素共享一对 U/Vkernel 将任务抽象为totalPairs totalRows × pairsPerRow个像素对每个线程处理一对水平相邻像素天然贴合 YUYV 打包布局。YUYV 打包写回对一对像素 (w0, w1)输出为Y0, U, Y1, V四个值依次落位奇数宽度W 为奇数时最右侧像素的w1越界此时 V 直接取当前像素对共享的v0保证每行输出元素数恰好为2×W。索引优化pairIdx到 (b, h, w) 的除法采用GetUintDivMagicAndShift生成的魔数除法magic number division替代整数除法减少 SIMT 线程内的除法开销当总元素数不超过 UINT32_MAX 时自动退化为 32 位索引路径否则走 64 位路径兼顾性能与超大 shape 的通用性。边界处理NCHW 布局下 R/G/B 三通道通过base0 k*H*W的跨平面寻址取数输出 U/V 平面同样按H*W偏移交错存放。6.5 测试与 golden 验证算子配套了完整的 UT 体系tests/ut/op_host覆盖 infershape 与 tiling 的 Host 侧单测tests/ut/op_kernel/test_rgb2yuv422.cpp 与数据生成脚本 gen_data.py、compare_data.pykernel 侧端到端比对tests/golden.py独立的 NumPy golden 实现验证 NHWC/NCHW 两种布局、三种 dtype 下的数学正确性。读者可参照这些测试文件理解算子的数值行为并在自己的环境中复跑 UT 验证。七、典型使用场景小结rgb2yuv422适合作为 NPU 视觉流水线中的色彩空间转换前置算子使用输入为 RGB 三通道图像uint8 或 float 精度输出为 YUYV 打包的 YUV422 数据数据布局按需选择 NHWC图像处理主流的通道末维布局性能更友好或 NCHW若下游算子需要 YUV444 全采样数据则不应使用本算子其输出已做水平 2:1 子采样色度信息有损。由于当前仅支持 Ascend 950PR/Ascend 950DT在更早的 Atlas 系列硬件上运行时需要额外做平台适配或回退到 CPU/其他转换实现。从算子定义中DynamicShapeSupportFlag(true)等配置可以推断该算子设计上已考虑动态 shape 场景适合在推理服务中接收不定尺寸的输入帧。【免费下载链接】ops-cv本项目是CANN提供的图像处理、目标检测相关的算子库实现网络在NPU上加速计算。项目地址: https://gitcode.com/cann/ops-cv创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表