kornia / kornia-rs

Low-level Computer Vision library in Rust
https://docs.rs/kornia
Apache License 2.0
192 stars 18 forks source link

kornia-rs: low level computer vision library in Rust

Crates.io Version PyPI version Documentation License Slack

The kornia crate is a low level library for Computer Vision written in Rust πŸ¦€

Use the library to perform image I/O, visualisation and other low level operations in your machine learning and data-science projects in a thread-safe and efficient way.

Getting Started

cargo run --bin hello_world -- --image-path path/to/image.jpg

use kornia::image::Image;
use kornia::io::functional as F;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // read the image
    let image: Image<u8, 3> = F::read_image_any("tests/data/dog.jpeg")?;

    println!("Hello, world! πŸ¦€");
    println!("Loaded Image size: {:?}", image.size());
    println!("\nGoodbyte!");

    Ok(())
}
Hello, world! πŸ¦€
Loaded Image size: ImageSize { width: 258, height: 195 }

Goodbyte!

Features

Supported image formats

Image processing

Video processing

πŸ› οΈ Installation

>_ System dependencies

Dependeing on the features you want to use, you might need to install the following dependencies in your system:

turbojpeg

sudo apt-get install nasm

gstreamer

sudo apt-get install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev

** Check the gstreamr installation guide: https://docs.rs/gstreamer/latest/gstreamer/#installation

πŸ¦€ Rust

Add the following to your Cargo.toml:

[dependencies]
kornia = "v0.1.7"

Alternatively, you can use each sub-crate separately:

[dependencies]
kornia-core = { git = "https://github.com/kornia/kornia-rs", tag = "v0.1.7" }
kornia-io = { git = "https://github.com/kornia/kornia-rs", tag = "v0.1.7" }
kornia-image = { git = "https://github.com/kornia/kornia-rs", tag = "v0.1.7" }
kornia-imgproc = { git = "https://github.com/kornia/kornia-rs", tag = "v0.1.7" }

🐍 Python

pip install kornia-rs

Examples: Image processing

The following example shows how to read an image, convert it to grayscale and resize it. The image is then logged to a rerun recording stream.

Checkout all the examples in the examples directory to see more use cases.

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

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // read the image
    let image: Image<u8, 3> = F::read_image_any("tests/data/dog.jpeg")?;
    let image_viz = image.clone();

    let image_f32: Image<f32, 3> = image.cast_and_scale::<f32>(1.0 / 255.0)?;

    // convert the image to grayscale
    let mut gray = Image::<f32, 1>::from_size_val(image_f32.size(), 0.0)?;
    imgproc::color::gray_from_rgb(&image_f32, &mut gray)?;

    // resize the image
    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::resize::InterpolationMode::Bilinear,
    )?;

    println!("gray_resize: {:?}", gray_resized.size());

    // create a Rerun recording stream
    let rec = rerun::RecordingStreamBuilder::new("Kornia App").connect()?;

    // log the images
    let _ = rec.log("image", &rerun::Image::try_from(image_viz.data)?);
    let _ = rec.log("gray", &rerun::Image::try_from(gray.data)?);
    let _ = rec.log("gray_resize", &rerun::Image::try_from(gray_resized.data)?);

    Ok(())
}

Screenshot from 2024-03-09 14-31-41

Python usage

Load an image, that is converted directly to a numpy array to ease the integration with other libraries.

    import kornia_rs as K
    import numpy as np

    # load an image with using libjpeg-turbo
    img: np.ndarray = K.read_image_jpeg("dog.jpeg")

    # alternatively, load other formats
    # img: np.ndarray = K.read_image_any("dog.png")

    assert img.shape == (195, 258, 3)

    # convert to dlpack to import to torch
    img_t = torch.from_dlpack(img)
    assert img_t.shape == (195, 258, 3)

Write an image to disk

    import kornia_rs as K
    import numpy as np

    # load an image with using libjpeg-turbo
    img: np.ndarray = K.read_image_jpeg("dog.jpeg")

    # write the image to disk
    K.write_image_jpeg("dog_copy.jpeg", img)

Encode or decode image streams using the turbojpeg backend

import kornia_rs as K

# load image with kornia-rs
img = K.read_image_jpeg("dog.jpeg")

# encode the image with jpeg
image_encoder = K.ImageEncoder()
image_encoder.set_quality(95)  # set the encoding quality

# get the encoded stream
img_encoded: list[int] = image_encoder.encode(img)

# decode back the image
image_decoder = K.ImageDecoder()

decoded_img: np.ndarray = image_decoder.decode(bytes(image_encoded))

Resize an image using the kornia-rs backend with SIMD acceleration

import kornia_rs as K

# load image with kornia-rs
img = K.read_image_jpeg("dog.jpeg")

# resize the image
resized_img = K.resize(img, (128, 128), interpolation="bilinear")

assert resized_img.shape == (128, 128, 3)

πŸ§‘β€πŸ’» Development

Pre-requisites: install rust and python3 in your system.

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Clone the repository in your local directory

git clone https://github.com/kornia/kornia-rs.git

πŸ¦€ Rust

Compile the project and run the tests

cargo test

For specific tests, you can run the following command:

cargo test image

🐍 Python

To build the Python wheels, we use the maturin package. Use the following command to build the wheels:

make build-python

To run the tests, use the following command:

make test-python

πŸ’œ Contributing

This is a child project of Kornia. Join the community to get in touch with us, or just sponsor the project: https://opencollective.com/kornia