Converting an image into a 2D matrix

Hi, so I wanted to convert an image to a 2D matrix, like more specifically 128 x 128 matrix in grayscale. Is there a functionality in rust I can use for it, I am sort of unaware of it. Could anyone give me some reference, it would be great.

Thanks.

I would use the image crate. You can open the image with image::open, which returns a DynamicImage. Then call to_luma8 or to_luma16 to convert it to grayscale. See the ImageBuffer type for more details on what you can do with the resulting image.

4 Likes

Oh thanks, I will give it a go

Hi, so I was testing with the piece of code that is given in documentation to convert image to grayscale "image::ImageBuffer - Rust".

use image::{open, DynamicImage};

fn main(){
let rgba = open("path/to/some.png").unwrap().into_rgba();
let gray = DynamicImage::ImageRgba8(rgba).into_luma();
}

But this shows me warning signs. Also I would wanna convert into a fixed size matrix, 128 x 128, any suggestions?

Thanks.

Please read

The warning is because it is deprecated. Use into_luma8 or into_luma16 instead.

As for resizing, you can call resize_exact. Here you will need to pick a filter type — I just chose one of them randomly in the example below.

Your call to into_rgba also doesn't make sense. The open call already gives you a DynamicImage. No need to convert into rgba and then back to DynamicImage.

use image::{open, DynamicImage};

fn main(){
    let gray = open("path/to/some.png").unwrap()
        .resize_exact(128, 128, FilterType::Nearest)
        .into_luma8();
}

Hey, I tried your piece, but it gives error in filter type,

error[E0433]: failed to resolve: use of undeclared type `FilterType`
 --> src/main.rs:5:33
  |
5 |         .resize_exact(128, 128, FilterType::Nearest)
  |                                 ^^^^^^^^^^ use of undeclared type `FilterType`

warning: unused import: `DynamicImage`
 --> src/main.rs:1:19
  |
1 | use image::{open, DynamicImage};
  |                   ^^^^^^^^^^^^
  |
  = note: `#[warn(unused_imports)]` on by default

error: aborting due to previous error; 1 warning emitted

For more information about this error, try `rustc --explain E0433`.

I did try the error command to see more and I get,

An undeclared crate, module, or type was used.

Erroneous code example:

let map = HashMap::new();
// error: failed to resolve: use of undeclared type HashMap


Please verify you didn't misspell the type/module's name or that you didn't
forget to import it:

use std::collections::HashMap; // HashMap has been imported.
let map: HashMap<u32, u32> = HashMap::new(); // So it can be used!

If you've expected to use a crate name:

use ferris_wheel::BigO;
// error: failed to resolve: use of undeclared crate or module `ferris_wheel`

I really don't understand what is going wrong

Hey, So I actually made some changes,

use image::{open, imageops};

fn main(){
	let img =  open("sample.png").unwrap();
	let _gray = img.resize_exact(128, 128, imageops::FilterType::Nearest).into_luma8();
}

My warnings and error are not there while I compile now but I get error when I run the code.

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: IoError(Os { code: 2, kind: NotFound, message: "No such file or directory" })', src/main.rs:4:35
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Can you please help me understand this. Thanks.

The program is looking for a file named sample.png in the current working directory, and failing with "No such file or directory".

Is there a file named sample.png in the directory where you are running the program? (Usually this is the top-level directory of your Cargo project, where Cargo.toml lives.)

Oh okay, I had it placed in src. I thought since my main function is in src, the image should be in src too. Thanks a lot. Yes so I get the image. So, does it mean that assuming I used the variable gray, gray is also a matrix of 128x128 and I can use gray directly for further calculations?? Also, if I want to see the matrix is there some specific function for it too ??
Thanks !

I think by far the easiest way to view the image is to write it to a file.

So I did gray.save("grayscale.png");. This has saved the image in a file but like after running the code I want to see the matrix as well. It is because once I have the matrix I want to add a column of length 128. to it, so I kind of want to see the matrix too or like be able to access it, so I am asking.

Thanks!

To read the value at a pixel, you can call get_pixel. In general, I recommend checking out the documentation for ImageBuffer, since it has many useful methods.

Also another thing, can we not have a matrix in rust and print entire matrix at once ?

I mean, the ImageBuffer type is not really created for the purpose of being a matrix of numbers. Its purpose is to be an image. If you want the numbers out, you'll likely have to copy them to an actual matrix type such as Vec<Vec<...>> or one of the types from the ndarray crate.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.