kornia/kornia-rs

[Feature]: Optimize `pyrdown_f32` with separable convolution and Rayon parallelism

Open

#763 opened on Feb 25, 2026

 (6 comments) (0 reactions) (1 assignee)Rust (188 forks)auto 404
enhancementhelp wantedtriage

Repository metrics

Stars
 (675 stars)
PR merge metrics
 (PR metrics pending)

Description

🚀 Feature Description

Optimize the pyrdown_f32 function (currently found in crates/kornia-imgproc/src/pyramid.rs) to use separable 1D Gaussian convolutions and parallelize the execution using rayon.

📂 Feature Category

Performance Optimization

💡 Motivation

Currently, pyrdown_f32 is implemented as a single-threaded, fully-nested 5x5 convolution loop. This makes it an $O(25)$ operation per pixel and a significant bottleneck for algorithms that rely heavily on floating-point pyramids, such as the Pyramidal Lucas-Kanade Optical Flow (PR #756).

For comparison, generating a 128x112 downsampled image via pyrdown_f32 currently takes ~87µs, while generating a massive 512x448 upsampled image via pyrup_f32takes only ~75µs - solely because pyrup_f32 utilizes separable convolutions and rayon. Bringing pyrdown_f32up to par with the other pyramid functions will yield severe performance improvements.

💭 Proposed Solution

  1. Introduce pyrdown_horizontal_pass_f32 and pyrdown_vertical_pass_f32 helper functions to match the parallel structure of the existing pyrdown_u8 passes.
  2. Use floating-point Gaussian weights: 0.0625, 0.25, 0.375, 0.25, 0.0625.
  3. The horizontal pass will convolve and downsample in the X direction, writing to an intermediate buffer. The vertical pass will convolve and downsample in the Y direction reading from the buffer and writing directly to the destination.
  4. Utilize rayon's par_chunks_mut() across rows during both passes.
  5. Ensure the OpenCV-compatible reflect_101 border mode is preserved to maintain exact mathematical correctness.

📚 Library Reference

This optimization brings the implementation in line with the already existing pyrdown_u8, pyrup_u8, and pyrup_f32 functions in kornia-imgproc/src/pyramid.rs. It also matches the standard OpenCV optimization strategy for Image Pyramids (cv::pyrDown).

🔄 Alternatives Considered

Vectorization (SIMD): We could manually unroll the loops and write explicit SIMD instructions using std::arch. However, since the rest of the crates rely on standard auto-vectorization and rayon data-parallelism, adding separable kernels + rayon is the idiomatic, safest, and most generic approach for kornia-rs.

🎯 Use Cases

  • Pyramidal Lucas-Kanade Optical Flow: Massively speeds up the computation of image pyramids during the initialization step of tracking.
  • Feature Extraction (SIFT/SURF equivalents): Any multi-scale algorithms involving Difference-of-Gaussians or scale-space generation that operate on f32 tensors.

📝 Additional Context

  • This change is purely an internal performance optimization and will not alter the public API signature of pyrdown_f32.
  • Mathematical correctness will be verified against the existing slow implementation via unit tests.

🤝 Contribution Intent

  • I plan to submit a PR to implement this feature
  • I'm requesting this feature but not planning to implement it

Contributor guide