# kornia-rs: a low-level computer vision library in Rust with one CPU/GPU API

> kornia-rs is a Rust crate (and a kornia-rs Python wheel) for image I/O, processing and video capture, where the same Image type and operators dispatch on whether the data lives on the CPU or an NVIDIA GPU. It is aimed at real-time pipelines that need to hand frames to PyTorch or TensorRT without a host copy.

**kornia/kornia-rs** — 🦀 Low-level 3D Computer Vision library in Rust

- Repository: https://github.com/kornia/kornia-rs
- Website: https://docs.rs/kornia
- Stars: 718 · Forks: 203
- Language: Rust
- License: Apache-2.0
- Published: 2026-09-10 · Updated: 2026-09-10 · Language: en
- Canonical page: https://hysenlabs.com/projects/kornia-kornia-rs

## What kornia-rs solves, and who it is for

Most computer vision code pays a tax every time a frame crosses a boundary. A camera hands you NV12 or YUYV, you convert it to RGB on the CPU, resize and normalize it, then copy the buffer into a tensor so a model can read it. kornia-rs exists to remove those copies and that conversion chain. The README describes the crate as a low-level computer vision library for Rust, with fast, thread-safe image I/O and processing under a single API that runs on the CPU or an NVIDIA GPU, and it states that results are handed to PyTorch and TensorRT with no host copy through DLPack and the CUDA Array Interface.

The intended reader is an engineer building a real-time pipeline: robotics, camera capture, or an inference service where per-frame latency matters. The repository topics list robotics alongside computer-vision and deep-learning, and the examples directory contains entries such as cuda_camera_preprocess, cuda_camera_sift, v4l capture and AprilTag detection. The Python side is packaged as kornia-rs and the README says the same wheel is CPU-only or activates CUDA when an NVIDIA GPU is present, which means a deployment does not need two artifacts.

It is not a general-purpose replacement for a full imaging toolkit. The feature list is deliberately narrow: read from a list of formats, convert, resize, crop, rotate, flip, pad, normalize, capture video, write video. If your work is mostly file-based batch processing, the zero-copy GPU path buys you nothing.

## One Image type, two residencies: the dispatch mechanism

The design choice that shapes everything else is that there is no separate GPU image type. The README states that the same Image and operators dispatch on where the data lives. So Image<u8, 3> is the type whether the buffer is in host memory or on the device, and the operator you call decides which kernel to run. That keeps generic code generic: a function that takes an Image and resizes it does not need to be written twice or made generic over a backend.

The cost of that choice is that residency becomes runtime state rather than a type-level fact. Nothing in the type signature tells you whether a call will synchronize with the GPU. The README does not document how dispatch failures are reported when an operator has no GPU implementation, and the release notes for v0.1.15-rc.5 describe GPU op coverage as an ongoing item (filters, pyramids, CLAHE, Canny, CCL, a fusion engine), which implies coverage is still being filled in rather than uniform across the operator set.

The interop path is the other half of the mechanism. DLPack and __cuda_array_interface__ are the two protocols named in the README for moving tensors to and from PyTorch, plus numpy views. Those are the standard exchange formats, so the integration is with the ecosystem rather than with one framework. On the capture side, V4L2 is supported for cameras and there is a fused NV12/YUYV to normalized CHW CUDA kernel, which is the single-kernel camera-to-model-input path the README advertises.

## Installing kornia-rs from crates.io or PyPI

For Rust, the README gives a single dependency line. Adding it to Cargo.toml pulls the umbrella crate, and the workspace declares a rust-version of 1.89, so an older toolchain will fail before it compiles anything.

```toml
[dependencies]
kornia = "0.1"
```

If you want to avoid pulling everything, the README lists sub-crates that can be depended on individually: kornia-tensor, kornia-tensor-ops, kornia-io, kornia-image, kornia-imgproc, kornia-3d, kornia-apriltag, kornia-vlm, kornia-bow and kornia-algebra. That split matters for build times and for binary size in embedded targets.

For Python, the install is one command, and the README notes that a subset of the full Rust API is exposed.

