🖼️ Basic Image Operations with OpenCV and Rust

Learn how to Display and Save Images using OpenCV

Posted by Tech Blogger on April 22, 2024

🖼️ Basic Image Operations with OpenCV and Rust

📚 Table of Contents

  1. Setting Up
  2. Displaying Images
  3. Saving Images
  4. Complete Implementation
  5. Common Issues and Solutions

Setting Up

First, let’s import the necessary OpenCV modules:

1
2
3
4
5
6
use opencv::{
    core::{self, MatTraitConst}, 
    highgui, 
    imgcodecs,
    Result
};

Displaying Images 🖥️

Loading and displaying an image is one of the most basic operations in OpenCV. Here’s how to do it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
pub fn display_image() -> Result<()> {
    // Load the image
    let src = imgcodecs::imread(
        "./img/lion.jpeg", 
        imgcodecs::IMREAD_COLOR
    )?;

    // Display the image
    highgui::imshow("Image Display", &src)?;
    
    // Wait for 10 seconds
    highgui::wait_key(10000)?;
    
    // Clean up
    highgui::destroy_all_windows()?;
    
    Ok(())
}

Saving Images 💾

Saving images requires a few more steps to ensure quality and proper handling:

1. Create Image Matrix

1
2
let mut src = core::Mat::default();
src = imgcodecs::imread("./img/lion.jpeg", imgcodecs::IMREAD_COLOR)?;

2. Validate Image Data

1
2
3
4
if src.empty() {
    println!("Image load failed");
    std::process::exit(0);
}

3. Set Quality Parameters

1
2
3
let mut params = core::Vector::default();
params.push(imgcodecs::IMWRITE_JPEG_QUALITY);  // Quality parameter
params.push(95);  // Quality value (0-100)

4. Save the Image

1
2
3
4
5
imgcodecs::imwrite(
    "./img/write_test.png", 
    &src, 
    &params
)?;

Complete Implementation

Here’s the complete code that demonstrates both loading and saving images:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
use opencv::{
    core::{self, MatTraitConst}, 
    highgui, 
    imgcodecs,
    Result
};

pub fn main() -> Result<()> {
    // Initialize default matrix
    let mut src = core::Mat::default();
    
    // Load image
    src = imgcodecs::imread(
        "./img/lion.jpeg", 
        imgcodecs::IMREAD_COLOR
    )?;
    
    // Validate image loading
    if src.empty() {
        println!("Image load failed");
        std::process::exit(0);
    }
    
    // Set quality parameters for saving
    let mut params = core::Vector::default();
    params.push(imgcodecs::IMWRITE_JPEG_QUALITY);
    params.push(95);  // High quality (0-100)
    
    // Save image
    imgcodecs::imwrite(
        "./img/write_test.png", 
        &src, 
        &params
    )?;
    
    // Display image
    highgui::imshow("image", &src)?;
    
    // Wait for 10 seconds
    highgui::wait_key(10000)?;
    
    // Clean up
    highgui::destroy_all_windows()?;
    
    Ok(())
}

Common Issues and Solutions 🔧

  1. Image Loading Fails
    • Check file path
    • Verify file permissions
    • Ensure supported format
  2. Quality Settings
    • JPEG quality (0-100):
      • 95-100: Best quality
      • 80-90: Good quality
      • 60-70: Moderate quality
      • Below 60: Low quality
  3. Memory Management
    • Always call destroy_all_windows()
    • Use Rust’s ownership system
    • Handle errors properly with Result

Best Practices ✨

  1. Error Handling
    1
    2
    3
    
    if src.empty() {
        // Handle error appropriately
    }
    
  2. Resource Cleanup
    1
    
    highgui::destroy_all_windows()?;
    
  3. Quality Settings
    • Choose appropriate quality based on needs
    • Consider file size vs. quality trade-off
  4. Path Management
    • Use relative paths carefully
    • Consider cross-platform compatibility

🔍 Further Steps

Try experimenting with:

  1. Different image formats (PNG, JPEG, BMP)
  2. Various quality settings
  3. Error handling improvements
  4. Multiple image operations

💡 Tips

  • Always validate image loading
  • Use appropriate quality settings
  • Clean up resources properly
  • Handle errors gracefully
  • Test with different image formats

Remember that OpenCV in Rust combines the safety of Rust with the power of OpenCV, making it an excellent choice for image processing applications!