Exemplo n.º 1
0
        public static PointF[] GetSegmentOfPolygon(PointF[] polygon, PointF p1, PointF p2)
        {
            List <PointF> points = new List <PointF>();

            double startMin = Double.MaxValue, endMin = Double.MaxValue;

            int startIndex = 0, endIndex = 0;

            int counter = 0;

            foreach (PointF point in polygon)
            {
                double p1Dist = p1.DistanceSquared(point);
                if (p1Dist < startMin)
                {
                    startMin   = p1Dist;
                    startIndex = counter;
                }

                double p2Dist = p2.DistanceSquared(point);
                if (p2Dist < endMin)
                {
                    endMin   = p2Dist;
                    endIndex = counter;
                }

                counter++;
            }

            int lowerBound, upperBound;

            if (startIndex < endIndex)
            {
                lowerBound = startIndex;
                upperBound = endIndex;
            }
            else
            {
                lowerBound = endIndex;
                upperBound = startIndex;
            }

            for (int i = lowerBound; i < upperBound; i++)
            {
                points.Add(polygon[i]);
            }

            return(points.ToArray());
        }
Exemplo n.º 2
0
        private void UpdateFrameNumber()
        {
            Video.SetFrame(SliderValue);

            using (Image <Bgr, Byte> orig = Video.GetFrameImage())
                using (Image <Gray, Byte> origGray = orig.Convert <Gray, Byte>())
                    using (Image <Gray, Byte> binary = origGray.ThresholdBinary(new Gray(ThresholdValue), new Gray(255)))
                        using (Image <Gray, Byte> subbed = BinaryBackground.AbsDiff(binary))
                        {
                            CvBlobs blobs = new CvBlobs();
                            BlobDetector.Detect(subbed, blobs);

                            CvBlob mouseBlob = null;
                            double maxArea   = -1;
                            foreach (var blob in blobs.Values)
                            {
                                if (blob.Area > maxArea)
                                {
                                    mouseBlob = blob;
                                    maxArea   = blob.Area;
                                }
                            }

                            //double gapDistance = GetBestGapDistance(rbsk);
                            double gapDistance = 50;
                            RBSK.Settings.GapDistance = gapDistance;
                            //PointF[] headPoints = ProcessFrame(orig, RBSK);
                            PointF center = mouseBlob.Centroid;
                            //LineSegment2DF[] targetPoints = null;

                            Point[] mouseContour = mouseBlob.GetContour();

                            orig.DrawPolyline(mouseContour, true, new Bgr(Color.Cyan));
                            Image1 = ImageService.ToBitmapSource(orig);

                            PointF[] result;
                            if (HeadPoints != null)
                            {
                                result = HeadPoints[SliderValue].HeadPoints;
                            }
                            else
                            {
                                double prob     = 0;
                                RBSK   headRbsk = MouseService.GetStandardMouseRules();
                                headRbsk.Settings.GapDistance     = 65;
                                headRbsk.Settings.BinaryThreshold = 20;

                                List <List <PointF> > allKeyPoints = headRbsk.FindKeyPoints(mouseContour, headRbsk.Settings.NumberOfSlides, false);
                                result = headRbsk.FindPointsFromRules(allKeyPoints[0], binary, ref prob);
                            }

                            if (result != null)
                            {
                                using (Image <Bgr, Byte> test = orig.Clone())
                                {
                                    foreach (var point in result)
                                    {
                                        test.Draw(new CircleF(point, 3), new Bgr(Color.Red), 3);
                                    }

                                    Image1 = ImageService.ToBitmapSource(test);
                                }
                            }
                            else
                            {
                                return;
                            }

                            RotatedRect rotatedRect = CvInvoke.MinAreaRect(mouseContour.Select(x => new PointF(x.X, x.Y)).ToArray());
                            //Console.WriteLine("Size: " + rotatedRect.Size);

                            ISkeleton          skel       = ModelResolver.Resolve <ISkeleton>();
                            Image <Gray, Byte> tempBinary = binary.Clone();

                            System.Drawing.Rectangle rect      = mouseBlob.BoundingBox;
                            Image <Gray, Byte>       binaryRoi = tempBinary.GetSubRect(rect);
                            using (Image <Bgr, Byte> displayImage = subbed.Convert <Bgr, Byte>())

                                using (Image <Gray, Byte> skelImage = skel.GetSkeleton(binaryRoi))
                                    using (Image <Bgr, Byte> drawImage = orig.Clone())
                                        using (Image <Bgr, Byte> tempImage2 = new Image <Bgr, byte>(drawImage.Size))
                                        {
                                            //-----------------------------------------
                                            if (SkelImage != null)
                                            {
                                                SkelImage.Dispose();
                                            }
                                            SkelImage = skelImage.Clone();
                                            //--------------------------------------------

                                            tempImage2.SetValue(new Bgr(Color.Black));
                                            ISpineFinding spineFinder = ModelResolver.Resolve <ISpineFinding>();
                                            spineFinder.NumberOfCycles     = 3;
                                            spineFinder.NumberOfIterations = 1;
                                            spineFinder.SkeletonImage      = skelImage;
                                            //spineFinder.RotatedRectangle = rotatedRect;
                                            Image5 = ImageService.ToBitmapSource(skelImage);

                                            const int delta         = 20;
                                            double    smallestAngle = double.MaxValue;
                                            Point     tailPoint     = Point.Empty;
                                            for (int i = 0; i < mouseContour.Length; i++)
                                            {
                                                int leftDelta  = i - delta;
                                                int rightDelta = i + delta;

                                                if (leftDelta < 0)
                                                {
                                                    leftDelta += mouseContour.Length;
                                                }

                                                if (rightDelta >= mouseContour.Length)
                                                {
                                                    rightDelta -= mouseContour.Length;
                                                }

                                                Point testPoint  = mouseContour[i];
                                                Point leftPoint  = mouseContour[leftDelta];
                                                Point rightPoint = mouseContour[rightDelta];

                                                Vector v1 = new Vector(leftPoint.X - testPoint.X, leftPoint.Y - testPoint.Y);
                                                Vector v2 = new Vector(rightPoint.X - testPoint.X, rightPoint.Y - testPoint.Y);

                                                double angle = Math.Abs(Vector.AngleBetween(v1, v2));

                                                if (angle < 30 && angle > 9)
                                                {
                                                    if (angle < smallestAngle)
                                                    {
                                                        smallestAngle = angle;
                                                        tailPoint     = testPoint;
                                                    }
                                                }
                                            }

                                            PointF   headCornerCorrect    = new PointF(result[2].X - rect.X, result[2].Y - rect.Y);
                                            PointF   tailCornerCorrect    = new PointF(tailPoint.X - rect.X, tailPoint.Y - rect.Y);
                                            PointF[] spine                = spineFinder.GenerateSpine(headCornerCorrect, tailCornerCorrect);
                                            Point    topCorner            = mouseBlob.BoundingBox.Location;
                                            PointF[] spineCornerCorrected = new PointF[spine.Length];

                                            for (int i = 0; i < spine.Length; i++)
                                            {
                                                spineCornerCorrected[i] = new PointF(spine[i].X + topCorner.X, spine[i].Y + topCorner.Y);
                                            }

                                            ITailFinding tailFinding  = ModelResolver.Resolve <ITailFinding>();
                                            double       rotatedWidth = rotatedRect.Size.Width < rotatedRect.Size.Height ? rotatedRect.Size.Width : rotatedRect.Size.Height;
                                            List <Point> bodyPoints;

                                            if (result != null)
                                            {
                                                double firstDist = result[2].DistanceSquared(spineCornerCorrected.First());
                                                double lastDist  = result[2].DistanceSquared(spineCornerCorrected.Last());

                                                if (firstDist < lastDist)
                                                {
                                                    spineCornerCorrected = spineCornerCorrected.Reverse().ToArray();
                                                }
                                            }

                                            double waistLength;
                                            double pelvicArea1, pelvicArea2;
                                            tailFinding.FindTail(mouseContour, spineCornerCorrected, displayImage, rotatedWidth, mouseBlob.Centroid, out bodyPoints, out waistLength, out pelvicArea1, out pelvicArea2);

                                            Console.WriteLine(smallestAngle);
                                            if (!tailPoint.IsEmpty)
                                            {
                                                drawImage.Draw(new CircleF(tailPoint, 4), new Bgr(Color.Red), 3);
                                            }

                                            if (bodyPoints != null && bodyPoints.Count > 0)
                                            {
                                                Point[] bPoints = bodyPoints.ToArray();
                                                double  volume  = MathExtension.PolygonArea(bPoints);
                                                Emgu.CV.Structure.Ellipse fittedEllipse = PointCollection.EllipseLeastSquareFitting(bPoints.Select(x => x.ToPointF()).ToArray());
                                                //CvInvoke.Ellipse(drawImage, fittedEllipse.RotatedRect, new MCvScalar(0, 0, 255), 2);

                                                Console.WriteLine("Volume: " + volume + " - " + (fittedEllipse.RotatedRect.Size.Width * fittedEllipse.RotatedRect.Size.Height) + ", Waist Length: " + waistLength);

                                                //Alter this to something better
                                                if (MathExtension.PolygonArea(bPoints) > (rotatedRect.Size.Height * rotatedRect.Size.Width) / 6 || true)
                                                {
                                                    //tempImage2.FillConvexPoly(bPoints, new Bgr(Color.White));
                                                    tempImage2.DrawPolyline(bPoints, true, new Bgr(Color.White));
                                                    PointF centroid = MathExtension.FindCentroid(bPoints);
                                                    System.Drawing.Rectangle minRect;
                                                    Image <Gray, Byte>       temp2 = new Image <Gray, byte>(tempImage2.Width + 2, tempImage2.Height + 2);
                                                    CvInvoke.FloodFill(tempImage2, temp2, centroid.ToPoint(), new MCvScalar(255, 255, 255), out minRect, new MCvScalar(5, 5, 5), new MCvScalar(5, 5, 5));

                                                    using (Image <Gray, Byte> nonZeroImage = tempImage2.Convert <Gray, Byte>())
                                                    {
                                                        int[] volume2 = nonZeroImage.CountNonzero();
                                                        Console.WriteLine("Volume2: " + volume2[0]);

                                                        //int tester = 9;
                                                        //using (Image<Gray, Byte> t1 = nonZeroImage.Erode(tester))
                                                        //using (Image<Gray, Byte> t2 = t1.Dilate(tester))
                                                        //using (Image<Gray, Byte> t3 = t2.Erode(tester))
                                                        //using (Image<Gray, Byte> t4 = t3.Dilate(tester))
                                                        //using (Image<Gray, Byte> t5 = t4.Erode(tester))
                                                        //using (Image<Gray, Byte> t6 = t5.Dilate(tester))
                                                        //using (Image<Gray, Byte> t7 = t6.Erode(tester))
                                                        //{
                                                        //    Image6 = ImageService.ToBitmapSource(t7);
                                                        //}
                                                    }

                                                    tempImage2.Draw(new CircleF(centroid, 2), new Bgr(Color.Blue), 2);
                                                    double distanceToSpine = double.MaxValue;
                                                    PointF p11 = PointF.Empty, p22 = PointF.Empty;
                                                    for (int i = 1; i < spineCornerCorrected.Length; i++)
                                                    {
                                                        PointF point1 = spineCornerCorrected[i - 1];
                                                        PointF point2 = spineCornerCorrected[i];

                                                        double cDist = MathExtension.MinDistanceFromLineToPoint(point1, point2, centroid);
                                                        if (cDist < distanceToSpine)
                                                        {
                                                            p11             = point1;
                                                            p22             = point2;
                                                            distanceToSpine = cDist;
                                                        }
                                                    }

                                                    PointSideVector psv = MathExtension.FindSide(p11, p22, centroid);

                                                    if (psv == PointSideVector.Below)
                                                    {
                                                        distanceToSpine *= -1;
                                                    }

                                                    Console.WriteLine(distanceToSpine + ",");
                                                }
                                            }

                                            for (int i = 1; i < spine.Length; i++)
                                            {
                                                PointF point1 = spine[i - 1];
                                                PointF point2 = spine[i];

                                                point1.X += topCorner.X;
                                                point1.Y += topCorner.Y;
                                                point2.X += topCorner.X;
                                                point2.Y += topCorner.Y;

                                                LineSegment2D line = new LineSegment2D(new Point((int)point1.X, (int)point1.Y), new Point((int)point2.X, (int)point2.Y));
                                                drawImage.Draw(line, new Bgr(Color.Aqua), 2);
                                                tempImage2.Draw(line, new Bgr(Color.Cyan), 2);
                                            }

                                            drawImage.Draw(new CircleF(mouseBlob.Centroid, 2), new Bgr(Color.Blue), 2);
                                            Image3 = ImageService.ToBitmapSource(drawImage);

                                            Image6 = ImageService.ToBitmapSource(tempImage2);

                                            double rotatedRectArea = rotatedRect.Size.Width * rotatedRect.Size.Height;

                                            if (rotatedRectArea < 75000)
                                            {
                                                //Console.WriteLine(rotatedRectArea);
                                                //return;
                                            }
                                            else
                                            {
                                                //Console.WriteLine(rotatedRectArea);
                                            }

                                            double height = rotatedRect.Size.Height;
                                            double width  = rotatedRect.Size.Width;

                                            //double angle = rotatedRect.Angle;
                                            bool heightLong = height > width;

                                            double halfLength;

                                            PointF[] vertices = rotatedRect.GetVertices();

                                            if (heightLong)
                                            {
                                                halfLength = height;
                                            }
                                            else
                                            {
                                                halfLength = width;
                                            }

                                            halfLength /= 2;

                                            PointF[] sidePoints1 = new PointF[4], midPoints = new PointF[2];
                                            PointF   p1 = vertices[0], p2 = vertices[1], p3 = vertices[2], p4 = vertices[3];

                                            double d1 = p1.DistanceSquared(p2);
                                            double d2 = p2.DistanceSquared(p3);

                                            if (d1 < d2)
                                            {
                                                //p1 and p2, p3 and p4 are side points
                                                sidePoints1[0] = p1;
                                                sidePoints1[1] = p2;
                                                sidePoints1[2] = p4;
                                                sidePoints1[3] = p3;

                                                midPoints[0] = p1.MidPoint(p4);
                                                midPoints[1] = p2.MidPoint(p3);
                                            }
                                            else
                                            {
                                                //p2 and p3, p1 and p4 are side points
                                                sidePoints1[0] = p1;
                                                sidePoints1[1] = p4;
                                                sidePoints1[2] = p2;
                                                sidePoints1[3] = p3;

                                                midPoints[0] = p1.MidPoint(p2);
                                                midPoints[1] = p3.MidPoint(p4);
                                            }

                                            PointF intersection1 = PointF.Empty;
                                            PointF intersection2 = PointF.Empty;

                                            using (Image <Gray, Byte> halfTest1 = origGray.CopyBlank())
                                                using (Image <Gray, Byte> halfTest2 = origGray.CopyBlank())
                                                {
                                                    Point[] rect1 = new Point[] { new Point((int)sidePoints1[0].X, (int)sidePoints1[0].Y), new Point((int)midPoints[0].X, (int)midPoints[0].Y), new Point((int)midPoints[1].X, (int)midPoints[1].Y), new Point((int)sidePoints1[1].X, (int)sidePoints1[1].Y) };
                                                    Point[] rect2 = new Point[] { new Point((int)sidePoints1[2].X, (int)sidePoints1[2].Y), new Point((int)midPoints[0].X, (int)midPoints[0].Y), new Point((int)midPoints[1].X, (int)midPoints[1].Y), new Point((int)sidePoints1[3].X, (int)sidePoints1[3].Y) };

                                                    if (MathExtension.PolygonContainsPoint(rect1, center))
                                                    {
                                                        //Rect 1 is head, look for line in r2
                                                    }
                                                    else if (MathExtension.PolygonContainsPoint(rect2, center))
                                                    {
                                                        //Rect 2 is head, look for line in r1
                                                    }
                                                    else
                                                    {
                                                        //Something has gone wrong
                                                    }

                                                    halfTest1.FillConvexPoly(rect1, new Gray(255));
                                                    halfTest2.FillConvexPoly(rect2, new Gray(255));
                                                    //Image5 = ImageService.ToBitmapSource(halfTest1);
                                                    //Image6 = ImageService.ToBitmapSource(halfTest2);

                                                    //binary.Copy(holder1, halfTest1);
                                                    //binary.Copy(holder2, halfTest2);
                                                    int count1, count2;

                                                    //using (Image<Gray, Byte> binaryInverse = subbed.Not())
                                                    using (Image <Gray, Byte> holder1 = subbed.Copy(halfTest1))
                                                        using (Image <Gray, Byte> holder2 = subbed.Copy(halfTest2))
                                                        {
                                                            //Image4 = ImageService.ToBitmapSource(subbed);
                                                            //Image5 = ImageService.ToBitmapSource(holder1);
                                                            //Image6 = ImageService.ToBitmapSource(holder2);

                                                            count1 = holder1.CountNonzero()[0];
                                                            count2 = holder2.CountNonzero()[0];
                                                        }

                                                    PointF qr1 = PointF.Empty, qr2 = PointF.Empty, qr3 = PointF.Empty, qr4 = PointF.Empty;
                                                    if (count1 > count2)
                                                    {
                                                        //holder 1 is head, holder 2 is rear
                                                        qr1 = sidePoints1[2];
                                                        qr2 = sidePoints1[2].MidPoint(midPoints[0]);
                                                        qr3 = sidePoints1[3].MidPoint(midPoints[1]);
                                                        qr4 = sidePoints1[3];
                                                    }
                                                    else if (count1 < count2)
                                                    {
                                                        //holder 2 is head, holder 1 is year
                                                        qr1 = sidePoints1[0];
                                                        qr2 = sidePoints1[0].MidPoint(midPoints[0]);
                                                        qr3 = sidePoints1[1].MidPoint(midPoints[1]);
                                                        qr4 = sidePoints1[1];
                                                    }

                                                    //fat line is qr2, qr3
                                                    PointF centerPoint = qr2.MidPoint(qr3);
                                                    PointF i1          = qr2;
                                                    PointF i2          = qr3;
                                                    intersection1 = MathExtension.PolygonLineIntersectionPoint(centerPoint, i1, mouseContour);
                                                    intersection2 = MathExtension.PolygonLineIntersectionPoint(centerPoint, i2, mouseContour);
                                                }

                                            double deltaX = halfLength * Math.Cos(rotatedRect.Angle * MathExtension.Deg2Rad);
                                            double deltaY = halfLength * Math.Sin(rotatedRect.Angle * MathExtension.Deg2Rad);

                                            const double scaleFactor = 0.25;

                                            PointF   newPoint           = new PointF((float)(center.X - (deltaX * scaleFactor)), (float)(center.Y - (deltaY * scaleFactor)));
                                            PointF   intersectionPoint1 = PointF.Empty;
                                            PointF   intersectionPoint2 = PointF.Empty;
                                            Point[]  temp       = null;
                                            PointF[] headPoints = RBSKService.RBSKParallel(binary, MouseService.GetStandardMouseRules(), ref temp);
                                            if (headPoints != null)
                                            {
                                                PointF tip = headPoints[2];
                                                //targetPoints = new LineSegment2DF[3];
                                                Point centerInt = new Point((int)newPoint.X, (int)newPoint.Y);
                                                //targetPoints[0] = new LineSegment2DF(centerInt, new PointF(tip.X, tip.Y));
                                                Vector forwardVec = new Vector(tip.X - newPoint.X, tip.Y - newPoint.Y);
                                                Vector rotatedVec = new Vector(-forwardVec.Y, forwardVec.X);

                                                PointF i1 = new PointF((float)(newPoint.X + (rotatedVec.X * 1)), (float)(newPoint.Y + (rotatedVec.Y * 1)));
                                                PointF i2 = new PointF((float)(newPoint.X - (rotatedVec.X * 1)), (float)(newPoint.Y - (rotatedVec.Y * 1)));
                                                //targetPoints[1] = new LineSegment2DF(centerInt, i1);
                                                //targetPoints[2] = new LineSegment2DF(centerInt, i2);
                                                intersectionPoint1 = MathExtension.PolygonLineIntersectionPoint(newPoint, i1, mouseContour);
                                                intersectionPoint2 = MathExtension.PolygonLineIntersectionPoint(newPoint, i2, mouseContour);
                                            }



                                            //displayImage.Draw(mouseBlob.BoundingBox, new Bgr(Color.Red), 2);
                                            displayImage.Draw(new CircleF(mouseBlob.Centroid, 3), new Bgr(Color.Blue), 2);

                                            displayImage.Draw(rotatedRect, new Bgr(Color.Yellow), 3);
                                            //displayImage.Draw(mouseContour, new Bgr(Color.Aqua), 2);
                                            //displayImage.FillConvexPoly(new Point[] { new Point((int)sidePoints1[0].X, (int)sidePoints1[0].Y), new Point((int)midPoints[0].X, (int)midPoints[0].Y), new Point((int)midPoints[1].X, (int)midPoints[1].Y), new Point((int)sidePoints1[1].X, (int)sidePoints1[1].Y) }, new Bgr(Color.Blue));
                                            //if (targetPoints != null)
                                            //{
                                            //    displayImage.Draw(targetPoints[0], new Bgr(Color.Green), 2);
                                            //    displayImage.Draw(targetPoints[1], new Bgr(Color.Green), 2);
                                            //    displayImage.Draw(targetPoints[2], new Bgr(Color.Green), 2);
                                            //}

                                            //if (!intersection1.IsEmpty && !intersection2.IsEmpty)
                                            //{
                                            //    LineSegment2DF lineSegment = new LineSegment2DF(intersection1, intersection2);
                                            //    displayImage.Draw(lineSegment, new Bgr(Color.MediumPurple), 4);
                                            //    //Console.WriteLine(lineSegment.Length);
                                            //}

                                            //displayImage.Draw(new CircleF(newPoint, 4), new Bgr(Color.MediumPurple), 3);

                                            //Console.WriteLine(rotatedRect.Angle);
                                            Image4 = ImageService.ToBitmapSource(displayImage);
                                        }
                        }
        }
Exemplo n.º 3
0
        private LineSegment2D[] FindSpine(LineSegment2D[] lines, RotatedRect rotatedRectangle, Image <Gray, Byte> img, PointF headPoint, PointF tailPoint)
        {
            //LineSegment2DF[] initialLines = new LineSegment2DF[2];

            //if (!rotatedRectangle.Size.IsEmpty)
            //{
            //    //Use one of the smaller boundries from rotatedRect for initial detection
            //    PointF[] vertices = rotatedRectangle.GetVertices();
            //    PointF p1 = vertices[0];
            //    PointF p2 = vertices[1];
            //    PointF p3 = vertices[2];
            //    PointF p4 = vertices[3];

            //    //PointF p1 = new PointF(rotatedRectangle.Left, rotatedRectangle.Top);
            //    //PointF p2 = new PointF(rotatedRectangle.Left, rotatedRectangle.Bottom);
            //    //PointF p3 = new PointF(rotatedRectangle.Right, rotatedRectangle.Bottom);
            //    //PointF p4 = new PointF(rotatedRectangle.Right, rotatedRectangle.Top);

            //    if (p2.DistanceSquared(p1) < p2.DistanceSquared(p3))
            //    {
            //        //p1 and p2 are paired, p3 and p4 are paired
            //        initialLines[0] = new LineSegment2DF(p1, p2);
            //        initialLines[1] = new LineSegment2DF(p3, p4);
            //    }
            //    else
            //    {
            //        //p2 and p3 are paired, p1 and p4 are paired
            //        initialLines[0] = new LineSegment2DF(p2, p3);
            //        initialLines[1] = new LineSegment2DF(p1, p4);
            //    }
            //}
            //else
            //{
            //    //Use one of the image sides for intial detection
            //    initialLines[1] = new LineSegment2DF(new PointF(0, 0), new PointF(0, img.Height - 1));
            //    initialLines[0] = new LineSegment2DF(new PointF(img.Width - 1, 0), new PointF(img.Width - 1, img.Height - 1));
            //    //initialLines[0] = new LineSegment2DF(new PointF(0, 0), new PointF(img.Width - 1, 0));
            //    //initialLines[1] = new LineSegment2DF(new PointF(0 - 1, img.Height-1), new PointF(img.Width - 1, img.Height - 1));
            //}

            //Find closest line segment to initial line
            double minDistance = double.MaxValue;

            LineSegment2D?targetLine = null;

            foreach (LineSegment2D line in lines)
            {
                //double minDistance1 = MathExtension.MinDistanceFromLineToPoint(initialLines[0].P1, initialLines[0].P2, line.P1);
                //double minDistance2 = MathExtension.MinDistanceFromLineToPoint(initialLines[0].P1, initialLines[0].P2, line.P2);

                double minDistance1 = headPoint.DistanceSquared(line.P1);
                double minDistance2 = headPoint.DistanceSquared(line.P2);

                double currentDist = minDistance1 < minDistance2 ? minDistance1 : minDistance2;

                if (currentDist < minDistance)
                {
                    minDistance = currentDist;
                    targetLine  = line;
                }
            }

            List <LineSegment2D> previousLines = new List <LineSegment2D>();

            //We have our target line, try to traverse to the other side
            LineSegment2D?nextLine = null;

            if (targetLine.HasValue)
            {
                previousLines.Add(targetLine.Value);
            }

            do
            {
                GetValue(lines, tailPoint, previousLines.ToArray(), targetLine, ref nextLine);

                if (nextLine.HasValue)
                {
                    targetLine = nextLine;
                    previousLines.Add(nextLine.Value);
                }
            }while (nextLine.HasValue);

            if (previousLines.Count == 0)
            {
                return(null);
            }

            double minDistanceFromEnd1 = tailPoint.Distance(previousLines.Last().P1); //MathExtension.MinDistanceFromLineToPoint(initialLines[1].P1, initialLines[1].P2, previousLines.Last().P1));
            double minDistanceFromEnd2 = tailPoint.Distance(previousLines.Last().P2); //MathExtension.MinDistanceFromLineToPoint(initialLines[1].P1, initialLines[1].P2, previousLines.Last().P2);

            if (minDistanceFromEnd1 < 30 || minDistanceFromEnd2 < 30)
            {
                //Made it!
                return(previousLines.ToArray());
            }

            minDistance = double.MaxValue;

            targetLine = null;
            foreach (var line in lines)
            {
                double minDistance1 = tailPoint.Distance(line.P1); //MathExtension.MinDistanceFromLineToPoint(initialLines[1].P1, initialLines[1].P2, line.P1));
                double minDistance2 = tailPoint.Distance(line.P2); //MathExtension.MinDistanceFromLineToPoint(initialLines[1].P1, initialLines[1].P2, line.P2));

                double currentDist = minDistance1 < minDistance2 ? minDistance1 : minDistance2;

                if (currentDist < minDistance)
                {
                    minDistance = currentDist;
                    targetLine  = line;
                }
            }


            List <LineSegment2D> previousLines2 = new List <LineSegment2D>();

            //We have our target line, try to traverse to the other side
            nextLine = null;
            if (targetLine.HasValue)
            {
                previousLines2.Add(targetLine.Value);
            }

            do
            {
                GetValue(lines, headPoint, previousLines2.ToArray(), targetLine, ref nextLine);

                if (nextLine.HasValue)
                {
                    targetLine = nextLine;
                    previousLines2.Add(nextLine.Value);
                }
            }while (nextLine.HasValue);

            previousLines2.Reverse();
            previousLines.AddRange(previousLines2);

            return(previousLines.ToArray());
        }
