Rust OpenCVを使ってエッジ検出をしたいとき、ありますよね。
そんなときはopencv::imgproc::canny
を使います。
発生した問題
しかし、何やらパラメータの中に閾値
とやらを設定しなければいけないようです。
とりあえずベタ書きでいい感じの数値を入れちゃいましょう。
fn main() {
let src_img = imread("path/to/image.png", IMREAD_GRAYSCALE).unwrap();
let mut edge_img = src_img.clone();
let result_find_edge = canny(&src_img, &mut edge_img, 100.0, 100.0, 3, false);
match result_find_edge {
Ok(_) => imwrite("path/to/result.png", &edge_img, &Vector::new()).ok(),
Err(code) => {
panic!("code: {:?}", code);
}
};
}
元画像
エッジ検出後の画像
しかしこれだと画像ごとにいちいち閾値を設定しなくてはいけないですね。このままでは使い物にならないですね。
実現したいこと
入力画像からいい感じの閾値を算出して、その値をもとにエッジ検出を行う
結論
大津の2値化を使っていい感じの閾値を取得する
fn main() {
let max_thresh_val = threshold(&src_img, &mut Mat::default(), 0.0, 255.0, THRESH_OTSU).unwrap();
let min_thresh_val = max_thresh_val * 0.5;
let mut edge_img = src_img.clone();
let result_find_edge = canny(&src_img, &mut edge_img, min_thresh_val, max_thresh_val, 3, false);
match result_find_edge {
Ok(_) => imwrite("path/to/result.png", &edge_img, &Vector::new()).ok(),
Err(code) => {
panic!("code: {:?}", code);
}
};
}
これで画像入力画像からいい感じの閾値を算出してくれるようになりました。
バージョン情報
# Cargo.toml
[dependencies]
opencv = "0.53.1"
$ cargo --version
cargo 1.54.0 (5ae8d74b3 2021-06-22)
$ rustc -V
rustc 1.54.0 (a178d0322 2021-07-26)
$ rustup -V
rustup 1.24.3 (ce5817a94 2021-05-31)
参考記事
ソースコード
ここに載せてあります。