問題
日本の山のデジタル写真のコレクションを持っています。しかし、山はしばしば雲や霧に覆われています。
山が画像に表示されていることを検出するには、どのような手法を使用できますか?私は現在、ImagerモジュールでPerlを使用していますが、別の方法を利用できます。
すべての画像はまったく同じ位置から取得されています-これらはいくつかのサンプルです。
サンプル画像http://www.freeimagehosting.net/uploads/7304a6e191.jpg
私のナイーブな解決策
山の円錐のいくつかの水平ピクセルサンプルを取得し、明るさの値を空の他のサンプルと比較することから始めました。これは、良い画像1と悪い画像2を区別するためにうまく機能しました。
しかし、秋になると雪が降り、画像3のように山が空よりも明るくなり、簡単な明るさテストが失敗し始めました。
画像4はエッジケースの例です。山の一部がはっきりと見えるので、これを良い画像として分類します。
更新1
提案をありがとう-あなたが私の能力を非常に過大評価してくれてうれしいです。
答えに基づいて、私はImageMagickエッジ検出変換を試し始めました。これにより、分析する画像がはるかに簡単になります。
convert sample.jpg -edge 1 edge.jpg
エッジで検出されたサンプルhttp://www.freeimagehosting.net/uploads/caa9018d84.jpg
木やほとんどの雲を取り除くために、ある種のマスキングを使用する必要があると思います。
マスクされた画像を取得したら、類似性を「良好な」画像と比較するための最良の方法は何ですか?この仕事に適した「比較」コマンドだと思いますか?これから数値の「類似性」値を取得するにはどうすればよいですか?
更新2
たたみ込みでどこかに到達しているのではないかと思います。
良好な画像に対してエッジ検出を実行して、「カーネル」画像(下の画像の上部)を作成しました。次に、山の輪郭の周りのすべての「ノイズ」を黒く塗りつぶしてからトリミングしました。
次に、次のコードを使用しました。
use Image::Magick;
# Edge detect the test image
my $test_image = Image::Magick->new;
$test_image->Read($ARGV[0]);
$test_image->Quantize(colorspace=>'gray');
$test_image->Edge(radius => 1);
# Load the kernel
my $kernel_image = Image::Magick->new;
$kernel_image->Read('kernel-crop.jpg');
# Convolve and show the result
$kernel_image->Convolve(coefficients => [$test_image->GetPixels()]);
$kernel_image->Display();
これをさまざまなサンプル画像に対して実行したところ、次のような結果が得られました(畳み込み画像は各サンプルの下に表示されています)。
(申し訳ありませんが、前回とは異なるサンプル画像です!)
代替テキストhttp://www.freeimagehosting.net/uploads/f9a5a34980.jpg
今、私は画像がどれほど「ぎこちない」かを定量化しようとしています。画像の平均輝度を試してみました:
$kernel_image->Scale('1x1');
die $kernel_image->GetPixel(x=>1,y=>1)[0];
ただし、これでは意味のある値(0.0165、0.0175、0.0174)は得られません。より良い方法はありますか?