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

#Suggestion# How about simplify the API #332

Closed
Frank1126lin opened this issue Mar 20, 2022 · 16 comments
Closed

#Suggestion# How about simplify the API #332

Frank1126lin opened this issue Mar 20, 2022 · 16 comments

Comments

@Frank1126lin
Copy link

I am using the opencv rust bindings these days, which I want try to switch the program into rustlang. Well, it seem the API need a lot prelude work before I using the right function. Such as if I need "imwrite", I need to create a parms of ImwriteFlags first. Also, as I want to draw a rectangle, I need to create the line color params and Rect params first. How about just reshape it as a tuple or list instead? I wish the API is as easily used as Python API, that would be much easier for most of us.

@twistedfall
Copy link
Owner

Thanks for the suggestion! If I understand correctly you'd like to improve the usability of passing structures like Point, Rect etc, right? A quick solution to that would be to add the corresponding From implementations so that you could use, e.g.:

(10, 20).into()

where a Point is required.

Is it something that would improve your experience?

@Frank1126lin
Copy link
Author

Yeah, thanks a lot. As I am just a freshman to the rust as well as the opencv, I just try to understand the overall logic of cv. I will leave my immature ideas here if needed.

@twistedfall
Copy link
Owner

You can check out this nice article that should help you get started: https://blog.devgenius.io/rust-and-opencv-bb0467bf35ff

Let's leave this issue open until the fixes are pushed.

@twistedfall twistedfall reopened this Mar 21, 2022
@Frank1126lin
Copy link
Author

In my cases , I use a lib.rs to simplify my main code like this, I learned the python opencv bindings and then code it with rust.

name: lib.rs

use opencv::highgui;
use anyhow::{Result, Error};
use opencv::prelude::*;


pub fn img_show(name: &str, img: &Mat, hight: i32, width: i32) -> Result<()> {
    highgui::named_window(name, highgui::WINDOW_FREERATIO)?;
    highgui::resize_window(name, hight, width)?;
    highgui::imshow(name, img)?;
    Ok(())
}

pub fn close_show(i: i32) -> Result<()> {
    highgui::wait_key(i)?;
    highgui::destroy_all_windows()?;
    Ok(())
}

pub fn img_shape(img: &Mat) -> Result<(i32, i32, i32), Error> {
    let shape = (img.rows(), img.cols(), img.channels());
    Ok(shape)
}

so ,just like the shape function, I DIY it with the Mat to get all the info from a img.

@twistedfall
Copy link
Owner

Well, if it's about shape function then it's provided by numpy, not by OpenCV and thus quite Python-specific. I don't expect to add anything like this to the codebase unless it's already exposed by Mat class because generally I try to avoid adding any manual functionality not already present in OpenCV to reduce maintenance burden.

@Frank1126lin
Copy link
Author

Frank1126lin commented Mar 26, 2022

Is there any reference to the calc_hist fn? I looked up the Doc.rs and searched on the web, didn't find some worth infomation about my error, the code looks like this.

use anyhow::Result;
use opencv::{
    prelude::*,
    core::*,
    imgcodecs,
    imgproc,

};

mod lib;
use lib::{img_shape, img_show, close_show};

fn main() -> Result<()> {
    let img = imgcodecs::imread("../../../images/1.jpg", imgcodecs::IMREAD_GRAYSCALE)?;
    println!("img shape: {:?}", img_shape(&img)?);
    let mut hist = Mat::default();
    imgproc::calc_hist(
        &img,
        &Vector::from_slice(&[0]),
        &no_array(),
        &mut hist,
        &Vector::from_slice(&[255]),
        &Vector::from_slice(&[0., 255.]),
        false
    )?;
    Ok(())
}

And the error shows:

Error: OpenCV(4.5.5) C:\build\master_winpack-build-win64-vc15\opencv\modules\core\src\matrix.cpp:769: error: 
(-215:Assertion failed) 0 <= _rowRange.start && _rowRange.start <= _rowRange.end && _rowRange.end <= m.rows in function 'cv::Mat::Mat' (code: -215)
error: process didn't exit successfully: 
`D:\00-Program\05-Rust\04-RustImage\Opencv4-entry\06-imgHist\img_hist\target\debug\img_hist.exe` (exit code: 1)

