🌾
Rustで作物列画像を二値化処理をする
はじめに
Rust Docs を一通りやったので、作物列画像から植物体を検出をするための二値化処理を Rust でやってみた。
参照
- image - Rust crates
- GitHub Code search results for [path:*.rs "use image" open binary NOT is:fork NOT is:archived]
入出力画像
input.png
output.png (2G - R - B > 60 ? 255 : 1)
画像処理
二値化処理
入力画像中の植物体を検出するために簡易的な二値化判別式 2G-R-B
を用いました。入力画像の各ピクセルの RGB 値を与式に代入し、設定した閾値より大きければ1を返し、小さければ0を返すようにします。
入出力
image
crates での画像入力には image::open(path)
の他に image::io::Reader:open(path)
があります。今回は前者を使いました。
Try io::Reader for more advanced uses, including guessing the format based on the file’s content before its path.
プログラム
main.rs
use image::{DynamicImage, GenericImageView, ImageBuffer, Luma, Rgba};
fn main() {
let input_file = "input.png";
let output_file = "output.png";
let threshold = 60;
let img: DynamicImage = image::open(input_file).expect("Failed to open image");
let img_buffer = binarize_image(&img, threshold);
img_buffer
.save(output_file)
.expect("Failed to save binarize_image");
}
/// binarize image
fn binarize_image(img: &DynamicImage, threshold: u16) -> ImageBuffer<Luma<u8>, Vec<u8>> {
let (width, height) = img.dimensions();
let mut img_buffer = ImageBuffer::new(width, height);
for (x, y, pixel) in img.pixels() {
let Rgba([r, g, b, _a]) = pixel;
let value = calculate_value(r, g, b);
let binary_value = if value >= (threshold as i16) { 255 } else { 0 };
img_buffer.put_pixel(x, y, Luma([binary_value]));
}
img_buffer
}
/// calculate 2G - R - B
fn calculate_value(r: u8, g: u8, b: u8) -> i16 {
2 * (g as i16) - (r as i16) - (b as i16)
}
Discussion