Exemplo n.º 4
0
        private void FindSpine(LineSegment2D[] lines, RotatedRect rotatedRectangle, Image <Gray, Byte> img)
        {
            LineSegment2DF[] initialLines = new LineSegment2DF[2];

            if (!rotatedRectangle.Size.IsEmpty)
            {
                //Use one of the smaller boundries from rotatedRect for initial detection
                PointF[] vertices = rotatedRectangle.GetVertices();
                PointF   p1       = vertices[0];
                PointF   p2       = vertices[1];
                PointF   p3       = vertices[2];
                PointF   p4       = vertices[3];

                if (p2.DistanceSquared(p1) < p2.DistanceSquared(p3))
                {
                    //p1 and p2 are paired, p3 and p4 are paired
                    initialLines[0] = new LineSegment2DF(p1, p2);
                    initialLines[1] = new LineSegment2DF(p3, p4);
                }
                else
                {
                    //p2 and p3 are paired, p1 and p4 are paired
                    initialLines[0] = new LineSegment2DF(p2, p3);
                    initialLines[1] = new LineSegment2DF(p1, p4);
                }
            }
            else
            {
                //Use one of the image sides for intial detection
                initialLines[0] = new LineSegment2DF(new PointF(0, 0), new PointF(0, img.Height - 1));
                initialLines[1] = new LineSegment2DF(new PointF(img.Width - 1, 0), new PointF(img.Width - 1, img.Height - 1));
            }

            //Find closest line segment to initial line
            double minDistance = double.MaxValue;

            LineSegment2D?targetLine = null;

            foreach (var line in lines)
            {
                double minDistance1 = MathExtension.MinDistanceFromLineToPoint(initialLines[0].P1, initialLines[0].P2, line.P1);
                double minDistance2 = MathExtension.MinDistanceFromLineToPoint(initialLines[0].P1, initialLines[0].P2, line.P2);

                double currentDist = minDistance1 < minDistance2 ? minDistance1 : minDistance2;

                if (currentDist < minDistance)
                {
                    minDistance = currentDist;
                    targetLine  = line;
                }
            }
            List <LineSegment2D> previousLines = new List <LineSegment2D>();

            //We have our target line, try to traverse to the other side
            LineSegment2D?nextLine = null;

            Image <Bgr, Byte> moddedImage = img.Convert <Bgr, Byte>();

            if (targetLine.HasValue)
            {
                previousLines.Add(targetLine.Value);

                //We have a starting position, lets test it!
                moddedImage.Draw(targetLine.Value, new Bgr(Color.Red), 2);
            }

            do
            {
                GetValue(lines, initialLines[1], previousLines.ToArray(), targetLine, ref nextLine);

                if (nextLine.HasValue)
                {
                    targetLine = nextLine;
                    previousLines.Add(nextLine.Value);
                    moddedImage.Draw(nextLine.Value, new Bgr(Color.Red), 2);
                }
            }while (nextLine.HasValue);

            DisplayImage3 = ImageService.ToBitmapSource(moddedImage);
        }
