🌾

Rustで作物列画像を二値化処理をする

2024/06/18に公開

はじめに

Rust Ja Docs を一通りやったので、作物列画像から植物体を検出をするための二値化処理を Rust でやってみました。

参照

入出力画像

input.png
input.png

output.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)
}

おわりに

基本的に、大学農学部卒は農家にならない。

関連の読み物

GitHubで編集を提案

Discussion