```bash
pip install kornia-rs
```

Some features need system packages. The README lists clang for V4L2 camera support, nasm for turbojpeg, and libgstreamer1.0-dev plus libgstreamer-plugins-base1.0-dev for gstreamer, all installed with apt-get on Debian-family systems. None of these are required for the basic image path.

## A first real use: read, cast, grayscale, resize

The README's image processing example is the shortest path to something that runs. It reads a JPEG as an RGB8 image, casts to f32 and scales by 1/255, converts to grayscale, then resizes to 128x128 with bilinear interpolation. The result is logged to a rerun recording stream.

```rust
use kornia::{image::{Image, ImageSize}, imgproc};
use kornia::io::functional as F;

let image: Image<u8, 3> = F::read_image_any_rgb8("tests/data/dog.jpeg")?;
let image_f32: Image<f32, 3> = image.cast_and_scale::<f32>(1.0 / 255.0)?;

let mut gray = Image::<f32, 1>::from_size_val(image_f32.size(), 0.0)?;
imgproc::color::gray_from_rgb(&image_f32, &mut gray)?;
```

Two details are worth noticing. The output buffers are allocated by the caller with from_size_val, and the operators write into them, which is the pattern that lets a pipeline reuse buffers across frames instead of allocating per frame. And cast_and_scale takes the scale factor as an argument, so normalization is fused into the cast rather than being a separate pass.

The resize step follows the same shape, with the interpolation mode passed explicitly.

```rust
let new_size = ImageSize { width: 128, height: 128 };
let mut gray_resized = Image::<f32, 1>::from_size_val(new_size, 0.0)?;
imgproc::resize::resize_native(
    &gray, &mut gray_resized,
    imgproc::interpolation::InterpolationMode::Bilinear,
)?;
```

After this, gray_resized.size() is 128x128, which is what the README's printed output shows for the equivalent example. If you want to see the images rather than a size, the full example spawns a rerun recording stream and logs the original, the grayscale and the resized image under the names image, gray and gray_resize.

## Where kornia-rs is the wrong tool

The most concrete limitation is release status. The workspace version in Cargo.toml is 0.1.15-rc.5, and the recent releases are all pre-releases: v0.1.15-rc.5, v0.1.15-rc.4 and v0.1.15-rc.3, dated 2026-07-20, 2026-07-06 and 2026-07-06 respectively. A pre-release version means the API is still moving and a patch bump can break your build. If you need a frozen surface, this is not it yet.

The second limitation is Python coverage. The README says plainly that a subset of the full Rust API is exposed through the kornia-rs module and points to the kornia documentation for the Python functions and objects. If your team works in Python and expects the same breadth as the Rust crate, you will hit the boundary of that subset quickly, and the README does not enumerate which operators are on the Python side.

The third is the dependency pin. The workspace Cargo.toml pins candle-core and its siblings at 0.10.2 rather than 0.11, with a comment explaining that candle-core 0.11.0's NEON f16 path references the unstable float16x8_t type without a nightly gate, breaking builds wherever the fp16 target feature is enabled, on macOS CI and on aarch64 Linux. That pin is a real constraint: if your project already depends on candle 0.11, you have a version conflict to resolve, and the comment says the issue was still unfixed upstream at the time of writing.

Finally, format support is read-only in the sense that the README lists the readable formats (AVIF, BMP, DDS, Farbfeld, GIF, HDR, ICO, JPEG, OpenEXR, PNG, PNM, TGA, TIFF, WebP) but describes writers only in the video context. If your workload is batch conversion of image files, a mature imaging library will be less friction.

## kornia-rs compared with OpenCV and with the Python kornia package

The nearest comparison people search for is OpenCV. The difference in approach is where the GPU boundary sits. OpenCV has a large, mature operator set and its own CUDA module, but the CUDA path is a separate set of functions from the CPU path, and moving data between cv::Mat and cv::cuda::GpuMat is an explicit step you write. kornia-rs inverts that: one Image type, operators that dispatch on residency, and interop defined by DLPack and __cuda_array_interface__ rather than by a library-specific container. If your pipeline ends in PyTorch or TensorRT, the second design removes a copy that the first one asks you to manage. If your pipeline is a long chain of classical operators on the CPU, OpenCV's breadth wins and kornia-rs has nothing to offer you.

The other comparison is with the Python kornia package. They share a name and an organization but not a runtime: kornia-rs is the Rust crate and the PyO3/Maturin binding built from it, and the README directs Python users to the kornia documentation for the exposed API. The distinguishing property of the binding is threading. The README states the crate is memory- and thread-safe with no GIL, usable from the free-threaded Python build, and that supported Python versions are 3.8 through 3.14 including the free-threaded 3.13t and 3.14t builds. That is the reason to choose the Rust-backed module over a pure-Python implementation in a multithreaded service.

## Maintenance, licence and the upgrade cost you are signing up for

The repository is not archived, and the last push was on 2026-09-09. The version string in the workspace is 0.1.15-rc.5, and the changelog file CHANGELOG.md sits at the repository root, so release history is tracked in-tree. The presence of a .pre-commit-config.yaml, a pixi.toml and pixi.lock, three devel Dockerfiles (devel-aarch64, devel-i686, devel-x86_64) and a Cross.toml suggests the maintainers test across architectures rather than only on the host. That is a signal about process, not a guarantee about any individual operator.

The upgrade cost is dominated by the pre-release cadence. Three release candidates landed within two weeks in July 2026, and the v0.1.15-rc.5 notes are about GPU op coverage, which means the shape of the GPU surface is still being decided. Pin an exact version in Cargo.toml rather than a caret range if you depend on it in production, and read CHANGELOG.md before moving.

On licensing: the workspace declares license = "Apache-2.0" with a LICENSE file at the root, which is a permissive licence that does not require you to open your own source. The README's badge also shows Apache 2.0. Note that the crate depends on third-party packages with their own licences, including candle, cudarc, gstreamer, image and imageproc, and that GStreamer is LGPL. Whether that matters depends on how you link it, and that is a question for your own legal review, not something the repository answers.

## Conclusion

Adopt kornia-rs if you are building a Rust or free-threaded Python pipeline where frames must reach PyTorch or TensorRT without a host copy, and you accept that the workspace version is 0.1.15-rc.5, a release candidate. Do not adopt it if you need a stable 1.0 API, a mature Python surface, or a wide set of classical algorithms; the README states that only a subset of the Rust API is exposed to Python. Verify first that your target platform is covered by the published wheels (Linux amd64/arm64 including Jetson, macOS and Windows), that your toolchain meets the workspace rust-version of 1.89, and that the specific operator you need is present in the crates you depend on rather than only in the kornia umbrella crate.

## FAQ

### Is OpenCV still relevant next to kornia-rs?

The two solve overlapping problems with different GPU boundaries. OpenCV exposes a separate CUDA function set and an explicit GpuMat transfer, while kornia-rs uses one Image type whose operators dispatch on residency and defines interop through DLPack and the CUDA Array Interface. kornia-rs has a much narrower operator set than OpenCV.

### What libraries are used for computer vision?

kornia-rs is one: a low-level Rust crate with Python bindings via PyO3 and Maturin, covering image I/O, processing operations, camera capture and video writing. Its README names DLPack and __cuda_array_interface__ as the interop path to PyTorch and TensorRT.

### What are some good computer vision libraries for Python?

The kornia-rs Python module is one option, installed with pip install kornia-rs. The README states that only a subset of the full Rust API is exposed to Python, and that the same wheel is CPU-only or activates CUDA when an NVIDIA GPU is present.

## Sources

- [kornia/kornia-rs on GitHub](https://github.com/kornia/kornia-rs)
- [License: Apache-2.0](https://github.com/kornia/kornia-rs/blob/main/LICENSE)
- [Project website](https://docs.rs/kornia)
- [README](https://github.com/kornia/kornia-rs/blob/main/README.md)
- [Releases](https://github.com/kornia/kornia-rs/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/kornia-kornia-rs
