Difference between revisions of "Planar Subdivision in CSharp"

From Emgu CV: OpenCV in .NET (C#, VB, C++ and more)
Jump to navigation Jump to search
 
(6 intermediate revisions by 4 users not shown)
Line 1: Line 1:
[[image:PlanarSubdivisionExample.png]]
+
<font color=green>'''This project is part of the Emgu.CV.Example solution'''</font>
 +
== System Requirement ==
 +
{| style="text-align:center" border="1px" cellpadding="10" cellspacing="0"
 +
!Component || Requirement || Detail
 +
|-
 +
|Emgu CV || Version 1.5 ||
 +
|-
 +
|Operation System || Cross Platform ||
 +
|}
 +
 
 +
== Source Code ==
 +
=== Emgu CV 3.x ===
 +
<div class="toccolours mw-collapsible mw-collapsed">
 +
Click to view source code
 +
<div class="mw-collapsible-content">
 +
<source lang="csharp">
 +
using System;
 +
using System.Collections.Generic;
 +
using System.Drawing;
 +
using System.Runtime.InteropServices;
 +
using Emgu.CV;
 +
using Emgu.CV.CvEnum;
 +
using Emgu.CV.Structure;
 +
using Emgu.CV.Util;
 +
 
 +
namespace PlanarSubdivisionExample
 +
{
 +
  public static class DrawSubdivision
 +
  {
 +
      /// <summary>
 +
      /// Create planar subdivision for random points
 +
      /// </summary>
 +
      /// <param name="maxValue">The points contains values between [0, maxValue)</param>
 +
      /// <param name="pointCount">The total number of points to create</param>
 +
      public static void CreateSubdivision(float maxValue, int pointCount, out Triangle2DF[] delaunayTriangles, out VoronoiFacet[] voronoiFacets)
 +
      {
 +
        #region create random points in the range of [0, maxValue]
 +
        PointF[] pts = new PointF[pointCount];
 +
        Random r = new Random((int)(DateTime.Now.Ticks & 0x0000ffff));
 +
        for (int i = 0; i < pts.Length; i++)
 +
            pts[i] = new PointF((float)r.NextDouble() * maxValue, (float)r.NextDouble() * maxValue);
 +
        #endregion
 +
 
 +
        using (Subdiv2D subdivision = new Subdiv2D(pts))
 +
        {
 +
            //Obtain the delaunay's triangulation from the set of points;
 +
            delaunayTriangles = subdivision.GetDelaunayTriangles();
 +
 
 +
            //Obtain the voronoi facets from the set of points
 +
            voronoiFacets = subdivision.GetVoronoiFacets();
 +
        }
 +
      }
 +
 
 +
      /// <summary>
 +
      /// Draw the planar subdivision
 +
      /// </summary>
 +
      /// <param name="maxValue">The points contains values between [0, maxValue)</param>
 +
      /// <param name="pointCount">The total number of points</param>
 +
      /// <returns>An image representing the planar subvidision of the points</returns>
 +
      public static Mat Draw(float maxValue, int pointCount)
 +
      {
 +
        Triangle2DF[] delaunayTriangles;
 +
        VoronoiFacet[] voronoiFacets;
 +
        Random r = new Random((int)(DateTime.Now.Ticks & 0x0000ffff));
 +
 
 +
        CreateSubdivision(maxValue, pointCount, out delaunayTriangles, out voronoiFacets);
 +
 
 +
        //create an image for display purpose
 +
        Mat img = new Mat((int)maxValue, (int)maxValue, DepthType.Cv8U, 3);
 +
 
 +
        //Draw the voronoi Facets
 +
        foreach (VoronoiFacet facet in voronoiFacets)
 +
        {
 +
#if NETFX_CORE
 +
            Point[] polyline = Extensions.ConvertAll<PointF, Point>(facet.Vertices, Point.Round);
 +
#else
 +
            Point[] polyline = Array.ConvertAll<PointF, Point>(facet.Vertices, Point.Round);
 +
#endif
 +
            using (VectorOfPoint vp = new VectorOfPoint(polyline))
 +
            using (VectorOfVectorOfPoint vvp = new VectorOfVectorOfPoint(vp))
 +
            {
 +
              //Draw the facet in color
 +
              CvInvoke.FillPoly(
 +
                  img, vvp,
 +
                  new Bgr(r.NextDouble()*120, r.NextDouble()*120, r.NextDouble()*120).MCvScalar);
 +
 
 +
              //highlight the edge of the facet in black
 +
              CvInvoke.Polylines(img, vp, true, new Bgr(0, 0, 0).MCvScalar, 2);
 +
            }
 +
            //draw the points associated with each facet in red
 +
            CvInvoke.Circle(img, Point.Round( facet.Point ), 5, new Bgr(0, 0, 255).MCvScalar, -1);
 +
        }
 +
 
 +
        //Draw the Delaunay triangulation
 +
        foreach (Triangle2DF triangle in delaunayTriangles)
 +
        {
 +
#if NETFX_CORE
 +
            Point[] vertices = Extensions.ConvertAll<PointF, Point>(triangle.GetVertices(), Point.Round);
 +
#else
 +
            Point[] vertices = Array.ConvertAll<PointF, Point>(triangle.GetVertices(), Point.Round);
 +
#endif
 +
            using (VectorOfPoint vp = new VectorOfPoint(vertices))
 +
            {
 +
              CvInvoke.Polylines(img, vp, true, new Bgr(255, 255, 255).MCvScalar);
 +
            }
 +
        }
 +
 
 +
        return img;
 +
      }
 +
  }
 +
}
 +
</source>
 +
</div>
 +
</div>
  
 +
=== Emgu CV 2.x ===
 +
<div class="toccolours mw-collapsible mw-collapsed">
 +
Click to view source code
 +
<div class="mw-collapsible-content">
 
<source lang="csharp">
 
<source lang="csharp">
 
using System;
 
using System;
Line 8: Line 125:
 
using Emgu.CV;
 
using Emgu.CV;
 
using Emgu.CV.UI;
 
using Emgu.CV.UI;
 +
using Emgu.CV.Structure;
  
namespace PlannarSubdivision
+
namespace PlanarSubdivisionExample
 
{
 
{
 
   static class Program
 
   static class Program
Line 29: Line 147:
  
 
         #region create random points in the range of [0, maxValue]
 
         #region create random points in the range of [0, maxValue]
         Point2D<float>[] pts = new Point2D<float>[20];
+
         PointF[] pts = new PointF[20];
 
         Random r = new Random((int)(DateTime.Now.Ticks & 0x0000ffff));
 
         Random r = new Random((int)(DateTime.Now.Ticks & 0x0000ffff));
 
         for (int i = 0; i < pts.Length; i++)
 
         for (int i = 0; i < pts.Length; i++)
             pts[i] = new Point2D<float>((float)r.NextDouble() * maxValue, (float)r.NextDouble() * maxValue);
+
             pts[i] = new PointF((float)r.NextDouble() * maxValue, (float)r.NextDouble() * maxValue);
 
         #endregion
 
         #endregion
  
         List<Triangle2D<float>> delaunayTriangles;
+
         Triangle2DF[] delaunayTriangles;
         List<VoronoiFacet> voronoiFacets;
+
         VoronoiFacet[] voronoiFacets;
 
         using (PlanarSubdivision subdivision = new PlanarSubdivision(pts))
 
         using (PlanarSubdivision subdivision = new PlanarSubdivision(pts))
 
         {
 
         {
Line 52: Line 170:
 
         foreach (VoronoiFacet facet in voronoiFacets)
 
         foreach (VoronoiFacet facet in voronoiFacets)
 
         {
 
         {
             MCvPoint[] points = Array.ConvertAll<Point2D<float>, MCvPoint>(facet.Vertices, delegate(Point2D<float> p) { return p.MCvPoint; });
+
             Point[] points = Array.ConvertAll<PointF, Point>(facet.Vertices, Point.Round);
  
 
             //Draw the facet in color
 
             //Draw the facet in color
Line 64: Line 182:
  
 
             //draw the points associated with each facet in red
 
             //draw the points associated with each facet in red
             img.Draw(new Circle<float>(facet.Point, 5), new Bgr(Color.Red), 0);
+
             img.Draw(new CircleF(facet.Point, 5.0f), new Bgr(Color.Red), 0);
 
         }
 
         }
  
 
         //Draw the Delaunay triangulation
 
         //Draw the Delaunay triangulation
         foreach (Triangle2D<float> triangles in delaunayTriangles)
+
         foreach (Triangle2DF triangles in delaunayTriangles)
 
         {
 
         {
 
             img.Draw(triangles, new Bgr(Color.White), 1);
 
             img.Draw(triangles, new Bgr(Color.White), 1);
Line 80: Line 198:
  
 
</source>
 
</source>
 +
</div>
 +
</div>
 +
 +
== Result ==
 +
[[image:PlanarSubdivisionExample.png]]

Latest revision as of 20:55, 8 June 2015

This project is part of the Emgu.CV.Example solution

System Requirement

Component Requirement Detail
Emgu CV Version 1.5
Operation System Cross Platform

Source Code

Emgu CV 3.x

Click to view source code

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Runtime.InteropServices;
using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
using Emgu.CV.Util;

namespace PlanarSubdivisionExample
{
   public static class DrawSubdivision
   {
      /// <summary>
      /// Create planar subdivision for random points
      /// </summary>
      /// <param name="maxValue">The points contains values between [0, maxValue)</param>
      /// <param name="pointCount">The total number of points to create</param>
      public static void CreateSubdivision(float maxValue, int pointCount, out Triangle2DF[] delaunayTriangles, out VoronoiFacet[] voronoiFacets)
      {
         #region create random points in the range of [0, maxValue]
         PointF[] pts = new PointF[pointCount];
         Random r = new Random((int)(DateTime.Now.Ticks & 0x0000ffff));
         for (int i = 0; i < pts.Length; i++)
            pts[i] = new PointF((float)r.NextDouble() * maxValue, (float)r.NextDouble() * maxValue);
         #endregion

         using (Subdiv2D subdivision = new Subdiv2D(pts))
         {
            //Obtain the delaunay's triangulation from the set of points;
            delaunayTriangles = subdivision.GetDelaunayTriangles();

            //Obtain the voronoi facets from the set of points
            voronoiFacets = subdivision.GetVoronoiFacets();
         }
      }

      /// <summary>
      /// Draw the planar subdivision
      /// </summary>
      /// <param name="maxValue">The points contains values between [0, maxValue)</param>
      /// <param name="pointCount">The total number of points</param>
      /// <returns>An image representing the planar subvidision of the points</returns>
      public static Mat Draw(float maxValue, int pointCount)
      {
         Triangle2DF[] delaunayTriangles;
         VoronoiFacet[] voronoiFacets;
         Random r = new Random((int)(DateTime.Now.Ticks & 0x0000ffff));

         CreateSubdivision(maxValue, pointCount, out delaunayTriangles, out voronoiFacets);

         //create an image for display purpose
         Mat img = new Mat((int)maxValue, (int)maxValue, DepthType.Cv8U, 3);

         //Draw the voronoi Facets
         foreach (VoronoiFacet facet in voronoiFacets)
         {
#if NETFX_CORE
            Point[] polyline = Extensions.ConvertAll<PointF, Point>(facet.Vertices, Point.Round);
#else
            Point[] polyline = Array.ConvertAll<PointF, Point>(facet.Vertices, Point.Round);
#endif
            using (VectorOfPoint vp = new VectorOfPoint(polyline))
            using (VectorOfVectorOfPoint vvp = new VectorOfVectorOfPoint(vp))
            {
               //Draw the facet in color
               CvInvoke.FillPoly(
                  img, vvp, 
                  new Bgr(r.NextDouble()*120, r.NextDouble()*120, r.NextDouble()*120).MCvScalar);

               //highlight the edge of the facet in black
               CvInvoke.Polylines(img, vp, true, new Bgr(0, 0, 0).MCvScalar, 2);
            }
            //draw the points associated with each facet in red
            CvInvoke.Circle(img, Point.Round( facet.Point ), 5, new Bgr(0, 0, 255).MCvScalar, -1);
         }

         //Draw the Delaunay triangulation
         foreach (Triangle2DF triangle in delaunayTriangles)
         {
#if NETFX_CORE
            Point[] vertices = Extensions.ConvertAll<PointF, Point>(triangle.GetVertices(), Point.Round);
#else
            Point[] vertices = Array.ConvertAll<PointF, Point>(triangle.GetVertices(), Point.Round);
#endif
            using (VectorOfPoint vp = new VectorOfPoint(vertices))
            {
               CvInvoke.Polylines(img, vp, true, new Bgr(255, 255, 255).MCvScalar);
            }
         }

         return img;
      }
   }
}

Emgu CV 2.x

Click to view source code

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Drawing;
using Emgu.CV;
using Emgu.CV.UI;
using Emgu.CV.Structure;

namespace PlanarSubdivisionExample
{
   static class Program
   {
      /// <summary>
      /// The main entry point for the application.
      /// </summary>
      [STAThread]
      static void Main()
      {
         Application.EnableVisualStyles();
         Application.SetCompatibleTextRenderingDefault(false);
         Run();
      }

      static void Run()
      {
         float maxValue = 600;

         #region create random points in the range of [0, maxValue]
         PointF[] pts = new PointF[20];
         Random r = new Random((int)(DateTime.Now.Ticks & 0x0000ffff));
         for (int i = 0; i < pts.Length; i++)
            pts[i] = new PointF((float)r.NextDouble() * maxValue, (float)r.NextDouble() * maxValue);
         #endregion

         Triangle2DF[] delaunayTriangles;
         VoronoiFacet[] voronoiFacets;
         using (PlanarSubdivision subdivision = new PlanarSubdivision(pts))
         {
            //Obtain the delaunay's triangulation from the set of points;
            delaunayTriangles = subdivision.GetDelaunayTriangles();

            //Obtain the voronoi facets from the set of points
            voronoiFacets = subdivision.GetVoronoiFacets();
         }

         //create an image for display purpose
         Image<Bgr, Byte> img = new Image<Bgr, byte>((int)maxValue, (int) maxValue);

         //Draw the voronoi Facets
         foreach (VoronoiFacet facet in voronoiFacets)
         {
            Point[] points = Array.ConvertAll<PointF, Point>(facet.Vertices, Point.Round);

            //Draw the facet in color
            img.FillConvexPoly(
                points,
                new Bgr(r.NextDouble() * 120, r.NextDouble() * 120, r.NextDouble() * 120)
                );

            //highlight the edge of the facet in black
            img.DrawPolyline(points, true, new Bgr(Color.Black), 2);

            //draw the points associated with each facet in red
            img.Draw(new CircleF(facet.Point, 5.0f), new Bgr(Color.Red), 0);
         }

         //Draw the Delaunay triangulation
         foreach (Triangle2DF triangles in delaunayTriangles)
         {
            img.Draw(triangles, new Bgr(Color.White), 1);
         }

         //display the image
         ImageViewer.Show(img, "Plannar Subdivision");
      }
   }
}

Result

PlanarSubdivisionExample.png