Calculate average color of an image in Rust

The easiest thing to do with images is to calculate their average color.
Every color can be created by combining together so called primary colors – red, green and blue (RGB).
RGB is a mathematical model for representing colors as a tuple of numbers. Many computer vision tasks use greyscale (a one dimensional representation of an image in black and white) due to the fact, that using RGB for object detection requires alot of computing power.

Representation of an image in the RGB model is nothing else than just a two dimensional array in which each cell holds 3 values between 0 and 255.

With this knowledge it is very easy to calculate average color of an image.

We will begin by importing the Image crate

extern crate image;

Now we have to create a function, that takes a string as argument and imports the image

fn averageColor(i: &str){
    let img = image::open(i).expect("Opening image failed");
}

Now let’s hack our way throught the calculation. Let’s create local variables for storing the current average of all colors.

    let mut r: u32 = 0;
    let mut g: u32 = 0;
    let mut b: u32 = 0;

And get the width and height of the image.

    let (width,height) = img.dimensions();

Now we have everything we need to do the calculations, so let’s iterate over the width and height.

for x in 0..(width){
        for y in 0..(height){

        }
    }

Great! now we can access every pixel of our image. Let’s now add the calculation. Remember when I said that we are going to store the current value for each channel in our local variables?

    for x in 0..(width){
        for y in 0..(height){
            let px = img.get_pixel(x,y);
            let rgb = px.to_rgb();
            r = (r as u32 + rgb.data[0] as u32)/2;
            g = (g as u32 + rgb.data[1] as u32)/2;
            b = (b as u32 + rgb.data[2] as u32)/2;
            println!("R G B {} {} {}", r,g,b);
        }
    }

That’s it!
This is how our function looks like at the end:

fn averageColor(i: &str){
    let img = image::open(i).expect("Opening image failed");
    let mut r: u32 = 0;
    let mut g: u32 = 0;
    let mut b: u32 = 0;
    let (width,height) = img.dimensions();
    for x in 0..(width){
        for y in 0..(height){
            let px = img.get_pixel(x,y);
            let rgb = px.to_rgb();
            r = (r as u32 + rgb.data[0] as u32)/2;
            g = (g as u32 + rgb.data[1] as u32)/2;
            b = (b as u32 + rgb.data[2] as u32)/2;
            println!("R G B {} {} {}", r,g,b);
        }
    }
    println!("Average color is: RGB {} {} {}",r,g,b);
}

I hope that I helped and I’d really appreciate your feedback, especially if you’ve found a better, more efficient solution for this task.

8 Comments

Comments are closed, but trackbacks and pingbacks are open.