计算机视觉人工智能深度学习图像处理【免费下载链接】kornia Geometric Computer Vision Library for Spatial AI项目地址https://gitcode.com/gh_mirrors/ko/kornia点击查看免费下载Kornia 是面向 Spatial AI 与几何计算机视觉的 PyTorch 库其kornia.color子模块提供了一整套色彩空间转换算子其中 YUV 系列rgb_to_yuv/rgb_to_yuv420/rgb_to_yuv422/yuv_to_rgb/yuv420_to_rgb/yuv422_to_rgb及其模块化封装是处理 M/PAL 制式视频数据、亚采样色度平面的常用工具。本篇文章基于 Kornia 仓库的变更记录 changelog.d/migration-124.fixed.md 展开系统性讲解该次修复涉及的 YUV API 形状契约、文档示例的正确用法、形状守卫ShapeError行为、已知缺陷与规避方式以及配套测试体系的调整。读完本文你将掌握在 Kornia 中正确使用 4:2:0 / 4:2:2 亚采样转换算子、读懂并复现其文档 doctest、避免踩中奇偶尺寸与色度平面校验的坑并理解 gradcheck 在 MPS/XLA 设备上的跳过机制。一、变更背景一次针对文档与测试的精准修复该变更条目编号 #4045关联 #3539、#4044、#4050的核心工作是“恢复被 #3539 删除的 YUV 测试覆盖并修复kornia.color的 YUV 文档字符串示例”。从源码结构看这是一次典型的“文档-实现-测试”三联动修复既不改变任何运行时行为条目明确说明No runtime behavior changed又让 YUV 系列 API 的文档示例真正可以被复制执行、被 doctest 自动验证。修复前YUV 模块存在四类具体问题示例调错函数rgb_to_yuv422和yuv422_to_rgb的文档示例实际调用的是 4:2:0 的函数读者照抄会得到错误的转换结果和错误的色度形状形状注释与实现不符例如RgbToYuv420的示例尾部注释声称色度平面是2x1x2x3但实际返回的是(2, 2, 2, 3)形状输入约束说明不准确4:2:2 的文档声称输入只需在“垂直方向”可被 2 整除但实现中的守卫同时拒绝奇数高度和奇数宽度导致只 padding 了一个轴的读者会触发ShapeError错误信息拼写错误四个ShapeError消息中的 evenly disible by 2 是拼写错误同时在kornia/color/raw.py中还有两条相同措辞的消息需要一并修正。二、YUV API 全景函数与模块化封装本次修复涉及的核心实现位于 kornia/color/yuv.py。该文件定义了六个函数与六个nn.Module封装形成一一对应关系函数式 API模块化 API输入输出rgb_to_yuv(image)RgbToYuv(*, 3, H, W)(*, 3, H, W)rgb_to_yuv420(image)RgbToYuv420(*, 3, H, W)H/W 均为偶数(*, 1, H, W)(*, 2, H/2, W/2)rgb_to_yuv422(image)RgbToYuv422(*, 3, H, W)H/W 均为偶数(*, 1, H, W)(*, 2, H, W/2)yuv_to_rgb(image)YuvToRgb(*, 3, H, W)(*, 3, H, W)yuv420_to_rgb(imagey, imageuv)Yuv420ToRgb(*, 1, H, W)(*, 2, H/2, W/2)(*, 3, H, W)yuv422_to_rgb(imagey, imageuv)Yuv422ToRgb(*, 1, H, W)(*, 2, H, W/2)(*, 3, H, W)其中*表示任意数量的前导维度例如 batch3是通道数H/W是高与宽。所有模块封装都只是简单地委托给对应函数例如RgbToYuv.forward直接return rgb_to_yuv(input)因此函数式与模块式的行为完全一致可以按使用习惯选用。2.1 YUV 色彩模型遵循 BT.470-5 M/PAL所有函数与类都明确声明采用 ITU-R BT.470-5 标准 Table 2 第 2.5 与 2.6 项定义的 M/PAL 系统其定义关系为Y 0.299 R 0.587 G 0.114 B U 0.492 (B - Y) V 0.877 (R - Y)Kornia 的rgb_to_yuv将上述关系以矩阵形式硬编码并四舍五入到三位小数kernel torch.tensor( [ [0.299, 0.587, 0.114], [-0.147, -0.289, 0.436], [0.615, -0.515, -0.100], ], deviceimage.device, dtypedtype, ) return _apply_linear_transformation(image, kernel)见 kornia/color/yuv.py输入数据假定处于(0, 1)范围输出中 lumaY处于(0, 1)U、V 的范围分别为(-0.436, 0.436)与(-0.615, 0.615)。值得特别注意的是yuv_to_rgb的逆变换内核它并不是另行取整出版本中公布的逆关系而是直接对rgb_to_yuv的舍入内核求精确逆。源码注释给出了有理数域上的精确逆矩阵[[1, -1/25344, 144439/126720], [1, -10001/25344, -73561/126720], [1, 51499/25344, -61/126720]]代码中的每个字面量都是该精确分数正确舍入到 float64 的结果参见 kornia/color/yuv.py。这样做的好处是RGB → YUV → RGB 往返round trip的误差只受输入 dtype 精度限制——因为两个内核在 float64 下复合后接近单位矩阵约 1.1e-16float32 下约 1.2e-7。这直接关联到条目中提到的 #4044 问题此前yuv_to_rgb使用独立舍入的逆矩阵往返误差最高可达 1.356e-3本条目中提及的“round trip 已由 #4044 修复”即指这一优化。2.2 4:2:0 与 4:2:2 亚采样的实现要点rgb_to_yuv420先做完整 YUV 转换取 UV 平面后用F.avg_pool2d(uv, 2)做 2×2 box 平均得到(*, 2, H/2, W/2)的色度平面kornia/color/yuv.py。源码注释特别说明虽然用两次 unfold 再 mean 也能得到同样数值但avg_pool2d直接计算更快尤其在 MPS 上差距明显——这是性能导向的实现细节。rgb_to_yuv422只对宽度方向做 2×1 平均unfold(-1, 2, 2).mean(-1)沿最后一维滑动窗口取均值得到(*, 2, H, W/2)kornia/color/yuv.py。yuv420_to_rgb先把 UV 平面通过repeat_interleave(2, dim-1).repeat_interleave(2, dim-2)上采样回全分辨率再与 Y 平面沿通道维torch.cat拼成 4:4:4最后调用yuv_to_rgbkornia/color/yuv.py。yuv422_to_rgb同理只对宽度维repeat_interleave(2, dim-1)上采样后拼接kornia/color/yuv.py。三、修复后的文档示例可直接复制的 doctest条目明确指出kornia/color/yuv.py中的每一个示例现在都以 doctest 形式断言输出形状而不是写在注释里。这意味着文档中的代码块可以直接用python -m doctest或 pytest 的--doctest-modules验证读者复制即用、不会出现形状与描述不符的情况。修复后的核心示例均可在当前源码中直接找到 input torch.rand(2, 3, 4, 5) rgb_to_yuv(input).shape torch.Size([2, 3, 4, 5]) input torch.rand(2, 3, 4, 6) y, uv rgb_to_yuv420(input) y.shape, uv.shape (torch.Size([2, 1, 4, 6]), torch.Size([2, 2, 2, 3])) input torch.rand(2, 3, 4, 6) y, uv rgb_to_yuv422(input) y.shape, uv.shape (torch.Size([2, 1, 4, 6]), torch.Size([2, 2, 4, 3])) inputy torch.rand(2, 1, 4, 6) inputuv torch.rand(2, 2, 2, 3) yuv420_to_rgb(inputy, inputuv).shape torch.Size([2, 3, 4, 6]) inputy torch.rand(2, 1, 4, 6) inputuv torch.rand(2, 2, 4, 3) yuv422_to_rgb(inputy, inputuv).shape torch.Size([2, 3, 4, 6])模块化版本如RgbToYuv420、RgbToYuv422、Yuv420ToRgb、Yuv422ToRgb的示例与之完全一致例如 yuvinput torch.rand(2, 3, 4, 6) yuv RgbToYuv422() y, uv yuv(yuvinput) y.shape, uv.shape (torch.Size([2, 1, 4, 6]), torch.Size([2, 2, 4, 3]))对照修复前的错误示例rgb_to_yuv422曾错误调用 4:2:0 的函数、RgbToYuv420曾注释色度形状为2x1x2x3实际为(2, 2, 2, 3)这些坑现在都已消除。读者在复制任何 YUV 示例时输出的形状断言就是最可靠的验收标准。四、形状守卫与ShapeError奇偶约束的准确含义所有 4:2:0 / 4:2:2 算子都要求输入高和宽都能被 2 整除“evenly divisible by 2 horizontal and vertical”。这与修复前 4:2:2 文档中“只需垂直方向可整除”的错误描述不同——实际上奇数高度和奇数宽度都会被拒绝。只 padding 一个轴就会触发ShapeError因此正确的 padding 策略是同时保证 H 和 W 为偶数。守卫的实现在 kornia/color/yuv.py 等处if len(image.shape) 2 or image.shape[-2] % 2 1 or image.shape[-1] % 2 1: raise ShapeError(fInput HW must be evenly divisible by 2. Got {image.shape})四个 YUV 算子rgb_to_yuv420、rgb_to_yuv422、yuv420_to_rgb、yuv422_to_rgb各有一个这样的守卫另外kornia/color/raw.py中的两个守卫例如 kornia/color/raw.py使用完全相同的措辞。修复内容之一就是把这些消息中的 evenly disible by 2 全部更正为 divisible——即现在的错误文本是Input HW must be evenly divisible by 2。此外yuv420_to_rgb与yuv422_to_rgb还各自带有一个形状匹配守卫验证色度平面的尺寸必须与亮度平面成比例4:2:0imagey的 H/W 必须恰好是imageuv的 2 倍否则抛出ShapeError消息为Input imageuv HW must be half the size of the luma plane. Got {imagey.shape} and {imageuv.shape}4:2:2imagey的 H 必须等于imageuv的 H且imagey的 W 必须是imageuv的 W 的 2 倍否则抛出ShapeError消息为Input imageuv H must match the luma plane and W must be half its size. Got {imagey.shape} and {imageuv.shape}。见 kornia/color/yuv.py 与 kornia/color/yuv.pyShapeError是kornia.core.exceptions提供的异常类型KORNIA_CHECK_SHAPE宏from kornia.core.check import KORNIA_CHECK_SHAPE负责在算子入口校验张量是否满足[*, 3, H, W]之类的形状模式随后手写的奇偶守卫抛出ShapeError。4.1 已知缺陷yuv422_to_rgb/Yuv422ToRgb只校验色度宽度条目提到yuv422_to_rgb及Yuv422ToRgb目前带有一个.. warning::文档块声明一个已知缺陷对应 #4050该函数只校验色度平面的宽度不校验高度。因此如果传入的imageuv高度错误守卫不会捕获而是会在torch.cat拼接时抛出一个裸的RuntimeError错误信息不如ShapeError清晰。规避方式是在调用前自行检查imageuv.shape[-2] imagey.shape[-2]。同理yuv420_to_rgb在高度、宽度上都做了比例校验相对更安全。另外修复前所有 YUV→RGB 形式都带有一个针对往返round trip问题的第二条警告对应 #4044随着yuv_to_rgb改为精确逆内核该问题已修复这些警告块已从文档中移除参见上文 2.1 节的往返精度说明。五、测试体系从恢复覆盖到跨设备 gradcheck 跳过条目开篇即指出“恢复 #3539 删除的 YUV 测试覆盖”这些测试主要位于 tests/color/test_yuv.py共 962 行。测试文件包含几类关键内容5.1 独立参考实现与容差推导测试文件顶部用 BT.470-5 的定义关系非矩阵形式独立实现了参考模型_rgb_to_yuv_reference与_yuv_to_rgb_referencetests/color/test_yuv.py并据此推导出容差正向rgb_to_yuv因矩阵系数四舍五入到三位小数与定义关系的最大偏差约为 4.46e-4故_FORWARD_ATOL 5.0e-4逆向yuv_to_rgb因采用精确逆内核偏差被压缩到约 5.231e-4B 通道为最坏情况_INVERSE_ATOL 6.0e-4——仅为旧实现1.535e-3的三分之一。此外还定义了白、黑、灰、红、绿、蓝六种参考色的精确 YUV 值_REFERENCE_COLORS以及每种 dtype 的往返容差表_ROUND_TRIP_TOLfloat64 为(1e-12, 1e-12)float32 为(1e-5, 1e-5)float16 为(1e-3, 2.5e-3)bfloat16 为(8e-3, 1.5e-2)。5.2 形状、异常与往返测试测试覆盖包括基数/形状测试test_cardinality对多种形状参数化验证输出形状例如rgb_to_yuv420输出(1, 3, 4, 4)、(2, 3, 2, 4)、(3, 3, 4, 2)、(3, 2, 2)甚至 5 维(3, 3, 3, 4, 4)异常测试对非张量输入kornia.color.rgb_to_yuv420([0.0])以及各种奇数尺寸张量断言抛出ShapeError往返测试rgb_to_yuv420→yuv420_to_rgb后与原图assert_close容差取自_round_trip_tol(dtype)gradcheck 测试对函数式算子直接调用torch.autograd.gradcheckfast_modeTrue。5.3 gradcheck 在 MPS / XLA / TPU 上的跳过机制条目特别说明了测试侧的两处调整gradcheck 的两个跳过点现在同时覆盖 XLA/TPU 设备而不只是 MPS。原因是 gradcheck 要求 float64而MPS 完全不支持 float64XLA 会把 float64 请求降低为 float32此时 gradcheck 默认的eps1e-6会使数值雅可比矩阵失效。因此这两类设备上运行 float64 gradcheck 会因纯粹的精度原因失败需要跳过。具体的双层机制是名称标记conftest.py在 conftest.py 中pytest_collection_modifyitems对名称包含gradcheck的测试gradcheck in name在 MPS 或 TPU fixtureon_mps or [tpu in item.nodeid上自动添加skip_gradcheck标记跳过理由为gradcheck requires float64, which this device does not compute in。这覆盖了所有直接导入torch.autograd.gradcheck的*gradcheck*测试设备守卫BaseTester.gradcheck在 testing/base.py 的BaseTester.gradcheck静态方法中对输入张量执行设备类型检查只要任一输入位于mps或xla设备t.device.type mps or xla in t.device.type就直接pytest.skip。这覆盖了六个通过BaseTester.gradcheck调用、但测试名不含gradcheck的用例条目提到的一个例子是test_grad_zca_with_fit位于 ZCA 相关测试中。默认情况下BaseTester.gradcheck会把所有输入转换为 float64 并要求梯度dtypes与requires_grad参数可覆盖然后调用torch.autograd.gradcheck(func, inputs, raise_exception..., fast_mode..., **kwargs)。六、实战速查如何正确使用 YUV 转换6.1 基本用法import torch import kornia # 4:2:0 正向转换输入 H/W 必须为偶数 rgb torch.rand(2, 3, 4, 6) # (B, C, H, W)H4, W6 均为偶数 y, uv kornia.color.rgb_to_yuv420(rgb) print(y.shape) # torch.Size([2, 1, 4, 6]) print(uv.shape) # torch.Size([2, 2, 2, 3]) # 4:2:0 逆向转换色度平面必须恰为亮度平面的 1/2 rgb_restored kornia.color.yuv420_to_rgb(y, uv) print(rgb_restored.shape) # torch.Size([2, 3, 4, 6]) # 4:2:2 正向转换仅宽度方向亚采样 y422, uv422 kornia.color.rgb_to_yuv422(rgb) print(y422.shape) # torch.Size([2, 1, 4, 6]) print(uv422.shape) # torch.Size([2, 2, 4, 3]) # 4:2:2 逆向转换宽度方向 2 倍上采样 rgb_restored_422 kornia.color.yuv422_to_rgb(y422, uv422)6.2 尺寸预处理避免ShapeError输入尺寸不满足偶数约束时先做 paddingimport torch.nn.functional as F def pad_to_even(x: torch.Tensor) - torch.Tensor: h_pad x.shape[-2] % 2 w_pad x.shape[-1] % 2 return F.pad(x, (0, w_pad, 0, h_pad)) # (right, left, bottom, top) 顺序 rgb torch.rand(2, 3, 5, 7) rgb_padded pad_to_even(rgb) # (2, 3, 6, 8) y, uv kornia.color.rgb_to_yuv420(rgb_padded)注意对于yuv422_to_rgb由于已知缺陷#4050还需自行校验imageuv的高度与imagey一致否则会在torch.cat处遇到裸RuntimeError。6.3 模块化用法适合nn.Module组合import torch.nn as nn import kornia class MyPipeline(nn.Module): def __init__(self): super().__init__() self.to_yuv kornia.color.RgbToYuv422() def forward(self, x): y, uv self.to_yuv(x) # y: (*, 1, H, W/2) 需要时自行调整 return y需要留意的是RgbToYuv420、RgbToYuv422、Yuv420ToRgb、Yuv422ToRgb这四类多输入/多输出模块目前设置了ONNX_EXPORTABLE FalseRgbToYuv与YuvToRgb则定义了ONNX_DEFAULT_INPUTSHAPE/ONNX_DEFAULT_OUTPUTSHAPE为[-1, 3, -1, -1]可参与 ONNX 导出流程这与源码中的# TODO: Handle multiple inputs and outputs models later注释一致即多平面版本的 ONNX 导出尚未支持。6.4 验证文档示例doctest修复后kornia/color/yuv.py中所有示例都是带形状断言的 doctest可用 pytest 直接验证pytest --doctest-modules kornia/color/yuv.py七、总结migration-124.fixed.md记录了一次小而完整的质量修复kornia/color/yuv.py的全部示例改为可断言的 doctest修正了 4:2:2 示例错调 4:2:0 函数、形状注释与实现不符、输入约束描述错误等问题统一了四个ShapeError守卫与raw.py中两条相同消息的措辞并为yuv422_to_rgb/Yuv422ToRgb补充了已知缺陷警告#4050测试侧恢复了 #3539 删除的 YUV 覆盖并把 gradcheck 的跳过逻辑扩展到 XLA/TPU从 conftest 的名称标记与BaseTester.gradcheck的设备守卫两层堵住了 float64 精度陷阱。整个变更不改变任何运行时数值行为却让 YUV API 的文档、实现与测试三者重新对齐——这正是依赖 doctest 与形状断言来守护 API 契约的典型实践。相关文件索引变更记录changelog.d/migration-124.fixed.md核心实现kornia/color/yuv.py同措辞守卫的另一处实现kornia/color/raw.py测试实现tests/color/test_yuv.pygradcheck 设备守卫testing/base.pygradcheck 名称标记conftest.py赞分享计算机视觉人工智能深度学习图像处理【免费下载链接】kornia Geometric Computer Vision Library for Spatial AI项目地址https://gitcode.com/gh_mirrors/ko/kornia点击查看免费下载相关推荐Kornia YUV 颜色空间转换完全指南RGB 与 4:2:0/4:2:2 色度子采样实战Kornia YUV 颜色空间转换完全指南RGB 与 4:2:0/4:2:2 色度子采样实战 Kornia 的 kornia.color 模块提供了一套完整的计算机视觉人工智能深度学习图像处理OBS Studio色彩空间处理从RGB到YUV的完美转换与色彩管理实战OBS Studio色彩空间处理从RGB到YUV的完美转换与色彩管理实战 引言直播画质的隐藏痛点 你是否曾遇到直播画面色彩失真、暗部细节丢失或HDR转SDR音视频直播屏幕录制桌面应用视频终极指南色度子采样技术详解 - 4:2:0、4:2:2和4:4:4的区别与应用色度子采样是数字视频压缩中的关键技术它通过降低色彩信息的分辨率来大幅减少数据量同时保持人眼几乎察觉不到的质量损失。这项技术基于人眼视觉系统的特性我们对亮度文档教程音视频视频创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考