How do I convert an array of two-dimensional Cartesian coordinates to an OpenCV input array?

Viewed 292

Initially, I tried implementing the OpenCV Basic Drawing example with rust using Rust OpenCV bindings (Crate opencv 0.48.0). However, I was stuck.

I want to draw a closed polygon with opencv::imgproc::polylines. The vertices of the polygon are given by an array of two-dimensional Cartesian coordinates. I need to pass these points to the 2nd argument of the function which is of type &dyn opencv::core::ToInputArray. This is where I struggle. How do I convert the array of vertices to an argument of type opencv::core::ToInputArray?

let pts = [[100, 50], [50, 150], [150, 150]];

imgproc::polylines(
        &mut image, 
        ???, <-- "pts" have to go here   
        true, 
        core::Scalar::from([0.0, 0.0, 255.0, 255.0]), 
        1, 8, 0).unwrap();

Minimal example

use opencv::{core, imgproc, highgui};

fn main() {
    let mut image : core::Mat = core::Mat::new_rows_cols_with_default(
        200, 200, core::CV_8UC4, core::Scalar::from([0.0, 0.0, 0.0, 0.0])).unwrap();

    // draw yellow quad
    imgproc::rectangle(
        &mut image, core::Rect {x: 50, y: 50, width: 100, height: 100},
        core::Scalar::from([0.0, 255.0, 255.0, 255.0]), -1, 8, 0).unwrap();

    // should draw red triangle -> causes error (of course)
    /*
    let pts = [[100, 50], [50, 150], [150, 150]];
    imgproc::polylines(
        &mut image, 
        &pts, 
        true, 
        core::Scalar::from([0.0, 0.0, 255.0, 255.0]), 
        1, 8, 0).unwrap();
    */

    highgui::imshow("", &image).unwrap();
    highgui::wait_key(0).unwrap();
}
[dependencies]
opencv = {version = "0.48.0", features = ["buildtime-bindgen"]}
1 Answers

I found the solution with the help of the comment from @kmdreko.

I can define the vertices with an opencv::types::VectorOfPoint, that implements an opencv::core::ToInputArray trait:

let pts = types::VectorOfPoint::from(vec![
    core::Point{x: 100, y: 50},
    core::Point{x: 50, y: 150},
    core::Point{x: 150, y: 150}]
);

Complete example:

use opencv::{core, types, imgproc, highgui};

fn main() {
    let mut image : core::Mat = core::Mat::new_rows_cols_with_default(
        200, 200, core::CV_8UC4, core::Scalar::from([0.0, 0.0, 0.0, 0.0])).unwrap();

    let pts = types::VectorOfPoint::from(vec![
        core::Point{x: 100, y: 50},
        core::Point{x: 50, y: 150},
        core::Point{x: 150, y: 150}]
    );

    imgproc::polylines(
        &mut image, 
        &pts, 
        true, 
        core::Scalar::from([0.0, 0.0, 255.0, 255.0]), 
        1, 8, 0).unwrap();
    
    highgui::imshow("", &image).unwrap();
    highgui::wait_key(0).unwrap();
}
Related