2016-05-24 7 views
4

Это должно быть просто для разработчиков C++, использующих OpenCV напрямую. Однако то, что я использую, является Emgu (оболочка OpenCV для .NET), и в последней версии мы имеем метод CvInvoke.FindContours, возвращающий void, выходной результат передается параметром и имеет тип VectorOfVectorOfPoint.Перейдите по иерархии контуров, найденных методом FindContours?

Вот простой вызов:

//outputResult is a VectorOfVectorOfPoint 
CvInvoke.FindContours(inputImage, outputResult, null, RetrType.Tree, 
         ChainApproxMethod.ChainApproxSimple); 

Для RetrType.List режима, мы можем просто преобразовать результат в какой-то массив массивов и перебора всех контуров легко. Однако здесь я хотел бы перемещаться по всем контурам в дереве. Я предполагаю, что мы должны что-то сделать с собственным (небезопасным) кодом C++ здесь с указателем (доступ через свойство Ptr результата вывода). Но мне интересно, есть ли для этого более удобное для .NET решение. И если даже использование указателя - единственное решение, я до сих пор не знаю, как вникать в этот Ptr для навигации по дереву контуров.

В примерах кодов, сопровождаемых установкой Emgu, есть фрагмент с использованием CvInvoke.FindContourTree (и который возвращает int[,]).

+1

Разве иерархия не выводится в третьем параметре, который вы задали равным нулю? Вы можете перечислить счетчики точно так же, используете ли вы RetrType.List или Tree, чтобы получить информацию о иерархии, создать новую переменную типа Mat и передать ее в качестве третьего параметра (который теперь является нулевым). – Evk

+0

@ Evk Да, я не понимал, что то, что я должен пройти, находится на третьей позиции, и даже если бы я знал об этом, я бы не знал, что это за тип. Теперь вы дайте мне знать, что я должен пройти в «Мат». Но я просто пытаюсь найти больше об этом типе, и у него нет никаких простых для распознавания членов, чтобы помочь перемещаться по дереву. Если возможно, пожалуйста, дайте мне пример кода в вашем ответе. Это было бы очень признательно. Спасибо! – Hopeless

ответ

6

Чтобы получить иерархию контуров, вы должны сначала пройти Mat объект функции:

Mat hierarchy = new Mat() ; 
CvInvoke.FindContours(inputImage, outputResult, hierarchy, RetrType.Tree, 
        ChainApproxMethod.ChainApproxSimple); 

Затем вы можете использовать hierarchy объект следующим образом (см here для более подробной информации в Python OpenCV):

hierarchy будет Mat объект размером 1 х размер outputResult х 4. Таким образом, для контура с индексом i:

  • hierachy[0,i,0] является индексом следующего контура на том же уровне иерархии (с тем же родителем) или - 1, если он не существует
  • hierachy[0,i,1] является индексом предыдущего контура на том же уровне иерархии или - 1, если он не существует
  • hierachy[0,i,2] является индекс ребенка контура i или - 1, если он не существует
  • hierachy[0,i,3] является индекс родительского контура i или - 1, если оно не есть

Так вы используете объект иерархии.

Доступ к контурам осуществляется через объект outputResult с использованием их индексов.

+0

Вы уверены, что 'Mat' имеет любого индексатора, принимающего 3 аргумента?Я попытался объявить простую переменную 'Mat' и написать что-то вроде этого' m [0,0,0] 'вызывает некоторую ошибку времени разработки, и, конечно же, ее невозможно даже скомпилировать. То, что вы предложили, может быть действительным и работать на Python, но здесь я спрашиваю на C#. Благодаря! – Hopeless

+0

Вы пробовали 'm.Data [0,0,0]'? Я не могу проверить его с помощью C#, но некоторые ответы онлайн, похоже, говорят, что это возможно. – Sunreef

+0

'm.Data'' 'Array', который может иметь различный размер (ранг), поэтому он, вероятно, имеет ранг' 3', но тогда нам нужно использовать метод 'GetValue' вместо этого (' Array' также не имеет любой индексир принимает 3 аргумента). Однако я пробовал свой код и 'm.Data' на самом деле« null », что невозможно, если древовидная структура должна быть достигнута, это означает, что« m.Data' не является местом, где можно вытащить данные дерева. Эта «Карта» сама по себе довольно сложна для меня, это своего рода класс общего назначения, поэтому трудно понять, как использовать его в этом конкретном сценарии. – Hopeless