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

OpenCV's highgui::select_roi() function does not render fully when used with Slint (Rust) #5085

Closed
Dirleye opened this issue Apr 17, 2024 · 2 comments

Comments

@Dirleye
Copy link
Contributor

Dirleye commented Apr 17, 2024

opencv::highgui::select_roi() spawns a window displaying a given image from which a user can select a bounding box with the mouse, returning an OpenCV::core::Rect object representing the area they drew.

For whatever reason, running this function from inside of a Slint callback handler works as normal, but the bounding box the user draws isn't visible in the OpenCV window. Since select_roi() spawns the window itself (I think it uses Qt?) I have no idea why using Slint would have an impact.

This bug occurs on Windows 10 with the latest Rust release. It does not occur on Linux.
Here is a basic example:

use opencv::prelude::*;
use opencv::highgui;
use opencv::videoio::VideoCapture;

slint::include_modules!();


fn get_roi() -> opencv::Result<()> {
    let window_name = "Selection Window";

    // Read the first frame of a video into a variable
    let mut player = VideoCapture::from_file_def("/path/to/video.mp4")?;
    let mut frame = Mat::default();
    player.read(&mut frame)?;

    // Create a new named window
    highgui::named_window(&window_name, highgui::WindowFlags::WINDOW_NORMAL.into())?;
    
    // Spawn the window with the frame we got earlier, allowing the user to select an area
    highgui::select_roi(&window_name, &frame, true, false, false)?;
    highgui::destroy_window(&window_name)?;

    Ok(())
}


fn main() {
    let ui = AppWindow::new().unwrap();

    ui.global::<PlayerLogic>().on_roi_button(
        move || get_roi().unwrap()
    );

    ui.run().unwrap();
}

Where on_roi_button() is just a callback from a button's clicked event.
Running this code as-is results in the bug, whereas running the get_roi() function from main() and commenting out any Slint related code results in the spawned window showing the bounding box the user draws normally.

This bug is purely visual - highgui::select_roi() still returns the rectangle the user drew, it just doesn't show it while it's being drawn.

I'm not sure what could be causing this. I've raised the issue with opencv-rust, but that didn't get anywhere since it works without Slint.

Thank you for any help. It's been a pleasure using Slint so far.

@ogoffart
Copy link
Member

ogoffart commented May 6, 2024

I have no idea about what opencv is going there.
I would assume maybe the problem might be because each library has its own event loop. And that the opencv event loop is blocking the slint event loop or vice versa.
You may need to try to run the opencv code in a different thread. See https://docs.rs/slint/latest/slint/fn.invoke_from_event_loop.html#example

@Dirleye
Copy link
Contributor Author

Dirleye commented May 8, 2024

On first attempt threading and invoking from Slint's event loop doesn't seem to make a difference but I didn't test particularly thoroughly.
I got around it by making the region of interest selector inside the Slint app instead of using OpenCV's built-in one which looks much nicer anyway.
I'll close this because I don't think it's a problem with Slint.

Thank you for your thoughts and suggestion though!

@Dirleye Dirleye closed this as completed May 8, 2024
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