Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
лекцииИИ.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
6.48 Mб
Скачать

Код Фримена

Прежде чем познакомиться с прототипом функции, необходимо точно понять что такое контур. По пути мы столкнёмся с понятием дерева контуров, что важно для понимания того как функция cvFindContours()(метод [Suzuki85]) будет возвращать нам результат.

Найдите минутку чтобы посмотреть на изображение 8-2, на котором изображена функциональность cvFindContours(). В верхней части рисунка показано тестовое изображение, содержащее несколько белых регионов (обозначены от A до E) на тёмном фоне2. В нижней части рисунка находится тоже изображение вместе с контурами, которя обозначены cX либо hX, где c расшифровывается как контур, а h как "дыра" и X некоторое число. Некоторые из этих контуров нарисованы пунктирными линиями; они представляют внешние границы белых регионов (т.е. ненулевых регионов). OpenCV и cvFindContours()различают эти внешние границы и пунктирные линии, которые вы можете себе представлять либо как внутренние границы либо как внешние границы дыр (т.е. нулевых регионов).

Концепция "вложенности" здесь играет важную роль во многих приложениях. По этой причине OpenCV может собрать найденные контуры в дерево контуров 3, которое отражает отношение вложенности контуров в своей структуре. Дерево контуров для этого тестового изображения будет иметь контур c0 как корневой узел, с "дырками" h00 и h01, как своих потомков. Они в свою очередь будут иметь потомков - контуров, и т.д.

Переменная mode может быть установлена в одно из следующих значений: CV_RETR_EXTERNAL, CV_RETR_LIST, CV_RETR_CCOMP, или CV_RETR_TREE. Значение режима указывает cvFindContours() в точности какие контуры мы хотим найти и в каком виде мы хотели бы получить результат. В частности каким образом переменные вершин дерева (?) (h_prev, h_next, v_prev, и v_next) используются для "соединения" найденных контуров определяется значением режима. На рисунке 8-3 приведены результирующие топологии для всех четырёх возможных значений mode. В любом случае структуры могут рассматриваться как "уровни" которые связаны "горизонтальными" связями (h_next и h_prev) и отделены друг от друга "вертикальными" ссылками (v_next и v_prev).

Как правило, контуры созданные с помощью cvFindContours() являются последовательностями вершин (т.е. точек). Альтернативное представление может быть получено путём установки method вCV_CHAIN_CODE, в результате контуры будут храниться в виде кода Фримена [Freeman67] (рис. 8-4). В коде Фримена полигон представляется как последовательность шагов в одном из 8-ми направлений, каждый шаг обозначается числом от 0 до 7.

Если мы рисуем контур или анализируем форму, то он является общим для аппроксимации (приближения) контура представляющего собой многоугольник с другим контуром содержащим меньшее число вершин. Существует много способов сделать это, OpenCV предлагает реализацию одного из них.1 Функция cvApproxPoly() является реализацией этого алгоритма, который работает с последовательностью контуров.

CvSeq* cvApproxPoly(

const void* src_seq,

int header_size,

CvMemStorage* storage,

int method,

double parameter,

int recursive = 0

);

Мы можем передать cvApproxPoly() последовательность в виде списка или дерева содержащую контуры; функция воздействует на все содержащиеся в последовательности контуры. Возвращаемое значение на самом деле является только первым контуром, но вы можете перейти к другим элементам возвращаемой последовательности с помощью h_next (и v_next, если это необходимо).

Т.к. cvApproxPoly() необходимо создать возвращаемые ей объекты, то функции необходимо передать указатель на CvMemStorage и размер заголовка (который обычно равен sizeof(CvContour)).

Аргумент method всегда устанавливается в CV_POLY_APPROX_DP (хотя другие алгоритмы могут быть выбраны если они станут доступны). Следующие два аргумента специфичны для метода (из которых на данный момент существует только один). Аргумент parameter это параметр точности для алгоритма. Чтобы понять как работает этот параметр, мы должны рассмотреть фактический алгоритм.2 Последний аргумент указывает, должен ли алгоритм применяться к каждому контуру, который может быть достигнут с помощью h_next и v_next указателей. Если этот аргумент равен 0, то только контур на который указывает src_seq будет приближенным.

Вот обещанное объяснение того как работает алгоритм. На изображении 8-5, начиная с контура a (рисунок b), алгоритм выбирает 2 экстремальные точки и связывает их линией (c), затем в исходном многоугольнике ищеться наиболее удалённая точка от только что нарисованной линии и эта точка добавляется к приближению. Процесс повторяется (d), добавляя следующую наиболее удалённую точку к накопленному приближению, пока все точки меньше чем расстояние указанное параметром точности. Это означает что хорошими кандидатами для параметра будут некоторая часть длины контура или длины его ограничительной рамки, или аналогичной меры полной длины контура.

С только что описанным приближением тесно связан процесс нахождения доминирующих точек. Доминирующая точка определяется как точка которая имеет больше информации о кривой чем другие точки. Доминирующие точки используются во многих ситуациях похожих на полигон приближений. Функция cvFindDominantPoints() реализует так называемый IPAN2 [Chetverikov99] алгоритм.

CvSeq* cvFindDominantPoints(

CvSeq* contour,

CvMemStorage* storage,

int method = CV_DOMINANT_IPAN,

double parameter1 = 0,

double parameter2 = 0,

double parameter3 = 0,

double parameter4 = 0

);

По сути, алгоритм IPAN пытается построить треугольники на внутренней кривой с использованием доступных вершин, путём сканирования контура. Этот треугольник характеризуется размером и углом открытия (см. рис. 8-6). Точки с большими углами открытия сохраняются при условии что их углы меньше чем указанный глобальный порог и меньше чем их соседи.

cvFindDominantPoints() принимает обычные CvSeq* и CvMemStorage* аргументы. Она также требует method (как и cvApproxPoly()) который на данный момент может принимать только одно значение CV_DOMINANT_IPAN.

Следующие 4 аргумента: минимальное расстояние dmin, максимальное расстояние dmax, расстояние до соседей dn и максимальный угол θmax. Как показано на изображении 8-6, сначала алгоритм строит все треугольники для которых rpa и rpbнаходятся между dmin и dmax и для которых θab < θmax. Далее следует второй проход, в которым сохраняются только точки p с наименьшим значением связывания θab в окрестности dn (значение dn никогда не должно превышать dmax). Типичные значения для dmin, dmax, dn и θmax: 7, 9, 9, 150(измеряется в градусах).

Матрицы и типы изображений

 При использовании OpenCV Вы неоднократно сталкивались с типом данных IplImage. IplImage это базовая структура используемая для кодирования того что мы называем “изображения”. Эти изображения могут быть чёрно-белыми, цветными, 4-х канальными(RGB+Alpha), и каждый канал может содержать либо целые либо вещественные значения