Planar Subdivision in CSharp: Difference between revisions

From EMGU
Jump to navigation Jump to search
New page: <source lang="csharp"> using System; using System.Collections.Generic; using System.Windows.Forms; using System.Drawing; using Emgu.CV; using Emgu.CV.UI; namespace PlannarSubdivision { ...
 
 
(7 intermediate revisions by 4 users not shown)
Line 1: Line 1:
<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 7: 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 28: 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 51: 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 63: 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 79: 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