ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Kornia Filtering API 深度指南:用 filter2d / filter2d_separable / filter3d 自定义图像滤波算子

2026/9/24 14:25:49 拓冰建站 浏览量
Kornia Filtering API 深度指南:用 filter2d / filter2d_separable / filter3d 自定义图像滤波算子 计算机视觉人工智能深度学习图像处理【免费下载链接】kornia Geometric Computer Vision Library for Spatial AI项目地址https://gitcode.com/gh_mirrors/ko/kornia点击查看免费下载本文是 Kornia 几何计算机视觉库中Filtering API的完整技术指南。Filtering API 是 Kornia 滤波子系统模糊、边缘检测等算子的底层原语层提供filter2d、filter2d_separable、filter3d三个核心函数让开发者用自己的卷积核直接对批量张量做滤波。读完本文你将掌握这三个原语的完整参数语义、底层实现原理、与相关别名函数convolve2d、correlate2d、fft_conv等的关系以及它们在 Kornia 内部盒式模糊、高斯模糊、拉普拉斯算子的真实调用方式从而能基于这些原语构建自己的可微图像处理算子。1. 什么是 Filtering API在 docs/source/filters.rst 中kornia.filters模块被划分为五大部分模糊blurring、边缘检测edge detection、阈值分割segmentation、Filtering API 与核生成kernels。其中 Filtering API 的官方定位是Apply your own 2D, separable or 3D kernels withfilter2d,filter2d_separableandfilter3d.对应的 docs/source/filters.filtering_api.rst 中明确写道Convolve an image with your own kernel. These are the primitives the blur and edge operators are built on.这两句话定义了本 API 的使命它是所有模糊blur与边缘edge算子的构建基石primitives。也就是说Kornia 里更上层的box_blur、gaussian_blur2d、laplacian等算子最终都会落到这三个函数上执行卷积。三个核心函数一览函数输入形状卷积核形状维度filter2d(B, C, H, W)(1, kH, kW)或(B, kH, kW)2Dfilter2d_separable(B, C, H, W)kernel_x: (1, kW)或(B, kW)kernel_y: (1, kH)或(B, kH)2D可分离filter3d(B, C, D, H, W)(1, kD, kH, kW)或(B, kD, kH, kW)3D所有函数都遵循 Kornia 的统一约定输入必须是批量化的(B, C, ...)形状张量卷积核独立作用于每个通道输出与输入保持相同的通道数与空间形状在paddingsame时。2. filter2d二维卷积原语filter2d是 Filtering API 中最核心的函数其完整签名定义在 kornia/filters/filter.pydef filter2d( input: torch.Tensor, kernel: torch.Tensor, border_type: str reflect, normalized: bool False, padding: str same, behaviour: str corr, ) - torch.Tensor:2.1 参数语义参数默认值含义input必填输入张量形状(B, C, H, W)批次数为 B、通道数为 Ckernel必填卷积核形状(1, kH, kW)所有批次共享或(B, kH, kW)每批次独立核border_typereflect卷积前对输入施加的边界填充模式可选constant、reflect、replicate、circularnormalizedFalse若为True核在应用前会被 L1 归一化paddingsame填充策略same保持输出与输入同尺寸valid不做隐式填充behaviourcorr卷积模式corr为互相关默认等价于 PyTorchconv2dconv为真卷积核先翻转2.2 官方文档示例均值滤波filter2d的 docstring 中给出的标准示例源于 kornia/filters/filter.py演示了用3x3全 1 核做窗口求和import torch from kornia.filters import filter2d input torch.tensor([[[ [0., 0., 0., 0., 0.], [0., 0., 0., 0., 0.], [0., 0., 5., 0., 0.], [0., 0., 0., 0., 0.], [0., 0., 0., 0., 0.], ]]]) kernel torch.ones(1, 3, 3) filter2d(input, kernel, paddingsame) # tensor([[[[0., 0., 0., 0., 0.], # [0., 5., 5., 5., 0.], # [0., 5., 5., 5., 0.], # [0., 5., 5., 5., 0.], # [0., 0., 0., 0., 0.]]]])可以看到位于中心的像素值 5 被扩散到3x3邻域中由于paddingsame输出形状与输入一致仍是(1, 1, 5, 5)。2.3 归一化与均值滤波当normalizedTrue时核会先经过 L1 归一化即除以核内所有元素绝对值之和归一化实现见 kornia/filters/kernels.pydef normalize_kernel2d(input: torch.Tensor) - torch.Tensor: norm input.abs().sum(dim-1).sum(dim-1) return input / (norm[..., None, None])因此torch.ones(1, 3, 3)在normalizedTrue时会变成每个元素为1/9的核等价于标准均值滤波。在测试 tests/filters/test_filters.py 中test_normalized_mean_filter验证了这一点中心值 5 经归一化后邻域值为5.0 / 9注释中写明的nv: float 5.0 / 9并断言该结果在paddingsame与paddingvalid两种模式下均成立。2.4 校验与异常函数内部通过 Kornia 的类型/形状检查体系KORNIA_CHECK_IS_TENSOR、KORNIA_CHECK_SHAPE、KORNIA_CHECK对输入做严格校验input必须是张量且形状为[B, C, H, W]kernel必须是张量且形状为[B, H, W]border_type必须属于{constant, reflect, replicate, circular}padding必须属于{valid, same}behaviour必须属于{conv, corr}。测试 tests/filters/test_filters.py 的test_exception验证了这些失败路径传入非张量会抛TypeCheckErrorType mismatch: expected Tensor形状不符抛ShapeError非法border_type/padding则分别抛出 Invalid border, a. Ex... 与 Invalid padding mode, a. Ex... 错误信息。3. filter2d_separable可分离卷积原语filter2d_separable提供**可分离separable**卷积将一个二维核分解为水平方向核kernel_x与垂直方向核kernel_y先后各做一次一维滤波。签名见 kornia/filters/filter.pydef filter2d_separable( input: torch.Tensor, kernel_x: torch.Tensor, kernel_y: torch.Tensor, border_type: str reflect, normalized: bool False, padding: str same, ) - torch.Tensor:kernel_x形状为(1, kW)或(B, kW)沿 W 方向作用kernel_y形状为(1, kH)或(B, kH)沿 H 方向作用。3.1 实现原理两次一维滤波其实现非常简洁本质上是两次filter2d的组合见 kornia/filters/filter.pyout_x filter2d(input, kernel_x[..., None, :], border_type, normalized, padding) return filter2d(out_x, kernel_y[..., None], border_type, normalized, padding)即先把kernel_x变成形状(1, 1, kW)的二维核沿水平方向滤波再把kernel_y变成(1, kH, 1)沿垂直方向滤波。对可分核如高斯核、盒式核这种两次一维卷积的计算量与二维直接卷积相比大幅降低是 Kornia 中许多模糊算子的默认路径。3.2 与 filter2d 的等价性验证测试 tests/filters/test_filters.py 的test_separable专门验证了可分路径与直接二维路径的一致性kernel_x torch.ones(1, 3) kernel_y torch.ones(1, 3) kernel kernel_y.t() kernel_x # 由两个一维核外积构造二维核 out filter2d(inp, kernel[None], paddingpadding) out_sep filter2d_separable(inp, kernel_x, kernel_y, paddingpadding) self.assert_close(out, out_sep) # 两种路径输出一致该测试覆盖了paddingsame与paddingvalid两种模式是理解可分离卷积正确性的最佳佐证。4. filter3d三维卷积原语filter3d将滤波扩展到三维体数据如 CT 体数据、视频序列、光场签名见 kornia/filters/filter.pydef filter3d( input: torch.Tensor, kernel: torch.Tensor, border_type: str replicate, normalized: bool False, behaviour: str corr, ) - torch.Tensor:input形状为(B, C, D, H, W)D 为深度维kernel形状为(1, kD, kH, kW)或(B, kD, kH, kW)border_type支持constant、reflect、replicate、circular默认值为replicate与 2D 版本的reflect不同注意filter3d没有padding参数输出始终与输入保持相同形状(B, C, D, H, W)始终等价于paddingsamebehaviour同样支持corr与conv。4.1 官方文档示例docstring 中的示例kornia/filters/filter.py构造了一个5x5x5的三维张量中心切片上有一个值为 5 的体素用3x3x3全 1 核滤波后该值在三个深度切片的3x3邻域中都被扩散为 5import torch from kornia.filters import filter3d input torch.tensor([[[ [[0., 0., 0., 0., 0.], ...], # 深度切片 0全 0 [[0., 0., 0., 0., 0.], [0., 0., 5., 0., 0.], ...], # 深度切片 1中心值为 5 [[0., 0., 0., 0., 0.], ...] # 深度切片 2全 0 ]]]) kernel torch.ones(1, 3, 3, 3) filter3d(input, kernel) # 输出在三个切片上都出现 5 的 3x3 扩散块4.2 三维归一化与filter2d不同filter3d在normalizedTrue时先做维度重整再复用normalize_kernel2d见 kornia/filters/filter.pyif normalized: bk, dk, hk, wk kernel.shape tmp_kernel normalize_kernel2d(tmp_kernel.view(bk, dk, hk * wk)).view_as(tmp_kernel)即把三维核展平为(B, D, H*W)后逐行做 L1 归一化。测试 tests/filters/test_filters.py 的test_normalized_mean_filter验证了3x3x3全 1 核归一化后中心值 5 变为5.0 / 2727 个元素之和。5. 核心参数深挖padding、border_type 与 behaviour5.1 paddingsame 与 validpaddingsame是默认模式在卷积前先对输入做填充使输出与输入空间形状一致。填充量由内部函数_compute_padding计算kornia/filters/filter.pydef _compute_padding(kernel_size: list[int]) - list[int]: computed [k - 1 for k in kernel_size] # 每维需要填充的总量 out_padding 2 * len(kernel_size) * [0] for i in range(len(kernel_size)): computed_tmp computed[-(i 1)] pad_front computed_tmp // 2 # 前侧上/左 pad_rear computed_tmp - pad_front # 后侧下/右 out_padding[2 * i 0] pad_front out_padding[2 * i 1] pad_rear return out_padding关键细节对偶数尺寸的核填充是不对称的pad_rear pad_front 1因为奇数尺寸核的k-1是偶数可以对称平分而偶数尺寸核只能通过前少后多的方式保持输出尺寸。测试 tests/filters/test_filters.py 的test_even_sized_filter专门覆盖了2x2偶数核在same与valid下的行为test_mix_sized_filter_padding_sametests/filters/test_filters.py则覆盖了5x6这种宽高不对称的核。paddingvalid不做填充输出尺寸变为(B, C, H - kH 1, W - kW 1)在源码中由 kornia/filters/filter.py 的output.view(b, c, h - height 1, w - width 1)体现。5.2 border_type四种边界模式模式行为constant用常数0填充边界reflect镜像反射填充不含边界像素本身replicate复制最边缘像素值填充circular环形循环填充这些模式直接透传给torch.nn.functional.pad的mode参数见 kornia/filters/filter.py因此行为与 PyTorch 完全一致。测试中test_smoketests/filters/test_filters.py对四种 border 类型 × 归一化开关 × 两种 padding 模式做了全组合冒烟验证。5.3 behaviourcorr 与 conv 的区别这是本 API 最值得注意的细节之一。深度学习框架中的conv2d实际执行的是互相关cross-correlation而数学意义上的真卷积需要先将核翻转 180°。filter2d通过behaviour参数显式区分两者corr默认核不翻转行为等价于 PyTorchconv2dconv执行真卷积源码中通过kernel.flip((-2, -1))翻转核见 kornia/filters/filter.py。测试 tests/filters/test_filters.py 的test_conv用1..9排列的3x3核验证了两者差异对中心为 1 的输入corr输出核的原始排列9 在左上而conv输出核翻转后的排列1 在左上。6. 便捷别名与 FFT 加速后端filter2d/filter3d之外kornia/filters/filter.py 还提供了一系列语义化别名与高性能实现全部通过 kornia/filters/init.py 对外导出6.1 语义化别名函数等价调用correlate2d(input, kernel, ...)filter2d(..., behaviourcorr)convolve2d(input, kernel, ...)filter2d(..., behaviourconv)correlate3d(input, kernel, ...)filter3d(..., behaviourcorr)convolve3d(input, kernel, ...)filter3d(..., behaviourconv)例如convolve2d的实现就是一行kornia/filters/filter.pyreturn filter2d(input, kernel, border_typeborder_type, normalizednormalized, paddingpadding, behaviourconv)当你的算法在语义上需要真卷积而非互相关时使用这些别名可以显著提升代码可读性。6.2 fft_conv大核加速fft_convkornia/filters/filter.py提供基于 FFT 的二维卷积后端利用卷积定理在频域做逐元素乘法。其 docstring 明确指出适用场景This function is recommended when the kernel size is larger than approximately (20 x 20). For large kernels, FFT-based convolution is computationally more efficient than direct spatial convolution, reducing complexity from O(H * W * kH * kW) to approximately O(H * W log(H * W)).实现细节内部使用torch.fft.rfftn/torch.fft.irfftn通过共轭torch.conj实现互相关并在频域计算前做空间域填充以避免循环卷积伪影CPU 上的 float16 / bfloat16 输入会先用 float32 计算再转回原精度。测试 tests/filters/test_filters.py 的test_matches_spatial_filter验证了fft_conv与filter2d在所有 padding / behaviour / normalized 组合下输出一致。7. 源码级应用模糊与边缘算子如何构建在 Filtering API 之上回到文档的核心定位——the primitives the blur and edge operators are built on——我们可以在源码中逐一印证这些原语在 Kornia 内部的实际调用7.1 box_blur盒式模糊kornia/filters/blur.py 中box_blur的卷积路径分别使用filter2d_separable可分离模式默认与filter2d不可分离模式if separable: ky, kx _unpack_2d_ks(kernel_size) kernel_y get_box_kernel1d(ky, deviceinput.device, dtypeinput.dtype) kernel_x get_box_kernel1d(kx, deviceinput.device, dtypeinput.dtype) out filter2d_separable(input, kernel_x, kernel_y, border_type) else: kernel get_box_kernel2d(kernel_size, deviceinput.device, dtypeinput.dtype) out filter2d(input, kernel, border_type)7.2 gaussian_blur2d高斯模糊kornia/filters/gaussian.py 中gaussian_blur2d用get_gaussian_kernel1d生成水平/垂直一维高斯核后走filter2d_separable可分离路径或用get_gaussian_kernel2d生成二维高斯核走filter2dif separable: kernel_x get_gaussian_kernel1d(kx, sigma[:, 1].view(bs, 1)) kernel_y get_gaussian_kernel1d(ky, sigma[:, 0].view(bs, 1)) out filter2d_separable(input, kernel_x, kernel_y, border_type) else: kernel get_gaussian_kernel2d(kernel_size, sigma) out filter2d(input, kernel, border_type)7.3 laplacian拉普拉斯算子kornia/filters/laplacian.py 直接导入filter2d并用get_laplacian_kernel2d生成的核调用它kornia/filters/laplacian.pyreturn filter2d(input, kernel, border_type)。此外filter2d系列还被广泛用于其他子模块例如kornia/metrics/ssim.py、kornia/geometry/transform/pyramid.py、kornia/geometry/transform/elastic_transform.py、kornia/contrib/distance_transform.py等。这充分说明 Filtering API 确实是整个 Kornia 滤波与几何变换体系的公共底座。8. 实战构建自定义算子基于以上知识你可以用 Filtering API 快速实现任意线性滤波算子。以锐化unsharp 风格为例import torch from kornia.filters import filter2d def sharpen(image: torch.Tensor, strength: float 1.0) - torch.Tensor: 用自定义核实现锐化identity strength * (identity - box) kernel torch.tensor([[[ [0.0, -1.0, 0.0], [-1.0, 5.0, -1.0], [0.0, -1.0, 0.0], ]]], deviceimage.device, dtypeimage.dtype) return filter2d(image, kernel, border_typereplicate, paddingsame)几个来自源码与测试的最佳实践核形状单核用(1, kH, kW)需要按批次使用不同核时用(B, kH, kW)此时每个批次元素独立滤波可分离优先只要核能写成两个一维核的外积高斯、盒式、Sobel 类就用filter2d_separable提升效率且输出与二维路径一致有test_separable保证大核用 FFT核尺寸超过约20x20时考虑fft_conv以换取更低复杂度边界语义边缘处理敏感的任务如梯度估计优先考虑replicate或reflect避免constant引入的边界跳变可微性整个 API 完全由 PyTorch 算子组成F.padF.conv2d/F.conv3d梯度可以正常反向传播。测试test_gradchecktests/filters/test_filters.py对filter2d与filter3d均做了梯度检查test_dynamo还验证了与torch.compile的兼容性输入约束所有输入必须是(B, C, ...)形状的张量维度不足或类型错误会立即抛异常TypeCheckError/ShapeError便于尽早发现 bug。9. 小结Filtering API 是 Kornia 滤波系统的核心原语层filter2d提供二维互相关/卷积filter2d_separable通过两次一维滤波实现高效的可分离卷积filter3d将同一套设计扩展到三维体数据。配合normalized、padding、border_type、behaviour四个开关这组函数可以表达几乎所有的线性图像滤波操作而convolve2d/correlate2d/fft_conv等辅助函数进一步丰富了表达力与性能选项。Kornia 自身的box_blur、gaussian_blur2d、laplacian等算子全部构建在这些原语之上——理解了 Filtering API就掌握了 Kornia 滤波体系的根基也为自定义可微图像算子打下了坚实基础。赞分享计算机视觉人工智能深度学习图像处理【免费下载链接】kornia Geometric Computer Vision Library for Spatial AI项目地址https://gitcode.com/gh_mirrors/ko/kornia点击查看免费下载相关推荐OpenCV filter2D() 深度教程从零实现自定义线性滤波器与归一化盒式滤波OpenCV filter2D 深度教程从零实现自定义线性滤波器与归一化盒式滤波 本指南围绕 OpenCV 官方教程《Making your own line计算机视觉图像处理深度学习机器学习Kornia 图像模糊算子完全指南从 box_blur 到 guided_blur 的滤波工具箱Kornia 图像模糊算子完全指南从 box_blur 到 guided_blur 的滤波工具箱 导读 本文系统梳理 Kornia几何计算机视觉库中 ko计算机视觉人工智能深度学习图像处理gh_mirrors/ope/opencv_contrib图像处理算子设计自定义卷积核与滤波实现gh_mirrors/ope/opencv_contrib图像处理算子设计自定义卷积核与滤波实现 在计算机视觉应用中图像滤波是基础且核心的预处理步骤。传统均计算机视觉图像处理机器学习上一篇从 .bundle 到可导入的工程AssetRipper 跨平台资产提取手记下一篇GitHub_Trending/de/developer-portfolios项目国际化多语言作品集网站的实现方法创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考