Skip to content

Instantly share code, notes, and snippets.

@joshuanapoli
Created November 18, 2016 12:41
Show Gist options
  • Select an option

  • Save joshuanapoli/8c3f282cece8340a1dd43aa5e80d170b to your computer and use it in GitHub Desktop.

Select an option

Save joshuanapoli/8c3f282cece8340a1dd43aa5e80d170b to your computer and use it in GitHub Desktop.
How to access OpenCV contour hierarchy data through Emgu.
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
}
}
@coumbsek
Copy link
Copy Markdown

Hello, if I want to set a specific contour hierarchy, could I just use the same pointer as Get to set my element ?

Thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment