Library / SDK
kornia/kornia-rs avatar
kornia/kornia-rs

kornia-rs: a Rust computer vision crate that shares one Image type across CPU and CUDA

🦀 Low-level 3D Computer Vision library in Rust

707 stars198 forksRustApache-2.0

At a glance

What is it?
kornia-rs is a low-level Rust computer vision library with Python bindings, built around a single Image type that dispatches on where the data lives. It is aimed at real-time pipelines that need to hand frames to PyTorch or TensorRT without a host copy, and its release history is still pre-1.0.
Who is it for?
Adopt kornia-rs if you are writing a Rust service or a Python pipeline that already holds frames on an NVIDIA GPU and wants to skip the host round trip into PyTorch, and if you can accept a 0.1.x dependency whose newest published versions are release candidates. Do not adopt it if you need a stable API surface, a documented performance envelope, or GPU parity with the CPU operator list, because the release notes themselves describe the GPU coverage as still being filled in.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The problem kornia-rs targets: frames that already live on the GPU

Most computer vision code in Rust is a collection of separate crates: one for decoding, one for pixel manipulation, one for tensor math. Each has its own buffer type, and moving data between them usually means a copy. kornia-rs takes the opposite position. The README describes it as a low-level computer vision library where the same Image type and the same operators dispatch on where the data lives, with no separate GPU types. That single design decision is the whole pitch. If a decoded frame is already on an NVIDIA GPU, the operators that follow it do not need a new abstraction or a transfer to host memory. The README also states that results are handed to PyTorch and TensorRT with no host copy through DLPack and the CUDA Array Interface, and that a camera frame can be fused into a normalized model input in one CUDA kernel. The intended audience is therefore narrow and identifiable: engineers building real-time inference pipelines in Rust, or Python engineers using the bindings, who care about the cost of each frame copy between capture and model input. It is not a general-purpose image library for someone who just wants to resize a PNG.

One Image type, two residencies, and the interop that makes it useful

The mechanism visible in the README is a generic image container parameterized by element type and channel count, written as Image<u8, 3> or Image<f32, 1>. Reading a file returns Image<u8, 3> from read_image_any_rgb8. Conversion to float is explicit: cast_and_scale::<f32>(1.0 / 255.0) returns Image<f32, 3>. Operators then take input and output images as separate arguments, as in gray_from_rgb(&image_f32, &mut gray) and resize_native(&gray, &mut gray_resized, InterpolationMode::Bilinear). Output buffers are allocated by the caller with Image::<f32, 1>::from_size_val(size, 0.0), which means the caller controls allocation and can reuse buffers across frames. That is a deliberate choice for a real-time library and it pushes lifetime and sizing decisions onto the application. The dispatch claim is that the same types work whether the backing memory is host or device. The interop layer is what makes this usable outside Rust: DLPack and __cuda_array_interface__ for PyTorch, plus numpy views. The README also mentions V4L2 camera capture and a fused NV12/YUYV to normalized CHW CUDA kernel, which is the concrete example of where a fused kernel beats a chain of separate operators.

Installing it: one crate, ten sub-crates, and optional system packages

For Rust, the README gives a single dependency line, kornia = "0.1", and lists the sub-crates that can be pulled in 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 time and for dependency hygiene: a project that only needs tensor math does not have to compile the AprilTag detector. For Python, the install is pip install kornia-rs, and the README is explicit that only a subset of the full Rust API is exposed, pointing at the kornia documentation for what the Python module actually provides. Three optional system dependencies are named with their install commands: clang for v4l (Video4Linux camera support), nasm for turbojpeg, and libgstreamer1.0-dev plus libgstreamer-plugins-base1.0-dev for gstreamer, with a pointer to the gstreamer crate's own installation guide. The README does not state which Cargo features gate these, so a reader who needs V4L2 capture should expect to check the crate's feature list rather than assume the system package alone is sufficient. The README also states that the same Python wheel is CPU-only or activates CUDA when an NVIDIA GPU is present, and that supported Python versions run from 3.8 through 3.14 including the free-threaded build.

Reading a file and resizing it: the shape of a kornia-rs program

The quick example is small enough to be worth reading closely. It imports kornia::image::Image and kornia::io::functional as F, calls F::read_image_any_rgb8 on a JPEG path, and prints the size. The README shows the expected output as ImageSize { width: 258, height: 195 }. The longer example shows the pipeline shape: read, clone for visualization, cast_and_scale to f32 with a 1/255 factor, allocate a single-channel float image, run gray_from_rgb, allocate a 128 by 128 single-channel float image, run resize_native with Bilinear interpolation, then log all three images to a rerun recording stream. Every operator returns a Result, so error handling is part of the call site rather than an exception. The allocation pattern is the part worth noticing: nothing in the example returns a new image from an operator. The caller creates the destination and passes a mutable reference. That is more verbose than a chain of method calls, and it is also the reason the library can be used in a loop over camera frames without allocating on every iteration. The rerun dependency in the example is illustrative only; it is not part of the kornia crate.

Where kornia-rs is the wrong tool, and what the release history says

The version numbering is the first thing to weigh. The crate is at 0.1, and the three most recent releases listed are v0.1.15-rc.5, v0.1.15-rc.4 and v0.1.15-rc.3, all pre-releases. The newest is titled around GPU op coverage: filters, pyramids, CLAHE, Canny, CCL and a fusion engine. That title is itself the limitation. If GPU operator coverage was still being filled in at rc.5 of 0.1.15, then a reader cannot assume that an operator available on the CPU is also available on the GPU path, and the README does not publish a matrix of which operators exist on which backend. The second limitation is the API surface. A 0.1.x crate with frequent release candidates makes no stability promise, so pinning an exact version is the only way to keep a build reproducible. The third is scope. The Python bindings expose a subset of the Rust API, so a Python user who needs a specific operator has to check whether it is exposed before designing around it. Finally, the README makes no performance claim with numbers, and no benchmark results are given, so anyone comparing kornia-rs to another library on speed has nothing in this material to compare against.

How it differs from OpenCV bindings and the image crate stack

The obvious comparison is OpenCV through its Rust or Python bindings. OpenCV is a mature, wide library whose core is C++, with its own Mat type and its own memory model. Its GPU path is a separate module set with its own types, so code written against the CPU API does not automatically run on the GPU. kornia-rs inverts that: the README states the same Image and operators dispatch on residency, with no separate GPU types. The trade is breadth for uniformity. OpenCV has decades of operators; kornia-rs has a set the release notes describe as still expanding, particularly on the GPU side. A second comparison is the pure-Rust image stack, the image crate plus imageproc. Those crates are easy to build, have no CUDA dependency, and cover decoding and common pixel operations. They do not offer DLPack interop, CUDA Array Interface export, or a fused NV12/YUYV to normalized CHW kernel, and they do not have a Python binding story. If your pipeline ends in a PyTorch model on the same GPU that captured the frame, the difference between kornia-rs and the image crate stack is the number of copies per frame, which is exactly the axis kornia-rs was designed around.

Licence, maintenance and the cost of tracking a pre-1.0 crate

The licence is Apache-2.0, stated in the repository metadata and shown as a badge in the README. That is a permissive licence, and it is the same licence family as much of the Rust ecosystem, which simplifies redistribution. This is not legal advice; if you ship a product, have your own counsel read the LICENSE file and the licences of the dependencies, particularly the optional gstreamer and turbojpeg paths. On maintenance, the material supports only a limited reading: the default branch is main, the repository is not archived, and the most recent push recorded is 2026-09-09, with the newest release candidate dated 2026-07-20. The cadence of release candidates within a single patch version suggests active development rather than a frozen API. The practical cost is upgrade work. Every 0.1.x bump can move types or signatures, and the caller-allocated output pattern means a signature change touches every operator call site in your code. Budget for reading the changelog before each bump, and pin the version in Cargo.toml rather than tracking a caret range if you need reproducible builds. The README lists a Discord for support; there is no stated support or deprecation policy.

Editorial conclusion

Adopt kornia-rs if you are writing a Rust service or a Python pipeline that already holds frames on an NVIDIA GPU and wants to skip the host round trip into PyTorch, and if you can accept a 0.1.x dependency whose newest published versions are release candidates. Do not adopt it if you need a stable API surface, a documented performance envelope, or GPU parity with the CPU operator list, because the release notes themselves describe the GPU coverage as still being filled in. Before committing, pin the exact version you intend to ship, read the changelog for the release you pin, and confirm on your own hardware that the operators you depend on are present in the GPU path and not only on the CPU path.

Official sources

  1. kornia/kornia-rs on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
Community notes

Community notes