На цифровой фотографии, как я могу определить, скрыта ли гора облаками? - PullRequest
27 голосов
/ 27 марта 2010

Проблема

У меня есть коллекция цифровых фотографий горы в Японии. Однако гора часто скрыта облаками или туманом.

Какие методы я могу использовать, чтобы обнаружить, что гора видна на изображении? В настоящее время я использую Perl с модулем Imager , но открыта для альтернатив.

Все изображения взяты из одной и той же позиции - вот некоторые образцы.

Образцы изображений http://www.freeimagehosting.net/uploads/7304a6e191.jpg

Мое наивное решение

Я начал с того, что взял несколько горизонтальных образцов пикселей горного конуса и сравнил значения яркости с другими образцами с неба. Это хорошо работало для различения хорошего изображения 1 и плохого изображения 2.

Однако осенью пошел снег, и гора стала ярче неба, как на изображении 3, и мой простой тест яркости начал проваливаться.

Изображение 4 является примером краевого случая. Я бы классифицировал это как хорошее изображение, так как часть горы хорошо видна.

ОБНОВЛЕНИЕ 1

Спасибо за предложения - я рад, что вы все сильно переоценили мою компетентность.

Основываясь на ответах, я начал пробовать преобразование ImageMagick Edge-Detection , которое дает мне намного более простое изображение для анализа.

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). Есть ли лучшие способы?

Ответы [ 3 ]

9 голосов
/ 27 марта 2010

Я думаю, вы работаете на слишком низком уровне. Быстрый проход через фильтр обнаружения краев очень четко разделяет набор изображений на (1, 3) и (2, 4). Особенно, если эти изображения поступают с фиксированной точки обзора камеры, найти совпадение с прототипом в (1) было бы относительно легко алгоритмически. Даже ваш случай (4) может дать вам область частичного соответствия, которую вы могли бы эвристически определить, достаточно ли там гор для рассмотрения.

5 голосов
/ 28 марта 2010

Несколько конкретных рекомендаций, основанных на том, что вы уже получили:

  1. Возьмите свое лучшее изображение (что-то вроде изображения 1), запустите его через обнаружение краев, откройте результат в любом графическом редакторе (подойдет MS Paint) и очистите все, кроме верхней границы горы (линия «Китайская шляпа»). Это твое ядро ​​свертки. Вы можете обрезать его (не изменять размер!) Сверху и снизу, чтобы сэкономить время на следующем шаге.
  2. Используйте функцию Convolve от PerlMagick (вы, кажется, уже знакомы с Perl и ImageMagick), чтобы свести ядро ​​с несколькими изображениями. На полученном изображении вы должны увидеть острый шип, соответствующий «правильному» положению ядра (совпадающему с горой на изображении).
  3. Относительная (к уровню окружающего шума) высота этого шипа будет больше, когда гора будет лучше видна. Взяв несколько репрезентативных изображений, вы сможете определить порог, который будет отличать хорошие изображения от плохих.
  4. Что бы вы ни делали, будут ложные срабатывания и ложные отрицания. Будьте готовы.
4 голосов
/ 27 марта 2010

Ответ зависит от того, насколько конкретно проблема. Если это та же самая гора из того же POV, запустите обнаружение и обнаружение краев на известном хорошем изображении и используйте его в качестве базовой линии для свертки против обнаруженных краями изображений из корпуса. Если вас интересует только край горы, вручную удалите другие объекты из базовой линии.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...