Rust opencv crate has very severe camera lag

52 Views Asked by At

Title could be worded better, but essentially I am trying to use open cv in Rust and I found the opencv crate

I am using Rust 1.76.0 and opencv crate version 0.88.8

I am running things on Ubuntu 22.04

Per the installation instructions from github I downloaded these

apt install libopencv-dev clang libclang-dev

Per the example from the github page I then tried this to display camera feed

use opencv::{highgui, prelude::*, videoio, Result};

fn main() -> Result<()> {
    let window = "video capture";
    highgui::named_window(window, highgui::WINDOW_AUTOSIZE)?;
    let mut cam = videoio::VideoCapture::new(0, videoio::CAP_ANY)?; // 0 is the default camera
    let opened = videoio::VideoCapture::is_opened(&cam)?;
    if !opened {
        panic!("Unable to open default camera!");
    }
    loop {
        let mut frame = Mat::default();
        cam.read(&mut frame)?;
        if frame.size()?.width > 0 {
            highgui::imshow(window, &frame)?;
        }
        let key = highgui::wait_key(10)?;
        if key > 0 && key != 255 {
            break;
        }
    }
    Ok(())
}

It works, but it is extremely slow, feels very laggy

I am using a webcam as the camera device, it should have around 22-24 FPS but in Rust it's most like 8 FPS

    let fps_start = Instant::now();             
    let num_frames_to_measure = 60;             
    for _ in 0..num_frames_to_measure {         
        let mut temp_frame = Mat::default();    
        cam.read(&mut temp_frame)?;             
    }                                           
    let fps_duration = fps_start.elapsed();     
    let fps = num_frames_to_measure as f64 / fps
    println!("Measured FPS: {:?}", fps);        

This is the comparison Python code

import cv2


vid = cv2.VideoCapture(0)
while True:
    ret, frame = vid.read()
    cv2.imshow('window', frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

vid.release()
cv2.destroyAllWindows()

Python version has no lag what so ever

Is the camera feed being slow just something I overlooked or is it just simply the way things currently are?

My scenario is that I need to take pictures, convert them into HSV and do some processing

By doing this in Rust I was hoping to speed up both the picture taking and processing part

EDIT:

To answer my own question setting a WIDTH and HEIGHT on the camera fixes the FPS issues.

use opencv::core::Vector;
use opencv::{
    highgui,
    prelude::*,
    videoio,
    imgcodecs
};
use std::time::Instant;


fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 1. Setup
    let setup_start = Instant::now();
    let mut cam = videoio::VideoCapture::new(0, videoio::CAP_ANY)?;  // 0 is the default camera
    let opened = videoio::VideoCapture::is_opened(&cam)?;
    if !opened {
        println!("Unable to open default camera!");
        return Ok(());
    }
    cam.set(videoio::CAP_PROP_FRAME_WIDTH, 640.0)?; // Set frame width
    cam.set(videoio::CAP_PROP_FRAME_HEIGHT, 480.0)?; // Set frame height
    let setup_duration = setup_start.elapsed().as_secs_f64(); // Calculate setup duration
    println!("Setup duration: {:?}", setup_duration); // Print setup duration

    // 2. Measure FPS
    let fps_start = Instant::now();
    let num_frames_to_measure = 60;
    for _ in 0..num_frames_to_measure {
        let mut temp_frame = Mat::default();
        cam.read(&mut temp_frame)?;
    }
    let fps_duration = fps_start.elapsed();
    let fps = num_frames_to_measure as f64 / fps_duration.as_secs_f64();
    println!("Measured FPS: {:?}", fps);

    // 3. Display the video feed
    loop {
        let mut frame = Mat::default();
        cam.read(&mut frame)?;
        if frame.size()?.width > 0 {
            highgui::imshow("camera", &frame)?;
            let key = highgui::wait_key(1)?;
            if key == 13 {  // If you press 'q' program exits
                break;
            }
        }
    }
    
    // 5. Function end
    Ok(())
}

0

There are 0 best solutions below