Exemplo n.º 5
0
        public static Point[] GetSegmentOfPolygon(Point[] polygon, PointF p1, PointF p2)
        {
            List <Point> points = new List <Point>();

            double startMin = Double.MaxValue, endMin = Double.MaxValue;

            int startIndex = 0, endIndex = 0;

            int counter = 0;

            foreach (Point point in polygon)
            {
                double p1Dist = p1.DistanceSquared(point);
                if (p1Dist < startMin)
                {
                    startMin   = p1Dist;
                    startIndex = counter;
                }

                double p2Dist = p2.DistanceSquared(point);
                if (p2Dist < endMin)
                {
                    endMin   = p2Dist;
                    endIndex = counter;
                }

                counter++;
            }

            bool searchLeft = true, searchRight = true;

            //bool goLeft = false;
            counter = startIndex;
            Point  previousPoint = polygon[startIndex];
            double distCounter1  = 0;

            while (searchLeft)
            {
                counter--;

                if (counter < 0)
                {
                    counter = polygon.Length - 1;
                }

                Point currentPoint = polygon[counter];

                distCounter1 += currentPoint.DistanceSquared(previousPoint);

                if (currentPoint == polygon[endIndex])
                {
                    searchLeft = false;
                }
            }

            counter       = startIndex;
            previousPoint = polygon[startIndex];
            double distCounter2 = 0;

            while (searchRight)
            {
                counter++;

                if (counter >= polygon.Length)
                {
                    counter = 0;
                }

                Point currentPoint = polygon[counter];

                distCounter2 += currentPoint.DistanceSquared(previousPoint);

                if (currentPoint == polygon[endIndex])
                {
                    searchRight = false;
                }
            }

            if (distCounter1 < distCounter2)
            {
                //Go left
                int index = startIndex;
                while (true)
                {
                    if (index == endIndex)
                    {
                        break;
                    }

                    points.Add(polygon[index]);
                    index--;

                    if (index < 0)
                    {
                        index = polygon.Length - 1;
                    }
                }
            }
            else
            {
                //Go right
                int index = startIndex;
                while (true)
                {
                    if (index == endIndex)
                    {
                        break;
                    }

                    points.Add(polygon[index]);
                    index++;

                    if (index >= polygon.Length)
                    {
                        index = 0;
                    }
                }
            }

            return(points.ToArray());
        }