2017-01-10 5 views
0

Я работаю над поиском контуров в проекте C# EmguCV. Для этого проекта важно получить данные иерархии контуров. Я использовал этот метод раньше в проекте C++ OpenCV, поэтому я понимаю работу метода FindContours и информацию Hierarchy. Пожалуйста, найдите соответствующий код:C# - Emgu CV - данные иерархии FindContours всегда равны нулю

Mat grayImage = new Mat(originalImage.Size, originalImage.Depth, 1); 
Mat edges = new Mat(originalImage.Size, originalImage.Depth, 1); 

CvInvoke.CvtColor(originalImage, grayImage, ColorConversion.Bgr2Gray);    
CvInvoke.Canny(grayImage, edges, 100, 200, 3); 

var contours = new VectorOfVectorOfPoint(); 

Mat hierarchy = new Mat(); 
CvInvoke.FindContours(edges, contours, hierarchy, RetrType.Tree, ChainApproxMethod.ChainApproxSimple); 

Когда я запустил этот код, контуры найдены, как ожидалось. Также Hierarchy Mat объект кажется, чтобы получить заселена, как ожидалось, а именно 1 x size of outputResult x 4 (см картинку ниже), но данные в этом объекте остается null:

Screenshot of hierarchy mat object

Я не смог найти ответ о том, как извлечь данные контура иерархии (дерева) этого объекта. Я видел в other StackOverflow posts (see also the comments), что другие борется и/или что могут быть ошибки в библиотеке EmguCV 3.x, но я не смог найти ответ.

Мой вопрос: таким образом, нормально, что поле данных в объекте Hierarchy Mat равно null?

  • Если да: как я могу извлечь соответствующие иерархические данные из этого объекта Mat?
  • Если нет: есть ли способ обходить эту ошибку, где иерархические данные null? Можно ли, например, вернуться к EmguCV 2.x?

ответ

1

Может быть, это поздно, но ...

Вы можете попробовать это:

using (VectorOfVectorOfPoint vecVecPts2 = new VectorOfVectorOfPoint()) 
{ 

    int[,] hierarchy = CvInvoke.FindContourTree(img3, vecVecPts2, 
    ChainApproxMethod.ChainApproxNone); 
} 

или: Emgu CV 3 findContours and hierarchy parameter of type Vec4i equivalent?

 /// >>>>Based on [joshuanapoli] answer<<< 
     /// <summary> 
     /// Get a neighbor index in the heirarchy tree. 
     /// </summary> 
     /// <returns> 
     /// A neighbor index or -1 if the given neighbor does not exist. 
     /// </returns> 
     //public int Get(HierarchyIndex component, int index) 
     //public int GetHierarchy(Mat Hierarchy, int contourIdx, int component) 
     public int[] GetHierarchy(Mat Hierarchy, int contourIdx) 
     { 
      int[] ret = new int[] { }; 

      if (Hierarchy.Depth != Emgu.CV.CvEnum.DepthType.Cv32S) 
      { 
       throw new ArgumentOutOfRangeException("ContourData must have Cv32S hierarchy element type."); 
      } 
      if (Hierarchy.Rows != 1) 
      { 
       throw new ArgumentOutOfRangeException("ContourData must have one hierarchy hierarchy row."); 
      } 
      if (Hierarchy.NumberOfChannels != 4) 
      { 
       throw new ArgumentOutOfRangeException("ContourData must have four hierarchy channels."); 
      } 
      if (Hierarchy.Dims != 2) 
      { 
       throw new ArgumentOutOfRangeException("ContourData must have two dimensional hierarchy."); 
      } 
      long elementStride = Hierarchy.ElementSize/sizeof(Int32); 
      var offset0 = (long)0 + contourIdx * elementStride; 
      if (0 <= offset0 && offset0 < Hierarchy.Total.ToInt64() * elementStride) 
      { 


       var offset1 = (long)1 + contourIdx * elementStride; 
       var offset2 = (long)2 + contourIdx * elementStride; 
       var offset3 = (long)3 + contourIdx * elementStride; 

       ret = new int[4]; 

       unsafe 
       { 
        //return *((Int32*)Hierarchy.DataPointer.ToPointer() + offset); 

        ret[0] = *((Int32*)Hierarchy.DataPointer.ToPointer() + offset0); 
        ret[1] = *((Int32*)Hierarchy.DataPointer.ToPointer() + offset1); 
        ret[2] = *((Int32*)Hierarchy.DataPointer.ToPointer() + offset2); 
        ret[3] = *((Int32*)Hierarchy.DataPointer.ToPointer() + offset3); 
       } 


      } 
      //else 
      //{ 
      // return new int[] { }; 
      //} 

      return ret; 
     }