Created
November 18, 2016 12:41
-
-
Save joshuanapoli/8c3f282cece8340a1dd43aa5e80d170b to your computer and use it in GitHub Desktop.
Revisions
-
joshuanapoli revised this gist
Nov 18, 2016 . No changes.There are no files selected for viewing
-
joshuanapoli created this gist
Nov 18, 2016 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,132 @@ using System; using Emgu.CV; using Emgu.CV.Util; namespace OCVContours { /// <summary> /// The contour hierarchy result of OpenCV's FindContours function /// </summary> public class ContourData : IDisposable { /// <summary> /// Construct an empty collection. /// </summary> public ContourData() { Vertices = new VectorOfVectorOfPoint(); Hierarchy = new Mat(); } /// <summary> /// Construct, taking ownership of the contours and hiearachy OpenCV objects. /// </summary> public ContourData(VectorOfVectorOfPoint contours, Mat hierarchy) { if (contours == null) { throw new ArgumentNullException("ContourData must not have null contours."); } if (hierarchy == null) { throw new ArgumentNullException("ContourData must not have null hierarchy."); } Vertices = contours; Hierarchy = hierarchy; } /// <remarks> /// Guaranteed to be not-null, because the property is non-asignable and assignment is guaranteed by the constructors. /// </remarks> public VectorOfVectorOfPoint Vertices { get; } /// <summary> /// For each i-th contour contours[i], the elements hierarchy[i][0], /// hiearchy[i][1], hiearchy[i][2], and hiearchy[i][3] are set to /// 0-based indices in contours of the next and previous contours at /// the same hierarchical level, the first child contour and the parent /// contour, respectively. If for the contour i there are no next, /// previous, parent, or nested contours, the corresponding elements of /// hierarchy[i] will be negative. /// </summary> /// <remarks> /// Guaranteed to be not-null. /// </remarks> public Mat Hierarchy { get; } /// <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) { 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 offset = (long)component + index * elementStride; if (0 <= offset && offset < Hierarchy.Total.ToInt64() * elementStride) { unsafe { return *((Int32*)Hierarchy.DataPointer.ToPointer() + offset); } } else { return -1; } } public int Size { get { var verticesSize = Vertices.Size; var hierarchySize = Hierarchy.Cols; if (verticesSize == hierarchySize) { return verticesSize; } else { throw new InvalidOperationException("The ContourData size is undefined because the contour vertices and hierarchy arrays have different length."); } } } #region IDisposable protected virtual void Dispose(bool disposing) { if (disposing) { Vertices.Dispose(); Hierarchy.Dispose(); } } public void Dispose() { Dispose(true); } #endregion } }