kornia/kornia-rs

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

Open

#763 opened on Feb 25, 2026

View on GitHub
 (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