GIS-LAB

Географические информационные системы и дистанционное зондирование

Выделение растровых контуров объектов в GRASS

В статье рассматривается теоретические основы и практическая реализация процедуры оконтуривания объектов, представленных на растровых изображениях.

Предположим, что имеется растровое изображение, например, космоснимок, содержащее некоторое число "пятен" - объектов разной природы, расположенных на относительно однородном фоне. Объект выделяется на фоне изображения благодаря его большей или меньшей яркости относительно яркости фона. Таким образом, контур (граница) объекта характеризуется скачкообразным изменением функции яркости изображения. Требуется построить автоматизированную процедуру выделения контуров объектов по изменениям функции яркости.

Обсудить в форуме Комментариев — 4

Необходимо подчеркнуть, что задача получения векторного представления контуров объектов не ставится, в данном случаем нам достаточно построения растрового изображения, на котором контуры объектов будут подчеркнуты.

Оглавление

  1. Основная идея
  2. Реализация в ГИС GRASS

1. Основная идея

Растровое изображение представляет собой модель некоторой 2.5-мерной поверхности, где каждый элемент помимо положения имеет координату Z, собственно значение, которое может быть представлено в виде высоты. Таким образом, участки относительно однородного фона на растре представляют собой более или менее плоские участки на моделирумой поверхности, а области, расположенные непосредственно на границах объектов, являются областями перепадов функции яркости растра. Следовательно, задача поиска контуров объектов на растровых изображениях - это задача поиска участков с относительно резкими перепадами высот (значений) моделируемой растром поверхности. Задача такого рода - хорошо изученная задача математического анализа, которая решается дифференциальными методами.

Прежде, чем приступать к описанию решения задачи, дадим необходимое определение:

Градиент - это вектор, ориентированный по направлению наиболее быстрого возрастания и имеющий длину, пропорциональную этой максимальной скорости.

Следовательно, на участках с большим перепадом высот модуль градиента должен быть также большим, а на относительно плоских участках - приблизительно равным нулю. Таким образом, для выделения контуров объектов необходимо построить поле модуля градиента для функции яркости исходного изображения. Эта функция является функцией, зависящей от двух переменных - координат x и y.

Как известно, градиент функции двух переменных вычисляется по формуле:

градиент

Поскольку нас не будет интересовать направление градиента, то ограничимся вычислением его модуля:

модуль градиента

Однако, в чистом виде данная формула неприменима, поскольку она работает с частными производными, которые не существуют в точках разрыва функции, т.е. имеют смысл для непрерывных функций, но не дискретных. А так как поле яркости изображения в общем случае представляет собой фунцию двух переменных со множеством разрывов, то частные производные необходимо получить в виде оценок:

оценки частных производных

здесь n1,n2 - координаты (измеренные в пикселах) на растровом изображении.

Из практических соображений, когда при вычислении частных производных используют метод скользящего окна, часто применяют оператор Собела. В этом случае s1 находят при помощи обработки маской 3x3:

-1 -2 -1
 0  0  0
 1  2  1

А s2 обработкой аналогичной маской:

-1  0  1
-2  0  2
-1  0  1

2. Реализация в ГИС GRASS

Предположим, что у нас уже создана область GRASS, в которую загружен растр под именем test. Этот файл показан на рисунке:

пример растра

Для реализации описанного выше способа нам понадобятся две команды GRASS: r.mfilter и r.mapcalc. Первая команда используется для создания фильтров и их последующего использования, вторая представляет собой мощный растровый калькулятор.

Для реализации фильтров, вычисляющих оператор Собеля, создадим два файла s1.f:

title s1
matrix 3
-1 -2 -1
0 0 0
1 2 1
divisor 1

и аналогичный файл s2.f:

title s2
matrix 3
-1 0 1
-2 0 2
-1 0 1

Для каждого из файла вызовем функцию r.mfilter следующими командами:

r.mfilter in=test out=s1 filter=s1.f
r.mfilter in=test out=s2 filter=s2.f

В результате будут построены два растра s1 и s2 - оценки частных производных по координатам x и y. Далее вычислим модуль градиента:

r.mapcalc grad="sqrt(pow(s1,2)+pow(s2,2))"

Таким образом будет создан новый растр под именем grad, представляющий собой поле модуля градиента функции яркости для изображения test.

фрагмент поля модуля градиента

Далее к этому растру можно применить пороговую обработку, когда все значения меньше определенного обращаются в NULL. При выборе порога нужно руководствоваться следующим соображением: чем меньше порог, тем меньше ячеек растра будут обращены в NULL и, соответственно, тем более жирными будут линии контуров. С другой стороны, излишне большой порог приведет к тому, что линии контуров станут слишком тонкими, а местами и вовсе пропадут. Таким образом, пороговое значение очень сильно зависит от исходного изображения и подбирается экспериментально, в нашем случае таким порогом был уровень 60:

r.mapcalc contur="if(grad-60, grad, grad, null())"

В результате был получен растр под названием contur, в котором все ячейки, которые соответствуют ячейкам растра grad со значениями меньше 60, были обращены в NULL, а ячейки, соответствующие ячейкам из grad с большими значениями, чем 60, получили значения из растра grad. Построенный таким образом растр представлен на рисунке ниже (с наложением на исходный растр):

поле модуля градиента

Вот фрагмент растра в более крупном масштабе:

фрагмент поля модуля градиента

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

Обсудить в форуме Комментариев — 4

Последнее обновление: August 26 2010

Дата создания: 09.09.2009
Автор(ы): Дмитрий Колесов


(Геокруг)

Если Вы обнаружили на сайте ошибку, выберите фрагмент текста и нажмите Ctrl+Enter