Контурное наслоение OpenCV-Python |25

глубокое обучение

Цель

На этот раз мы изучаем иерархию контуров, то есть отношения родитель-потомок в контурах.

теория

В предыдущих статьях о контурах мы обсуждали несколько функций, связанных с контурами, предоставляемыми OpenCV. но когда мы используемcv.findcontourКогда функция () находит контуры на изображении, мы передали параметр,Режим поиска по контуру. мы обычно проходимcv.RETR_LISTилиcv.RETR_TREE,хорошие результаты. Но что конкретно это означает?

Так же на выходе получаем три массива, первый это изображение, второй контур и еще один мы назвалиhierarchyвывод (проверьте код в предыдущем посте). Но мы никогда и нигде не использовали эту иерархию. Так что же это за иерархия, для чего она используется и как она связана с вышеупомянутыми параметрами функции?

Это то, что мы собираемся обсудить в этой статье.

Что такое иерархия?

Обычно мы используемcv.findcontour() для обнаружения объектов на изображении, верно? Иногда объекты находятся в разных местах. Но в некоторых случаях одни фигуры находятся внутри других фигур. Так же, как вложенные графы. В этом случае мы называем внешнийотец, вызовите внутреннийПодкласс. Таким образом, контуры на изображении находятся в определенной взаимосвязи друг с другом. Мы можем указать, как контур связан друг с другом, например, является ли он дочерним контуром другого контура или родительским контуром и т. д. Представление этого отношения называетсяИерархия.

Ниже приведен пример:

На этом изображении есть несколько фигур, которые я взял из0-5Начать нумерацию.2и2aПредставляет внешний и внутренний контуры самой внешней коробки.

Здесь контуры 0,1,2 находятся навнешний или крайний. Мы можем сказать, что ониУровень-0, или проще говоря, они находятся втот же уровеньсередина.

С последующимcontour-2a. это можно рассматривать какДети контура-2(или наоборот, контур-2 является родителем контура-2а). предположим, что это в1-го уровнясередина. Точно так же контур-3 является потомком контура-2, который находится в следующей иерархии. Наконец, контуры 4,5 являются потомками контура-3а, они находятся на последнем уровне. Судя по нумерации коробок, я думаю, что контур-4 является первым потомком контура-3а (он также может быть контуром-5).

Я упоминаю их, чтобы понять некоторые термины, такие кактот же уровень,Внешний профиль,подконтур,родительский профиль,первый подконтури Т. Д. Теперь давайте перейдем к OpenCV.

Иерархическое представление в OpenCV

Таким образом, каждый профиль имеет свою собственную информацию о том, какой он уровень, кто его дочерний элемент, кто его родитель и т. д. OpenCV представляет его как массив с четырьмя значениями:[Next, Previous, First_Child, Parent]

«Следующий представляет собой следующий контур на том же уровне».

Например, возьмем контур-0 на нашем изображении. Кто следующий контур на том же уровне?Это контур-1. просто сделатьNext = 1. Точно так же Контур-1 также является Контуром-2. такNext = 2. А как насчет контура-2?Нет следующей линии контура на той же горизонтальной линии. просто, пустьNext = -1. А контур-4 находится на том же уровне, что и контур-5. Следующим его контуром является контур-5, поэтомуnext = 5.

«Предыдущий представляет предыдущие контуры на том же уровне».

то же, что и выше. Контур перед контуром-1 является контуром-0 на том же уровне. Точно так же контур-2 также является контуром-1. Для контура-0 предшествующего элемента нет, поэтому он равен -1.

«First_Child представляет его первый дочерний контур».

Никаких объяснений не требуется. Для контура-2 дочерним элементом является контур-2а. Таким образом, получается значение индекса, соответствующее контуру-2а. А контур-3а у него двое детей. Но мы ориентируемся только на первого ребенка. Это контур-4. ТакFirst_Child = 4Для контура-3а.

«Родитель представляет индекс своего родительского контура».

это сFirst_ChildНапротив. Для контура-4 и контура-5 родительским контуром является контур-3а. Для контура 3а это контур-3 и так далее.

Уведомление
Если дочерних или родительских элементов нет, поле обрабатывается как -1.

Теперь, когда мы понимаем иерархические стили, используемые в OpenCV, мы можем проверить режим поиска контуров в OpenCV с помощью того же изображения, что и выше. некоторые признаки, какcv.RETR_LIST, cv.RETR_TREE,cv.RETR_CCOMP, cv.RETR_EXTERNALСмысл ожидания.

Режим поиска по контуру

1. RETR_LIST

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

Здесь 3-й и 4-й элементы всегда равны -1. Но очевидно, что следующий элемент и предыдущий элемент имеют соответствующие значения. Просто проверьте это сами.

Ниже представлен результат, который у меня получился, каждая строка — это уровень детализации соответствующего контура. Например, первая строка соответствует контуру 0. Следующий контур - контур 1. такNext = 1. Предыдущего контура нет, поэтомуPrevious=-1. Остальные два, как уже упоминалось,-1.

>>> hierarchy
array([[[ 1, -1, -1, -1],
        [ 2,  0, -1, -1],
        [ 3,  1, -1, -1],
        [ 4,  2, -1, -1],
        [ 5,  3, -1, -1],
        [ 6,  4, -1, -1],
        [ 7,  5, -1, -1],
        [-1,  6, -1, -1]]])

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

2. RETR_EXTERNAL

Если этот флаг используется, он возвращает только крайний внешний флаг. Все детские силуэты остались позади.Можно сказать, что по этому правилу внимание получает только старший сын в каждой семье. На остальных членов семьи плевать :).

Итак, на нашем изображении сколько крайних внешних контуров?На уровне 0?Их 3,т.е. контур 0 1 2, верно?Теперь попробуем найти контур с этим флажком. Здесь присвойте каждому элементу то же значение, что и выше. и сравнить с приведенными выше результатами. Вот что я получаю:

>>> hierarchy
array([[[ 1, -1, -1, -1],
        [ 2,  0, -1, -1],
        [-1,  1, -1, -1]]])

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

3. RETR_CCOMP

Этот флаг извлекает все контуры и упорядочивает их в двухуровневую иерархию. Внешний контур объекта (т.е. граница объекта) помещается в иерархию-1. Контур отверстия внутри объекта (если есть) помещается в иерархию-2. Если в нем есть какой-либо объект, его контур перемещается только в иерархии 1. и его уязвимости на уровне 2 и так далее.

Просто рассмотрите изображение «белого нуля» на черном фоне. Внешний круг нуля принадлежит первому уровню, а внутренний круг нуля принадлежит второму уровню.

Мы можем объяснить это с помощью простого изображения. Здесь я отметил порядок контуров и слоев, которым они принадлежат, красным и зеленым (1 или 2) в том же порядке, в котором OpenCV определяет контуры.

Рассмотрим первый контур, который является контуром-0. Это иерархия-1. Он имеет два отверстия, Контуры 1 и 2, которые относятся ко второму уровню. Таким образом, для контура-0 следующим контуром на том же уровне будет контур-3. Как и предыдущие. В иерархии-2 его первым дочерним элементом является контур-1. У него нет родительского класса, потому что он находится в иерархии-1. Таким образом, его иерархический массив[3,-1,1,-1]

Теперь контур-1. Он находится на уровне 2. Следующим в той же иерархии (под родителем контура-1) является контур-2. Предыдущего нет. нетchild,ноparentконтур-0. Итак, массив[2,-1,-1,0]

Аналогичный контур-2: находится в иерархии-2. При контуре-0 в той же иерархии нет следующего контура. тогда нетNext.previousконтур-1. нетchild,parentконтур0. Итак, массив[-1,1,-1,0]

контур-3: рядом с уровнем-1 находится контур-5. Раньше это был контур-0.childконтур4, нетparent. Итак, массив[5,0,4,-1]

контур-4: он находится в иерархии 2 под контуром-3, у него нет братьев и сестер. нетnext,нетprevious,нетchild,parentконтур-3. Итак, массив[-1,-1,-1,3]

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

>>> hierarchy
array([[[ 3, -1,  1, -1],
        [ 2, -1, -1,  0],
        [-1,  1, -1,  0],
        [ 5,  0,  4, -1],
        [-1, -1, -1,  3],
        [ 7,  3,  6, -1],
        [-1, -1, -1,  5],
        [ 8,  5, -1, -1],
        [-1,  7, -1, -1]]])

4. RETR_TREE

Это последний парень, мистер Перфект. Он извлекает все контуры и создает полный список семейной иерархии.Он даже рассказывает, кто дедушка, отец, сын, внук и многое другое... :).

Например, я взял картинку выше и переписал код для cv. RETR_TREE, переупорядочить контуры и проанализировать их в соответствии с результатами, предоставленными OpenCV. Опять же, красные буквы обозначают количество контуров, а зеленые — порядок иерархии.

Выбиратьcontour-0: это вhierarchy-0середина. той же иерархииnextКонтур - контур-7. нетpreviousКонтур.childконтур-1, нетparent. Итак, массив[7,-1,1,-1]

отcontour-2Например: это вhierarchy-1середина. Ни один из контуров не находится на одном уровне. нетprevious.childдаcontour-3. родителиcontour-1. Итак, массив[-1,-1,3,1]

В остальном попробуйте сами. Вот полный ответ:

>>> hierarchy
array([[[ 7, -1,  1, -1],
        [-1, -1,  2,  0],
        [-1, -1,  3,  1],
        [-1, -1,  4,  2],
        [-1, -1,  5,  3],
        [ 6, -1, -1,  4],
        [-1,  5, -1,  4],
        [ 8,  0, -1, -1],
        [-1,  7, -1, -1]]])

Сводная станция блога о технологиях искусственного интеллекта Panchuang: http://docs.panchuang.net/PyTorch, официальная учебная станция на китайском языке: http://pytorch.panchuang.net/OpenCV, официальный китайский документ: http://woshicver.com/