It seems the docs on the Doc.rs it not enough for me to get the answers and to show the histograms. Any help? Thanks a lot.

@twistedfall
Copy link
Owner

You should check the original OpenCV docs here: https://docs.opencv.org/4.x/d6/dc7/group__imgproc__hist.html#ga4b2b5fd75503ff9e6844cc4dcdaed35d

@Frank1126lin
Copy link
Author

It seems the problem comes below, but I tried to compare the diff between the C++ version and Doc.rs, still can't find the mistake.
So ,Could you please share a similar example?
Code:

    let mut hist = Mat::default();
    let channel = Vector::from_slice(&[0]);
    imgproc::calc_hist(
        &img,
        &channel,
        &no_array(),
        &mut hist,
        &Vector::from_slice(&[255]),
        &Vector::from_slice(&[0., 256.]),
        false
    )?; 

Error:

Error: OpenCV(4.5.5) C:\build\master_winpack-build-win64-vc15\opencv\modules\core\src\matrix.cpp:769: error: (-215:Assertion failed) 0 <= _rowRange.start && _rowRange.start <= _rowRange.end && _rowRange.end <= m.rows in function 'cv::Mat::Mat'
 (code: -215)
error: process didn't exit successfully: `D:\00-Program\05-Rust\04-RustImage\Opencv4-entry\06-imgHist\img_hist\target\debug\img_hist.exe` (exit code: 1)

@twistedfall
Copy link
Owner

It's quite difficult to help here without the context. It would help if you could write a working example in Python or C++ and then I can help convert it to Rust

@Frank1126lin
Copy link
Author

Frank1126lin commented Apr 2, 2022

In Python as below:

import cv2
import numpy as np
import matplotlib.pyplot as plt


img = cv2.imread("../image/1.jpg", 0)
hist = cv2.calcHist([img], [0], None, [256], [0, 256])

dst = cv2.equalizeHist(img)
plt.imshow(dst, cmap=plt.cm.gray)

plt.figure(figsize=(10, 8))
plt.plot(hist)
plt.show()

Something like this, I can't convert it using rust-bindings.

@Frank1126lin
Copy link
Author

Is there any solution to the situation above? Or just something wrong with my steps?

@twistedfall
Copy link
Owner

The Python example shown above works correctly on the same image that you're trying to run Rust on, right?

@Frank1126lin
Copy link
Author

The Python example shown above works correctly on the same image that you're trying to run Rust on, right?

Yeah, the python code can run correctly, and can show the hist graph.

@twistedfall
Copy link
Owner

This produces the same result as the python code on my machine:

use opencv::{prelude::*, core, types, imgproc, imgcodecs};

fn main() {
	let img = imgcodecs::imread("1.jpg", imgcodecs::IMREAD_GRAYSCALE).unwrap();
	let mut images = types::VectorOfMat::new();
	images.push(img);
	let mut hist = Mat::default();
	imgproc::calc_hist(
		&images,
		&vec![0].into(),
		&core::no_array(),
		&mut hist,
		&vec![256].into(),
		&vec![0., 256.].into(),
		false,
	).unwrap();
	dbg!(&hist.data_typed::<f32>());
}

@Frank1126lin
Copy link
Author

I got the right result as well adding code below .

let mut images = types::VectorOfMat::new();
images.push(img);

Is this means the input of the calc_hist should be a Vector ranther than a Mat?
By the way, could you please share some tips on how to show the hist graph?

@twistedfall
Copy link
Owner

Is this means the input of the calc_hist should be a Vector ranther than a Mat?

Yes, in fact, in Python code that's exactly what you're passing to the cv2.calcHist call.

By the way, could you please share some tips on how to show the hist graph?

Not really unfortunately, I've never had to use this particular function myself.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants