Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change Project structure to be a little more scalable #6

Merged
merged 1 commit into from
Sep 9, 2024

Conversation

Hennzau
Copy link
Collaborator

@Hennzau Hennzau commented Sep 6, 2024

Objective

Hi! This is the final useful PR for #4. After ensuring everything was easy to use and to create new datatypes, I slightly changed the entire structure of the project to make it a bit more scalable. Here’s how it looks: 😎

Usage

To create a new datatype, you need to add a module in the libraries/datatypes crate. If you want to add ndarray or arrow support for this datatype, you’ll need to create a ndarray.rs or arrow.rs submodule that will use the functions and structures from the libraries/converter crate. For example, for BBox’s arrow support, we use the fastformat_converter::arrow module:

use fastformat_converter::arrow::{FastFormatArrowBuilder, FastFormatArrowRawData};

impl<'a> BBox<'a> {
    pub fn raw_data(array_data: arrow::array::ArrayData) -> Result<FastFormatArrowRawData> {
        use arrow::datatypes::Float32Type;

        let raw_data = FastFormatArrowRawData::new(array_data)?
            .load_primitive::<Float32Type>("data")?
            .load_primitive::<Float32Type>("confidence")?
            .load_utf("label")?
            .load_utf("encoding")?;

        Ok(raw_data)
    }

    pub fn from_raw_data(mut raw_data: FastFormatArrowRawData) -> Result<Self> {
        use arrow::datatypes::Float32Type;

        let data = raw_data.primitive_array::<Float32Type>("data")?;
        let confidence = raw_data.primitive_array::<Float32Type>("confidence")?;
        let label = raw_data.utf8_array("label")?;
        let encoding = Encoding::from_string(raw_data.utf8_singleton("encoding")?)?;

        Ok(Self {
            data: Cow::Owned(data),
            confidence: Cow::Owned(confidence),
            label,
            encoding,
        })
    }
}

We do the same for ndarray support. 🤓

Features

I’ve added the [[features]] tag for the fastformat crates, so that we don’t add a bunch of dependencies for people who don’t need them. 🚀

[dependencies]
fastformat = { version = "0.1.0", features = ["arrow", "ndarray"] }

@Hennzau Hennzau changed the title Change Project structure to me a little more useful Change Project structure to be a little more scalable Sep 6, 2024
@Hennzau Hennzau self-assigned this Sep 6, 2024
@Hennzau Hennzau added the enhancement New feature or request label Sep 6, 2024
@haixuanTao
Copy link
Contributor

Relevant to this PR: kornia/kornia-rs#115

I talked with @edgarriba and he is happy to work with us to make kornia a thing in dora-rs. And as performance is a key criteria for dora, it's interesting that if i recall correctly kornia can be slightly faster than opencv.

@Hennzau Hennzau merged commit 7b6a2d7 into other_datatype Sep 9, 2024
24 checks passed
@Hennzau Hennzau deleted the project-structure branch September 9, 2024 08:31
pub mod arrow;

#[cfg(feature = "ndarray")]
pub mod ndarray;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here, some support conversion from kornia-dnn (to landed this week).
Still iterating on the Detection struct, but for now what we have is sufficient enough to keep it lightweighted

Copy link

@edgarriba edgarriba Sep 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Hennzau @haixuanTao the kornia-dnn basically is a wrapper around the ort crate which I'm iterating with the author in order to run inference the models from kornia-pytorch-models from the HF hub: https://huggingface.co/kornia/ONNX_models that @shijianjian has been working on

@Hennzau
Copy link
Collaborator Author

Hennzau commented Sep 9, 2024

Adding Kornia is a really good idea, I made this PR so it's easy to add/change conversion wrapper!

I opened #8 to make all the needed changes :)

Hennzau added a commit that referenced this pull request Sep 9, 2024
# Objective

This PR adds a new datatype for **BBox** to ensure that everything work
well and it's easy to add a new datatype.

# Datatypes & Usage

- [x] Image

```Rust
use crate::image::Image;

let flat_image = (0..27).collect::<Vec<u8>>();
let image = Image::new_rgb8(flat_image, 3, 3, Some("camera.test")).unwrap();

let final_image = image.into_bgr8().unwrap();
let final_image_data = final_image.data.as_u8().unwrap();

let expected_image = vec![
    2, 1, 0, 5, 4, 3, 8, 7, 6, 11, 10, 9, 14, 13, 12, 17, 16, 15, 20, 19, 18, 23, 22, 21,
    26, 25, 24,
];

assert_eq!(&expected_image, final_image_data);

use crate::image::Image;

let flat_image = vec![0; 27];
let original_buffer_address = flat_image.as_ptr();

let bgr8_image = Image::new_bgr8(flat_image, 3, 3, None).unwrap();
let image_buffer_address = bgr8_image.as_ptr();

let arrow_image = bgr8_image.into_arrow().unwrap();

let new_image = Image::from_arrow(arrow_image).unwrap();
let final_image_buffer = new_image.as_ptr();

assert_eq!(original_buffer_address, image_buffer_address);
assert_eq!(image_buffer_address, final_image_buffer);
```

- [x] BBox

```Rust
use crate::bbox::BBox;

let flat_bbox = vec![1.0, 1.0, 2.0, 2.0];
let confidence = vec![0.98];
let label = vec!["cat".to_string()];

let bbox = BBox::new_xyxy(flat_bbox, confidence, label).unwrap();
let final_bbox = bbox.into_xywh().unwrap();
let final_bbox_data = final_bbox.data;

let expected_bbox = vec![1.0, 1.0, 1.0, 1.0];

assert_eq!(expected_bbox, final_bbox_data);

use crate::bbox::BBox;

let flat_bbox = vec![1.0, 1.0, 2.0, 2.0];
let original_buffer_address = flat_bbox.as_ptr();

let confidence = vec![0.98];
let label = vec!["cat".to_string()];

let xyxy_bbox = BBox::new_xyxy(flat_bbox, confidence, label).unwrap();
let bbox_buffer_address = xyxy_bbox.data.as_ptr();

let arrow_bbox = xyxy_bbox.into_arrow().unwrap();

let new_bbox = BBox::from_arrow(arrow_bbox).unwrap();
let final_bbox_buffer = new_bbox.data.as_ptr();

assert_eq!(original_buffer_address, bbox_buffer_address);
assert_eq!(bbox_buffer_address, final_bbox_buffer);
```

# Quick Fixes

- I also improved readability and consistency with Rust formatting,
following the guidelines mentioned in [this
comment](#1 (comment)).
- Fix Arrow Array extraction from Union inside #3 
- Fix Dora compatibility (by viewing objects when it's not possible to
own them) inside #5
- I improved the structure of the library, with separated packages and
with some `features` as one might want to use `fastformat` only with
ndarray/arrow. #6
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants