Example #1
0
        static void Main(string[] args)
        {
            MyCustomDatasetItem[] featureData = { };

            List<MyCustomDatasetItem> testPoints = new List<MyCustomDatasetItem>();
            for (int i = 0; i < 1000; i++)
            {
                //points around (1,1) with most 1 distance
                testPoints.Add(new MyCustomDatasetItem(1, 1 + ((float)i / 1000)));
                testPoints.Add(new MyCustomDatasetItem(1, 1 - ((float)i / 1000)));
                testPoints.Add(new MyCustomDatasetItem(1 - ((float)i / 1000), 1));
                testPoints.Add(new MyCustomDatasetItem(1 + ((float)i / 1000), 1));

                //points around (5,5) with most 1 distance
                testPoints.Add(new MyCustomDatasetItem(5, 5 + ((float)i / 1000)));
                testPoints.Add(new MyCustomDatasetItem(5, 5 - ((float)i / 1000)));
                testPoints.Add(new MyCustomDatasetItem(5 - ((float)i / 1000), 5));
                testPoints.Add(new MyCustomDatasetItem(5 + ((float)i / 1000), 5));
            }
            featureData = testPoints.ToArray();
            HashSet<MyCustomDatasetItem[]> clusters;

            var dbs = new DbscanAlgorithm<MyCustomDatasetItem>((x, y) => Math.Sqrt(((x.X - y.X) * (x.X - y.X)) + ((x.Y - y.Y) * (x.Y - y.Y))));
            dbs.ComputeClusterDbscan(allPoints: featureData, epsilon: .01, minPts: 10, clusters: out clusters);
        }
Example #2
0
        /// <summary>
        /// Most basic usage of Dbscan implementation, with no eventing and async mechanism
        /// </summary>
        /// <param name="features">Features provided</param>
        private static void RunOfflineDbscan(List <MyFeature> features)
        {
            var simpleDbscan = new DbscanAlgorithm <MyFeature>(EuclidienDistance);

            var result = simpleDbscan.ComputeClusterDbscan(allPoints: features.ToArray(),
                                                           epsilon: .01, minimumPoints: 10);

            Console.WriteLine($"Noise: {result.Noise.Count}");

            Console.WriteLine($"# of Clusters: {result.Clusters.Count}");
        }
Example #3
0
        static void Main(string[] args)
        {
            MyCustomFeature[] featureData = { };

            var testPoints = new List <MyCustomFeature>();

            //points around (1,1) with most 1 distance
            testPoints.Add(new MyCustomFeature(1, 1));
            for (int i = 1; i <= 1000; i++)
            {
                float v = ((float)i / 1000);
                testPoints.Add(new MyCustomFeature(1, 1 + v));
                testPoints.Add(new MyCustomFeature(1, 1 - v));
                testPoints.Add(new MyCustomFeature(1 - v, 1));
                testPoints.Add(new MyCustomFeature(1 + v, 1));
            }

            //points around (5,5) with most 1 distance
            testPoints.Add(new MyCustomFeature(5, 5));
            for (int i = 1; i <= 1000; i++)
            {
                float v = ((float)i / 1000);
                testPoints.Add(new MyCustomFeature(5, 5 + v));
                testPoints.Add(new MyCustomFeature(5, 5 - v));
                testPoints.Add(new MyCustomFeature(5 - v, 5));
                testPoints.Add(new MyCustomFeature(5 + v, 5));
            }

            featureData = testPoints.ToArray();

            //INFO: applied euclidean distance as metric calculation function
            var dbscan = new DbscanAlgorithm <MyCustomFeature>(
                (feature1, feature2) =>
                Math.Sqrt(
                    ((feature1.X - feature2.X) * (feature1.X - feature2.X)) +
                    ((feature1.Y - feature2.Y) * (feature1.Y - feature2.Y))
                    )
                );

            var result = dbscan.ComputeClusterDbscan(allPoints: featureData, epsilon: .01, minimumPoints: 10);
        }
Example #4
0
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            bool IsPointData = false;

            GH_Structure <IGH_Goo> data = new GH_Structure <IGH_Goo>();
            List <double>          eps  = new List <double>();
            List <int>             minP = new List <int>();

            if (!DA.GetDataTree(0, out data))
            {
                return;
            }
            if (!DA.GetDataList(1, eps))
            {
                return;
            }
            if (!DA.GetDataList(2, minP))
            {
                return;
            }

            data.Simplify(GH_SimplificationMode.CollapseAllOverlaps);

            List <DataSetItemPoint[]> points = new List <DataSetItemPoint[]>();

            for (int i = 0; i < data.Branches.Count; i++)
            {
                DataSetItemPoint[] pp = new DataSetItemPoint[data.Branches[i].Count];

                for (int j = 0; j < data.Branches[i].Count; j++)
                {
                    if (data.Branches[i][j] is GH_Point)
                    {
                        IsPointData = true;
                        GH_Point target = new GH_Point();
                        if (GH_Convert.ToGHPoint(data.Branches[i][j], GH_Conversion.Both, ref target))
                        {
                            pp[j] = new DataSetItemPoint(target.Value.X, target.Value.Y, target.Value.Z, 0.0);
                        }
                    }
                    else
                    {
                        break;
                    }
                }
                if (IsPointData)
                {
                    points.Add(pp);
                }
                else
                {
                    break;
                }
            }

            // double data
            if (!IsPointData)
            {
                DataSetItemPoint[] pp = new DataSetItemPoint[data.Branches.Count];

                for (int i = 0; i < data.Branches.Count; i++)
                {
                    DataSetItemPoint p = new DataSetItemPoint();
                    for (int j = 0; j < data.Branches[i].Count; j++)
                    {
                        if (data.Branches[i][j] is GH_Number)
                        {
                            if (GH_Convert.ToDouble(data.Branches[i][j], out double value, GH_Conversion.Both))
                            {
                                switch (j)
                                {
                                case 0:
                                    p.X = value;
                                    break;

                                case 1:
                                    p.Y = value;
                                    break;

                                case 2:
                                    p.Z = value;
                                    break;

                                case 3:
                                    p.W = value;
                                    break;
                                }
                            }
                        }
                    }
                    pp[i] = p;
                }
                points.Add(pp);
            }

            if (IsPointData)
            {
                DataTree <IGH_Goo> output = new DataTree <IGH_Goo>();

                for (int i = 0; i < points.Count; i++)
                {
                    DbscanAlgorithm <DataSetItemPoint> dbs = new DbscanAlgorithm <DataSetItemPoint>((x, y) => Math.Sqrt(((x.X - y.X) * (x.X - y.X)) + ((x.Y - y.Y) * (x.Y - y.Y)) + ((x.Z - y.Z) * (x.Z - y.Z)) + ((x.W - y.W) * (x.W - y.W))));
                    dbs.ComputeClusterDbscan(points[i].ToArray(), eps[i], minP[i], out HashSet <DataSetItemPoint[]> clusters3d);

                    for (int j = 0; j < clusters3d.Count; j++)
                    {
                        ConcurrentQueue <GH_Point> _points = new ConcurrentQueue <GH_Point>();
                        Parallel.ForEach(clusters3d.ElementAt(j), p =>
                        {
                            _points.Enqueue(new GH_Point(new Point3d(p.X, p.Y, p.Z)));
                        });

                        output.AddRange(_points.ToList(), new GH_Path(i, j));
                    }
                }

                DA.SetDataTree(0, output);
            }
            else
            {
                DataTree <GH_Number> output = new DataTree <GH_Number>();

                for (int i = 0; i < points.Count; i++)
                {
                    DbscanAlgorithm <DataSetItemPoint> dbs = new DbscanAlgorithm <DataSetItemPoint>((x, y) => Math.Sqrt(((x.X - y.X) * (x.X - y.X)) + ((x.Y - y.Y) * (x.Y - y.Y)) + ((x.Z - y.Z) * (x.Z - y.Z)) + ((x.W - y.W) * (x.W - y.W))));
                    dbs.ComputeClusterDbscan(points[i].ToArray(), eps[i], minP[i], out HashSet <DataSetItemPoint[]> clusters3d);

                    for (int j = 0; j < clusters3d.Count; j++)
                    {
                        ConcurrentQueue <List <double> > _points = new ConcurrentQueue <List <double> >();

                        for (int k = 0; k < clusters3d.ElementAt(j).Length; k++)
                        {
                            List <GH_Number> ii      = new List <GH_Number>();
                            GH_Number        target1 = new GH_Number();
                            GH_Number        target2 = new GH_Number();
                            GH_Number        target3 = new GH_Number();
                            GH_Number        target4 = new GH_Number();
                            if (GH_Convert.ToGHNumber(clusters3d.ElementAt(j).ElementAt(k).X, GH_Conversion.Both, ref target1))
                            {
                                ii.Add(target1);
                            }
                            if (GH_Convert.ToGHNumber(clusters3d.ElementAt(j).ElementAt(k).Y, GH_Conversion.Both, ref target2))
                            {
                                ii.Add(target2);
                            }
                            if (GH_Convert.ToGHNumber(clusters3d.ElementAt(j).ElementAt(k).Z, GH_Conversion.Both, ref target3))
                            {
                                ii.Add(target3);
                            }
                            if (GH_Convert.ToGHNumber(clusters3d.ElementAt(j).ElementAt(k).W, GH_Conversion.Both, ref target4))
                            {
                                ii.Add(target4);
                            }

                            output.AddRange(ii, new GH_Path(i, j, k));
                        }
                    }
                }
                DA.SetDataTree(0, output);
            }
        }
Example #5
0
        static void Main(string[] args)
        {
            MyCustomFeature[] featureData = { };

            var testPoints = new List <MyCustomFeature>()
            {
            };

            //points around (1,1) with most 1 distance
            testPoints.Add(new MyCustomFeature(1, 1));
            for (int i = 1; i <= 1000; i++)
            {
                var v = (float)i / 1000;
                testPoints.Add(new MyCustomFeature(1, 1 + v));
                testPoints.Add(new MyCustomFeature(1, 1 - v));
                testPoints.Add(new MyCustomFeature(1 - v, 1));
                testPoints.Add(new MyCustomFeature(1 + v, 1));
            }

            //points around (5,5) with most 1 distance
            testPoints.Add(new MyCustomFeature(5, 5));
            for (int i = 1; i <= 1000; i++)
            {
                var v = (float)i / 1000;
                testPoints.Add(new MyCustomFeature(5, 5 + v));
                testPoints.Add(new MyCustomFeature(5, 5 - v));
                testPoints.Add(new MyCustomFeature(5 - v, 5));
                testPoints.Add(new MyCustomFeature(5 + v, 5));
            }

            //noise point
            testPoints.Add(new MyCustomFeature(10, 10));

            featureData = testPoints.ToArray();

            //INFO: applied euclidean distance as metric calculation function
            var dbscan = new DbscanAlgorithm <MyCustomFeature>(
                (feature1, feature2) =>
                Math.Sqrt(
                    ((feature1.X - feature2.X) * (feature1.X - feature2.X)) +
                    ((feature1.Y - feature2.Y) * (feature1.Y - feature2.Y))
                    )
                );

            var result = dbscan.ComputeClusterDbscan(allPoints: featureData, epsilon: .01, minimumPoints: 10);

            Console.WriteLine($"Noise: {result.Noise.Length}");

            Console.WriteLine($"# of Clusters: {result.Clusters.Count}");


            //INFO: applied euclidean distance as metric calculation function
            //INFO: second argument of constructor takes an instance implemented with IDbscanEventPublisher interface
            var dbscanWithEventing = new DbscanAlgorithm <MyCustomFeature>(
                (feature1, feature2) =>
                Math.Sqrt(
                    ((feature1.X - feature2.X) * (feature1.X - feature2.X)) +
                    ((feature1.Y - feature2.Y) * (feature1.Y - feature2.Y))
                    ),
                new DbscanLogger()
                );

            var resultWithEventing = dbscanWithEventing.ComputeClusterDbscan(allPoints: featureData, epsilon: .01, minimumPoints: 10);

            Console.WriteLine($"Noise: {resultWithEventing.Noise.Length}");

            Console.WriteLine($"# of Clusters: {resultWithEventing.Clusters.Count}");
        }
        private void ProcessFrame(object sender, EventArgs e)
        {
            if (BeforeProcessFrame != null)
                BeforeProcessFrame();

            Mat curImage = new Mat();
            var imageGrabbed = capture.Retrieve(curImage);
            {
                if (!imageGrabbed)
                {
                    capture.Stop();
                    return;
                }
                if (counter == 0)
                {

                }

                Interlocked.Increment(ref counter);

                if (counter == 1)
                {
                }

                if (counter % FrameInterval != 0)
                {
                    if (counter % FrameInterval == 1)
                    {
                        prevImage = new Image<Bgr, byte>(curImage.Bitmap);
                    }
                    return;
                }

                //Process starts here

                var prevGray = prevImage.Convert<Gray, byte>();
                var curGray = curImage.ToImage<Gray, byte>();

                var denseResult = new DenseOpticalFlowAlgorithm(prevGray, curGray, Parameters)
                {
                    VectorNoiseThreshold = VectorGlobalThreshold,
                    WindowSideLength = WindowSideLength,
                    ComputeFlowImage = ComputeFlowImage
                }.Compute();

                if (OpticalFlowVectorsProcessed != null)
                {
                    OpticalFlowVectorsProcessed(denseResult.FlowVectorImage);
                }

                OpticalFlowPoint[] pointsToCluster = denseResult.FlowLineArray
                    .Where(x => x.OverThreshold)
                    .Select(x => new OpticalFlowPoint(
                        x.Line.P2,
                        x.Line.GetExteriorAngleDegree(DenseOpticalFlowAlgorithm.UnitVectorOfX)))
                    .ToArray();

                var clusters =
                    new DbscanAlgorithm<OpticalFlowPoint>(
                        (p, x) => p - x,
                        Math.Abs(OrientationAngle) <= 0 || Math.Abs(OrientationAngle) >= 360
                            ? (Func<OpticalFlowPoint, OpticalFlowPoint, bool>)null
                            : (point, x) => Math.Abs(point.ExteriorAngleDegree - x.ExteriorAngleDegree)  < OrientationAngle)
                        .ComputeClusterDbscan(pointsToCluster, Epsilon, MinPts);

                #region Draw vectors per frame

                var processedImage = new Image<Bgr, byte>(curImage.Bitmap);
                foreach (var line in denseResult.FlowLineArray.Where(x => x.OverThreshold).Select(x => x.Line).ToArray())
                {
                    processedImage.Draw(new CircleF(line.P2, 2), new Bgr(Color.Yellow));
                }

                #endregion

                //draw cluster rectangles
                foreach (var points in clusters)
                {
                    var polyLines = PointCollection.BoundingRectangle(points.Select(x => x.EndPoint).ToArray());
                    processedImage.Draw(polyLines, new Bgr(Color.Red), 2);
                }

                //draw convex hull
                foreach (var points in clusters)
                {
                    PointF[] hull = CvInvoke.ConvexHull(points.Select(x => x.EndPoint).ToArray());
                    processedImage.DrawPolyline(Array.ConvertAll(hull, Point.Round), true, new Bgr(Color.Blue));
                }

                ImageProcessed(processedImage);
            }
        }