Beispiel #1
1
 public void TestMethod1()
 {
     var line = new LineSegment2D(new Point(1, 1), new Point(3, 3));
     Assert.IsTrue(line.Distance(new Point(1, 0)) - 1/Math.Sqrt(2) < Epsilon);
     Assert.IsTrue(line.Distance(new Point(0, 0)) < Epsilon);
     Assert.IsTrue(line.Distance(new Point(0, 4)) - 2*Math.Sqrt(2) < Epsilon);
 }
Beispiel #2
0
 public static bool OneLineClose(LineSegment2D segment1, LineSegment2D segment2)
 {
     const double eps = 10.0;
     var d1 = DistanceHelper.LineToPointDistance2D(segment1.P1, segment1.P2, segment2.P1);
     var d2 = DistanceHelper.LineToPointDistance2D(segment1.P1, segment1.P2, segment2.P2);
     var d3 = DistanceHelper.LineToPointDistance2D(segment2.P1, segment2.P2, segment1.P1);
     var d4 = DistanceHelper.LineToPointDistance2D(segment2.P1, segment2.P2, segment1.P2);
     return d1 < eps || d2 < eps || d3 < eps || d4 < eps;
 }
Beispiel #3
0
 public static void draw3LineFromList(Image<Bgr, Byte> img, List<Point> l)
 {
     LineSegment2D line1 = new LineSegment2D(l[0], l[1]);
     LineSegment2D line2 = new LineSegment2D(l[2], l[3]);
     LineSegment2D line3 = new LineSegment2D(l[4], l[5]);
     img.Draw(line1, new Bgr(255, 0, 0), 3);
     img.Draw(line2, new Bgr(0, 255, 0), 3);
     img.Draw(line3, new Bgr(0, 0, 255), 3);
 }
Beispiel #4
0
 /// <summary>
 /// Get the exterior angle between this line and <paramref name="otherLine"/>
 /// </summary>
 /// <param name="otherLine">The other line</param>
 /// <returns>The exterior angle between this line and <paramref name="otherLine"/></returns>
 public double GetExteriorAngleDegree(LineSegment2D otherLine)
 {
    PointF direction1 = Direction;
    PointF direction2 = otherLine.Direction;
    double radianAngle = Math.Atan2(direction2.Y, direction2.X) - Math.Atan2(direction1.Y, direction1.X);
    double degreeAngle = radianAngle * (180.0 / Math.PI);
    return
        degreeAngle <= -180.0 ? degreeAngle + 360 :
        degreeAngle > 180.0 ? degreeAngle - 360 :
        degreeAngle;
 }
Beispiel #5
0
        /// <summary>
        /// Get the exterior angle between this line and <paramref name="otherLine"/>
        /// </summary>
        /// <param name="otherLine">The other line</param>
        /// <returns>The exterior angle between this line and <paramref name="otherLine"/></returns>
        public double GetExteriorAngleDegree(LineSegment2D otherLine)
        {
            PointF direction1  = Direction;
            PointF direction2  = otherLine.Direction;
            double radianAngle = Math.Atan2(direction2.Y, direction2.X) - Math.Atan2(direction1.Y, direction1.X);
            double degreeAngle = radianAngle * (180.0 / Math.PI);

            return
                (degreeAngle <= -180.0 ? degreeAngle + 360 :
                 degreeAngle > 180.0 ? degreeAngle - 360 :
                 degreeAngle);
        }
        public static FeatureVector createFirstHypothesis(Image<Bgr, Byte> imagen)
        {
            List<PointF> fingertips = new List<PointF>();

               fingertips.Add(new PointF(110,220));
               fingertips.Add(new PointF(175, 60));
               fingertips.Add(new PointF(270, 4));
               fingertips.Add(new PointF(410, 26));
               fingertips.Add(new PointF(640, 200));

               PointF punto = new PointF(400, 400);
               //List<PointF> newFingertips = new List<PointF>();
               List<float> angles = calculateFingerAngles(fingertips, punto);

               FeatureVector vector = new FeatureVector(fingertips, angles, punto, 5);

               //dibujar punto central mano
               PointF puntoC = new PointF(400, 400);
               Point punt = new Point(400, 400);
               CircleF centerCircle = new CircleF(puntoC, 5f);
               imagen.Draw(centerCircle, new Bgr(Color.Brown), 3);

               foreach (PointF p in fingertips)
               {

               CircleF circle = new CircleF(p, 5f);

               imagen.Draw(circle, new Bgr(Color.Red), 3);

               Point pun = new Point(int.Parse(p.X.ToString()), int.Parse(p.Y.ToString()));
               LineSegment2D lineaDedoCentro = new LineSegment2D(pun, punt);
               imagen.Draw(lineaDedoCentro, new Bgr(Color.Green), 2);

               }

               Point p1 = new Point(int.Parse((puntoC.X - 90).ToString()), int.Parse((puntoC.Y - 90).ToString()));
               Point p2 = new Point(int.Parse((puntoC.X - 90).ToString()), int.Parse((puntoC.Y + 90).ToString()));
               Point p3 = new Point(int.Parse((puntoC.X + 90).ToString()), int.Parse((puntoC.Y - 90).ToString()));
               Point p4 = new Point(int.Parse((puntoC.X + 90).ToString()), int.Parse((puntoC.Y + 90).ToString()));

               LineSegment2D line = new LineSegment2D(p1, p2);
               LineSegment2D line1 = new LineSegment2D(p1, p3);
               LineSegment2D line2 = new LineSegment2D(p3, p4);
               LineSegment2D line3 = new LineSegment2D(p2, p4);

               imagen.Draw(line, new Bgr(Color.Brown), 3);
               imagen.Draw(line1, new Bgr(Color.Brown), 3);
               imagen.Draw(line2, new Bgr(Color.Brown), 3);
               imagen.Draw(line3, new Bgr(Color.Brown), 3);

               return vector;
        }
Beispiel #7
0
        public static bool DistanceClose(LineSegment2D segment1, LineSegment2D segment2, bool checkIntersection = false)
        {
            const double eps = 35.0;

            var d1 = DistanceHelper.SegmentToPointDistance2D(segment1, segment2.P1);
            var d2 = DistanceHelper.SegmentToPointDistance2D(segment1, segment2.P2);
            var d3 = DistanceHelper.SegmentToPointDistance2D(segment2, segment1.P1);
            var d4 = DistanceHelper.SegmentToPointDistance2D(segment2, segment1.P2);
            if (d1 < eps || d2 < eps || d3 < eps || d4 < eps)
                return true;
            if (checkIntersection && DistanceHelper.IsIntersect(segment1, segment2))
                return true;
            return false;
        }
Beispiel #8
0
        public static LineSegment2D MergeSegments(LineSegment2D[] segments)
        {
            var points = segments.Select(s => s.P1).Union(segments.Select(s => s.P2)).ToArray();

            var a = (double) points.Length*points.Sum(p => p.X*p.Y) - points.Sum(p => p.X)*points.Sum(p => p.Y);
            a /= points.Length*points.Sum(p => p.X*p.X) - Math.Pow(points.Sum(p => p.X), 2);
            var b = (points.Sum(p => p.Y) - a*points.Sum(p => p.X))/points.Length;

            var y1 = points.Min(p => p.Y);
            var y2 = points.Max(p => p.Y);
            var x1 = (int) ((y1 - b)/a);
            var x2 = (int) ((y2 - b)/a);

            return new LineSegment2D(new Point(x1, y1), new Point(x2, y2));
        }
        internal void BuildLineSets(LineSegment2D[] vertLines, LineSegment2D[]  horizLines,
            double vertTol, double horizTol)
        {
            const double MINLENGTH = 30.0;
            //const double ANGLETOLHORIZ = ; //;
            //const double ANGLETOLVERT = ;  // Math.PI / 10.0;

            HorizLines = horizLines.Where(line => GetAngle(line) < horizTol && GetAngle(line) > -horizTol).
                Where(x => x.Length > MINLENGTH).
                OrderBy(x => x.P1.Y).ToArray();

            VertLines = vertLines.Where(line => GetAngle(line) > (Math.PI / 2) - vertTol || GetAngle(line) < -(Math.PI / 2) + vertTol).
                Where(x => x.Length > MINLENGTH).
                OrderBy(x => x.P1.X).ToArray();
        }
Beispiel #10
0
        public static bool IsIntersect(LineSegment2D segment1, LineSegment2D segment2)
        {
            // Get the segments' parameters.
            float dx12 = segment1.P2.X - segment1.P1.X;
            float dy12 = segment1.P2.Y - segment1.P1.Y;
            float dx34 = segment2.P2.X - segment2.P1.X;
            float dy34 = segment2.P2.Y - segment2.P1.Y;

            // Solve for t1 and t2
            var denominator = (dy12*dx34 - dx12*dy34);
            var t1 = ((segment1.P1.X - segment2.P1.X)*dy34 + (segment2.P1.Y - segment1.P1.Y)*dx34)/denominator;
            if (float.IsInfinity(t1))
            {
                return false;
            }
            return true;
        }
Beispiel #11
0
        public static void ProcessCarDetectionTest()
        {
            var image = new Image<Gray, byte>("Images/disparity.png");

            var left = new LineSegment2D(new Point(61, 221), new Point(121, 175));
            var right = new LineSegment2D(new Point(253, 221), new Point(209, 175));

            ////*****draw lines*****
            //var red = new Bgr(Color.Red);
            //image.Draw(left, red, 1);
            //image.Draw(right, red, 1);

            var original = CalculateHistogram(image);
            var cutted = new float[256];
            Array.Copy(original, cutted, 256);

            var windows = WindowFlow.Compute(image.Size, new[] {left, right});
            var allValues = new List<float[]>();

            int counter = 0;
            foreach (var window in windows)
            {
                counter++;
                image.ROI = window;
                var values = CalculateHistogram(image);
                for (var i = 0; i < original.Length; ++i)
                {
                    if (original[i] > 0)
                        values[i] = (original[i] - values[i])/original[i];
                    else
                        values[i] = 1.0f;
                }
                if (AnalyzeHistogram(values))
                {
                    Console.WriteLine(counter);
                }

                allValues.Add(values);
            }

            //PrintData(allValues);

            //ImageViewer.Show(image);
        }
Beispiel #12
0
 public LineHistory FindParent(LineSegment2D segment)
 {
     for (var i = 1; i < ClearLevel; ++i)
     {
         var levelLines = levels_[i];
         foreach (var element in levelLines.Where(l => !l.HasChild))
         {
             var avgDirection = element.GetAverageDirection();
             if (SegmentHelper.DirectionClose(avgDirection, segment.Direction))
             {
                 if (SegmentHelper.DistanceClose(element.Segment, segment, true))
                 {
                     return element;
                 }
             }
         }
     }
     return null;
 }
        // Détecte et dessine le nombre de doigts sur l'image traitée
        // Ce code vient en partie de ce projet : https://www.youtube.com/watch?v=Fjj9gqTCTfc
        public void DrawAndComputeFingers()
        {
            fingerNum = 0;

            // Boucle sur tous les "defects"
            for (int i = 0; i < defects.Total; i++)
            {
                // Détecte les points de départ, de fin et de profondeur
                PointF startPoint = new PointF((float)defectArray[i].StartPoint.X,
                                                (float)defectArray[i].StartPoint.Y);
                PointF depthPoint = new PointF((float)defectArray[i].DepthPoint.X,
                                                (float)defectArray[i].DepthPoint.Y);
                PointF endPoint = new PointF((float)defectArray[i].EndPoint.X,
                                                (float)defectArray[i].EndPoint.Y);

                // Lignes entre les différents points (départ - profondeur, profondeur - fin)
                LineSegment2D startDepthLine = new LineSegment2D(defectArray[i].StartPoint, defectArray[i].DepthPoint);
                LineSegment2D depthEndLine = new LineSegment2D(defectArray[i].DepthPoint, defectArray[i].EndPoint);

                // Cercles liés aux points de départ, profondeur et fin
                CircleF startCircle = new CircleF(startPoint, 5f);
                CircleF depthCircle = new CircleF(depthPoint, 5f);
                CircleF endCircle = new CircleF(endPoint, 5f);

                // Heuristique personnalisée d'après diverses expériences pour détecter si il s'agit d'un doigt ou non, d'après la position des points de départ, de profondeur et de fin et la taille de la box qui les contient
                if ((startCircle.Center.Y < box.center.Y || depthCircle.Center.Y < box.center.Y) && (startCircle.Center.Y < depthCircle.Center.Y) && (Math.Sqrt(Math.Pow(startCircle.Center.X - depthCircle.Center.X, 2) + Math.Pow(startCircle.Center.Y - depthCircle.Center.Y, 2)) > box.size.Height / 6.5))
                {
                    fingerNum++;
                    imgProc.Draw(startDepthLine, new Bgr(Color.Green), 2);
                }

                // Dessine les différents points
                imgProc.Draw(startCircle, new Bgr(Color.Red), 2);
                imgProc.Draw(depthCircle, new Bgr(Color.Yellow), 5);
                imgProc.Draw(endCircle, new Bgr(Color.DarkBlue), 4);
            }
        }
Beispiel #14
0
        private static List<Tuple<PointF, List<LineSegment2D>>> GroupDirectionSerment(LineSegment2D[] segments)
        {
            var chunks = new List<Tuple<PointF, List<LineSegment2D>>>();
            foreach (var segment in segments)
            {
                var direction = segment.Direction.X >= 0
                    ? new PointF(segment.Direction.X, segment.Direction.Y)
                    : new PointF(-segment.Direction.X, -segment.Direction.Y);
                var isMerged = false;
                foreach (var chunk in chunks)
                {
                    var chunkDirection = chunk.Item1;
                    if (SegmentHelper.DirectionClose(chunkDirection, segment.Direction))
                    {
                        isMerged = true;
                        chunks.Remove(chunk);
                        var chunkItems = chunk.Item2;
                        chunkItems.Add(segment);

                        var weight = 1.0f/chunkItems.Count;
                        //all

                        direction = new PointF(chunkDirection.X*(1 - weight) + direction.X*weight,
                            chunkDirection.Y*(1 - weight) + direction.Y*weight);
                        var norm = (float) Math.Sqrt(direction.X*direction.X + direction.Y*direction.Y);
                        direction = new PointF(direction.X/norm, direction.Y/norm);
                        chunks.Add(new Tuple<PointF, List<LineSegment2D>>(direction, chunkItems));
                        break;
                    }
                }
                if (!isMerged)
                    chunks.Add(new Tuple<PointF, List<LineSegment2D>>(direction, new List<LineSegment2D> {segment}));
            }
            return chunks;
        }
        private void btnMAP_Click(object sender, EventArgs e)
        {
            while (MAPestimationOperations.definiteL > 35)
            {

                FeatureVector newVector = MAPestimationOperations.core(observedImageVector, hypothesisImageVector);
                hypothesisImageVector = newVector;

                // imagen2 = imagen2copia;
                //imgCaja2.Image = imagen2;
                // imgCaja2.Refresh();

                label1.Text = "L = " + MAPestimationOperations.definiteL.ToString();

                label1.Refresh();

                imagen2 = new Image<Bgr, byte>(archivo);
                imgCaja2.Image = imagen2;

                PointF puntoC = hypothesisImageVector.PalmCenter; ;
                Point punt = new Point(int.Parse(puntoC.X.ToString()), int.Parse(puntoC.Y.ToString()));
                CircleF centerCircle = new CircleF(puntoC, 5f);
                imagen2.Draw(centerCircle, new Bgr(Color.Brown), 3);

                Point p1 = new Point(int.Parse((hypothesisImageVector.PalmCenter.X - 90).ToString()), int.Parse((hypothesisImageVector.PalmCenter.Y - 90).ToString()));
                Point p2 = new Point(int.Parse((hypothesisImageVector.PalmCenter.X - 90).ToString()), int.Parse((hypothesisImageVector.PalmCenter.Y + 90).ToString()));
                Point p3 = new Point(int.Parse((hypothesisImageVector.PalmCenter.X + 90).ToString()), int.Parse((hypothesisImageVector.PalmCenter.Y - 90).ToString()));
                Point p4 = new Point(int.Parse((hypothesisImageVector.PalmCenter.X + 90).ToString()), int.Parse((hypothesisImageVector.PalmCenter.Y + 90).ToString()));

                LineSegment2D line = new LineSegment2D(p1,p2);
                LineSegment2D line1 = new LineSegment2D(p1,p3);
                LineSegment2D line2 = new LineSegment2D(p3, p4);
                LineSegment2D line3 = new LineSegment2D(p2, p4);

                imagen2.Draw(line, new Bgr(Color.Brown), 3);
                imagen2.Draw(line1, new Bgr(Color.Brown), 3);
                imagen2.Draw(line2, new Bgr(Color.Brown), 3);
                imagen2.Draw(line3, new Bgr(Color.Brown), 3);

                List<PointF> fingertips = new List<PointF>();

                fingertips.Add(hypothesisImageVector.LocationThumb);
                fingertips.Add(hypothesisImageVector.LocationIndexFinger);
                fingertips.Add(hypothesisImageVector.LocationHeartFinger);
                fingertips.Add(hypothesisImageVector.Location4Finger);
                fingertips.Add(hypothesisImageVector.LocationLittleFinger);

                foreach (PointF p in fingertips)
                {

                    CircleF circle = new CircleF(p, 5f);

                    imagen2.Draw(circle, new Bgr(Color.Red), 3);

                    Point pun = new Point(int.Parse(p.X.ToString()), int.Parse(p.Y.ToString()));
                    LineSegment2D lineaDedoCentro = new LineSegment2D(pun, punt);
                    imagen2.Draw(lineaDedoCentro, new Bgr(Color.Green), 2);

                    imgCaja2.Refresh();
                }

            }

            MessageBox.Show("Done!");
        }
 public int getDigitFromCode(CircleF circle, LineSegment2D[] pReferenceLines)
 {
     // remember that the first reference line is the horizontal one ,so we do not consider the line in this porocess
     return binarySearch((int)circle.Center.X, pReferenceLines, (pReferenceLines.Count() - 2) / 2);
 }
        /*
        public LineSegment2D[] getAnswerReferenceLines(Image<Bgr, Byte> img)
        {
            int scala = 2;
            int totalLines = 47;
            int desface = 172 * scala;
            int horizontalLineSpace = 131 * scala;
            LineSegment2D[] referencesLines = new LineSegment2D[totalLines];
            if (img != null)
            {
                //getting VERTICAL lines for answers
                for (int i = 0; i < 5; i++)
                {
                    LineSegment2D line = makeLine(desface + (i * horizontalLineSpace),
                                                 0,
                                                 desface + (i * horizontalLineSpace),
                                                 img.Height);
                    referencesLines[i] = line;
                }

                //getting HORIZONTAL lines for answers

                int inicio = (int)(img.Height / 3.55) - 15;
                int espacio = 212;

                for (int i = 0; i < 7; i++)
                {
                    if (i == 0) horizontalDesfase_Y_1 = inicio + espacio * i;
                    if (i == 1) horizontalDesfase_Y_2 = inicio + espacio * i + 1;
                    if (i == 2) horizontalDesfase_Y_3 = inicio + espacio * i + 3;
                    if (i == 3) horizontalDesfase_Y_4 = inicio + espacio * i + 5;
                    if (i == 4) horizontalDesfase_Y_5 = inicio + espacio * i + 8;
                    if (i == 5) horizontalDesfase_Y_6 = inicio + espacio * i + 10;
                    if (i == 6) horizontalDesfase_Y_7 = inicio + espacio * i + 12;
                }

                int horizontalWidth = 38;
                for (int i = 5; i < totalLines; i++)
                {
                    int indice = (i - 5);

                    if (indice < 6)
                    {
                        LineSegment2D line = makeLine(0,
                                                    horizontalDesfase_Y_1 + indice * horizontalWidth,
                                                     img.Width,
                                                     horizontalDesfase_Y_1 + indice * horizontalWidth);
                        referencesLines[i] = line;
                    }
                    else
                    {
                        if (indice < 12)
                        {
                            indice -= 6;
                            LineSegment2D line = makeLine(0,
                                                        horizontalDesfase_Y_2 + indice * horizontalWidth,
                                                         img.Width,
                                                         horizontalDesfase_Y_2 + indice * horizontalWidth);
                            referencesLines[i] = line;
                        }
                        else
                        {
                            if (indice < 18)
                            {
                                indice -= 12;
                                LineSegment2D line = makeLine(0,
                                                            horizontalDesfase_Y_3 + indice * horizontalWidth,
                                                             img.Width,
                                                             horizontalDesfase_Y_3 + indice * horizontalWidth);
                                referencesLines[i] = line;
                            }
                            else
                            {
                                if (indice < 24)
                                {
                                    indice -= 18;
                                    LineSegment2D line = makeLine(0,
                                                                horizontalDesfase_Y_4 + indice * horizontalWidth,
                                                                 img.Width,
                                                                 horizontalDesfase_Y_4 + indice * horizontalWidth);
                                    referencesLines[i] = line;
                                }
                                else
                                {
                                    if (indice < 30)
                                    {
                                        indice -= 24;
                                        LineSegment2D line = makeLine(0,
                                                                    horizontalDesfase_Y_5 + indice * horizontalWidth,
                                                                     img.Width,
                                                                     horizontalDesfase_Y_5 + indice * horizontalWidth);
                                        referencesLines[i] = line;
                                    }
                                    else
                                    {
                                        if (indice < 36)
                                        {
                                            indice -= 30;
                                            LineSegment2D line = makeLine(0,
                                                                        horizontalDesfase_Y_6 + indice * horizontalWidth,
                                                                         img.Width,
                                                                         horizontalDesfase_Y_6 + indice * horizontalWidth);
                                            referencesLines[i] = line;
                                        }
                                        else
                                        {
                                            indice -= 36;
                                            LineSegment2D line = makeLine(0,
                                                                        horizontalDesfase_Y_7 + indice * horizontalWidth,
                                                                         img.Width,
                                                                         horizontalDesfase_Y_7 + indice * horizontalWidth);
                                            referencesLines[i] = line;
                                        }
                                    }
                                }
                            }
                        }
                    }

                }
            }

            return referencesLines;
        }
        */
        public LineSegment2D[] getCodeNumberReferenceLines(Image<Bgr, Byte> pImg)
        {
            int scala = 2;

            int totalLines = 13;
            int verticalDesface = 406 * scala;
            int horizontalDesfase_Y = (int)(pImg.Height / 4.55);
            int spaceBtwVerticallines = 26 * scala;

            LineSegment2D[] verticallReferencesLines = new LineSegment2D[totalLines];
            if (pImg != null)
            {

                //first is HORIZONTAL referece line for getting the codes discrimination
                Point p1 = new Point(0, (int)(horizontalDesfase_Y / 1.5));
                Point p2 = new Point((int)pImg.Width, (int)(horizontalDesfase_Y / 1.5));
                LineSegment2D l = new LineSegment2D(p1, p2);

                verticallReferencesLines[0] = l;

                //Second is HORIZONTAL referece line for getting the codes discrimination
                p1 = new Point(0, horizontalDesfase_Y);
                p2 = new Point((int)pImg.Width, horizontalDesfase_Y);
                l = new LineSegment2D(p1, p2);

                verticallReferencesLines[1] = l;

                //referece lines for codes
                for (int i = 2; i < totalLines; i++)
                {
                    LineSegment2D line = makeLine(verticalDesface + (i * spaceBtwVerticallines),
                                                 120,
                                                 verticalDesface + (i * spaceBtwVerticallines),
                                                 horizontalDesfase_Y);
                    verticallReferencesLines[i] = line;
                }

            }

            return verticallReferencesLines;
        }
        public LineSegment2D[] getAnswerReferenceLines(Image<Bgr, Byte> img)
        {
            int scala = 2;
            int totalLines = 47;
            int desface = 172 * scala;
            int horizontalLineSpace = 131 * scala;
            LineSegment2D[] referencesLines = new LineSegment2D[totalLines];
            if (img != null)
            {
                //getting VERTICAL lines for answers
                for (int i = 0; i < 5; i++)
                {
                    LineSegment2D line = makeLine(desface + (i * horizontalLineSpace),
                                                 0,
                                                 desface + (i * horizontalLineSpace),
                                                 img.Height);
                    referencesLines[i] = line;
                }

                //getting HORIZONTAL lines for answers

                int inicio = (int)(img.Height / 3.55) - 15;
                int espacio = 212;

                for (int i = 0; i < 7; i++)
                {
                    if (i == 0) horizontalDesfase_Y_1 = inicio + espacio * i;
                    if (i == 1) horizontalDesfase_Y_2 = inicio + espacio * i + 1;
                    if (i == 2) horizontalDesfase_Y_3 = inicio + espacio * i + 3;
                    if (i == 3) horizontalDesfase_Y_4 = inicio + espacio * i + 5;
                    if (i == 4) horizontalDesfase_Y_5 = inicio + espacio * i + 8;
                    if (i == 5) horizontalDesfase_Y_6 = inicio + espacio * i + 10;
                    if (i == 6) horizontalDesfase_Y_7 = inicio + espacio * i + 12;
                }

                int horizontalWidth = 38;
                for (int i = 5; i < totalLines; i++)
                {
                    int indice = (i - 5);

                    if (indice < 6)
                    {
                        LineSegment2D line = makeLine(0,
                                                    horizontalDesfase_Y_1 + indice * horizontalWidth,
                                                     img.Width,
                                                     horizontalDesfase_Y_1 + indice * horizontalWidth);
                        referencesLines[i] = line;
                    }
                    else
                    {
                        if (indice < 12)
                        {
                            indice -= 6;
                            LineSegment2D line = makeLine(0,
                                                        horizontalDesfase_Y_2 + indice * horizontalWidth,
                                                         img.Width,
                                                         horizontalDesfase_Y_2 + indice * horizontalWidth);
                            referencesLines[i] = line;
                        }
                        else
                        {
                            if (indice < 18)
                            {
                                indice -= 12;
                                LineSegment2D line = makeLine(0,
                                                            horizontalDesfase_Y_3 + indice * horizontalWidth,
                                                             img.Width,
                                                             horizontalDesfase_Y_3 + indice * horizontalWidth);
                                referencesLines[i] = line;
                            }
                            else
                            {
                                if (indice < 24)
                                {
                                    indice -= 18;
                                    LineSegment2D line = makeLine(0,
                                                                horizontalDesfase_Y_4 + indice * horizontalWidth,
                                                                 img.Width,
                                                                 horizontalDesfase_Y_4 + indice * horizontalWidth);
                                    referencesLines[i] = line;
                                }
                                else
                                {
                                    if (indice < 30)
                                    {
                                        indice -= 24;
                                        LineSegment2D line = makeLine(0,
                                                                    horizontalDesfase_Y_5 + indice * horizontalWidth,
                                                                     img.Width,
                                                                     horizontalDesfase_Y_5 + indice * horizontalWidth);
                                        referencesLines[i] = line;
                                    }
                                    else
                                    {
                                        if (indice < 36)
                                        {
                                            indice -= 30;
                                            LineSegment2D line = makeLine(0,
                                                                        horizontalDesfase_Y_6 + indice * horizontalWidth,
                                                                         img.Width,
                                                                         horizontalDesfase_Y_6 + indice * horizontalWidth);
                                            referencesLines[i] = line;
                                        }
                                        else
                                        {
                                            indice -= 36;
                                            LineSegment2D line = makeLine(0,
                                                                        horizontalDesfase_Y_7 + indice * horizontalWidth,
                                                                         img.Width,
                                                                         horizontalDesfase_Y_7 + indice * horizontalWidth);
                                            referencesLines[i] = line;
                                        }
                                    }
                                }
                            }
                        }
                    }

                }
            }

            return referencesLines;
        }
 public int binarySearch(int posX, LineSegment2D[] pReferenceLines, int middle)
 {
     return _binarySearch(posX, pReferenceLines, middle, pReferenceLines.Count() - 1);
 }
Beispiel #20
0
      /// <summary>
      /// Finds line segments in a binary image using the probabilistic Hough transform.
      /// </summary>
      /// <param name="image">8-bit, single-channel binary source image. The image may be modified by the function.</param>
      /// <param name="rho">Distance resolution of the accumulator in pixels</param>
      /// <param name="theta">Angle resolution of the accumulator in radians</param>
      /// <param name="threshold">Accumulator threshold parameter. Only those lines are returned that get enough votes</param>
      /// <param name="minLineLength">Minimum line length. Line segments shorter than that are rejected.</param>
      /// <param name="maxGap">Maximum allowed gap between points on the same line to link them.</param>
      /// <returns>The found line segments</returns>
      public static LineSegment2D[] HoughLinesP(IInputArray image, double rho, double theta, int threshold, double minLineLength = 0, double maxGap = 0)
      {
         using (Mat lines = new Mat())
         {
            HoughLinesP(image, lines, rho, theta, threshold, minLineLength, maxGap);
            Size s = lines.Size;

            LineSegment2D[] segments = new LineSegment2D[s.Height];
            GCHandle handle = GCHandle.Alloc(segments, GCHandleType.Pinned);
            using (Mat tmp = new Mat(s.Height, s.Width, CV.CvEnum.DepthType.Cv32S, 4, handle.AddrOfPinnedObject(), sizeof(int) * 4))
            {
               lines.CopyTo(tmp);
            }
            handle.Free();

            return segments;
         }
      }
        private void processAnswers(List<List<CircleF>> pLsOrdered, LineSegment2D[] pAnswerReferenceLines, LineSegment2D[] pCodeNumberRefenceLines, Image<Bgr, Byte> pImg)
        {
            Question question;

            for (int i = 0; i < pLsOrdered.Count; i++)
            {
                int maxLengthList = pLsOrdered[i].Count;
                for (int j = 0; j < maxLengthList; j++)
                {
                    // for Answers
                    // note that the last list of list is for CodeNumbers, so "-1" leave the last for letter...(else)
                    #region process answers

                    if (i < maxLengthList - 1)
                    {
                        question = new Question();

                        if (pLsOrdered[i][j].Center.X == pAnswerReferenceLines[i].P1.X)
                        {
                            question.fillQuestion(ID_SEQUENCE + 1, "*************");
                            scalar = new MCvScalar(0, 255, 0);
                            color = new Bgr(Color.Green);
                        }
                        else
                        {
                            if (pLsOrdered[i][j].Center.X < pAnswerReferenceLines[i].P1.X)
                            {// Yes Answer
                                question.fillQuestion(ID_SEQUENCE + 1, "True");
                                scalar = new MCvScalar(0, 0, 255);
                                color = new Bgr(Color.Green);
                            }
                            else
                            {// No answer
                                question.fillQuestion(ID_SEQUENCE + 1, "False");
                                scalar = new MCvScalar(255, 0, 0);
                                color = new Bgr(Color.Green);
                            }

                        }
                        questions.Add(question);
                        ID_SEQUENCE++;

                    }
                    #endregion

                    // for CodeNumbers
                    #region process codes number

                    else //this is the last list of circles
                    {
                        codeNumber = 0;
                        int ii = pLsOrdered[i].Count - 1;
                        //for (int k =  - 1; 0 <= k; k--)
                        for (int k = 0; k < pLsOrdered[i].Count; k++)
                        {
                            codeNumber += (int)(getDigitFromCode(pLsOrdered[i][k], pCodeNumberRefenceLines) * Math.Pow(10, ii));
                            ii--;
                        }

                        txtCode.Text = codeNumber.ToString();

                        scalar = new MCvScalar(0, 0, 0);
                        color = new Bgr(Color.Green);

                    }

                    if (pLsOrdered[i][j].Radius == 20)
                    {
                        scalar = new MCvScalar(255, 255, 0);
                    }
                    CvInvoke.cvCircle(pImg,
                                        new Point((int)pLsOrdered[i][j].Center.X,
                                                  (int)pLsOrdered[i][j].Center.Y),
                                                  15,
                                                  scalar,
                                                  -1,
                                                  LINE_TYPE.CV_AA,
                                                  0);
                    #endregion

                }
            }
        }
        private List<List<CircleF>> orderAnswersAndCodeNumber_ByPos_Y(List<CircleF> pCircles, LineSegment2D[] pAnswerReferenceLines, LineSegment2D[] pCodeNumberReferenceLines)
        {
            #region Test
            //Segmentation of the answers by each line of reference
            int minDistToReferenceLine = 50;
            int maxDistFromReferenceLine = 19;
            List<List<CircleF>> lsAnswersAndCodes = new List<List<CircleF>>();
            List<CircleF> lsCodeNumbers = new List<CircleF>();

            for (int i = 0; i < pAnswerReferenceLines.Length - 42; i++)
            {
                List<CircleF> lsAnswersPerReferenceLine = new List<CircleF>();
                for (int j = 0; j < pCircles.Count; j++)
                {
                    /*
                     * filtering Answers and CodeNumbers, note that the first "pCodeNumberReferenceLines[0] " is
                     * used for this purpuse, remember this comes from " getCodeNumberReferenceLines() "
                    */

                    // Answer Circles
                    if (Math.Abs(pAnswerReferenceLines[i].P1.X - pCircles[j].Center.X) < minDistToReferenceLine &&
                        //Math.Abs(pAnswerReferenceLines[i].P1.X - pCircles[j].Center.X) > maxDistFromReferenceLine &&
                        pCircles[j].Center.Y > pAnswerReferenceLines[5].P1.Y)
                    {

                        lsAnswersPerReferenceLine.Add(pCircles[j]);
                    }

                    // CodesNumbers Circles =>  Validate Code Zone
                    else if (pCircles[j].Center.Y > pCodeNumberReferenceLines[0].P1.Y &&
                             pCircles[j].Center.Y < pCodeNumberReferenceLines[1].P1.Y &&
                            pCircles[j].Center.X > pCodeNumberReferenceLines[2].P1.X &&
                            pCircles[j].Center.X < pCodeNumberReferenceLines[12].P1.X &&
                             lsCodeNumbers.Count < 3)
                    {
                        lsCodeNumbers.Add(pCircles[j]);
                    }

                }

                lsAnswersAndCodes.Add(lsAnswersPerReferenceLine);
            }
            //Remenber and respect the last list of circles correspondes to CodesNumber Circles
            lsAnswersAndCodes.Add(lsCodeNumbers);

            //TODO: FIX = > a Bool vector for not repeating the visit to each circle
            // ordering anwers and codes by positions in y (quickSort), it is include all the list of list since
            // is just for orderig
            for (int i = 0; i < lsAnswersAndCodes.Count; i++)
            {
                QuickSort(lsAnswersAndCodes[i], 0, lsAnswersAndCodes[i].Count - 1);
            }
            return lsAnswersAndCodes;
            #endregion

            #region ok
            ////Segmentation of the answers by each line of reference
            //int minDistToReferenceLine = 50;
            //List<List<CircleF>> lsAnswersAndCodes = new List<List<CircleF>>();
            //List<CircleF> lsCodeNumbers = new List<CircleF>();

            //for (int i = 0; i < pAnswerReferenceLines.Length  ; i++)
            //{
            //    List<CircleF> lsAnswersPerReferenceLine = new List<CircleF>();
            //    for (int j = 0; j < pCircles.Count; j++)
            //     {
            //        /*
            //         * filtering Answers and CodeNumbers, note that the first "pCodeNumberReferenceLines[0] " is
            //         * used for this purpuse, remember this comes from " getCodeNumberReferenceLines() "
            //        */

            //        // Answer Circles
            //        if (Math.Abs(pAnswerReferenceLines[i].P1.X - pCircles[j].Center.X) < minDistToReferenceLine &&
            //            pCircles[j].Center.Y > pCodeNumberReferenceLines[1].P1.Y )
            //        {
            //            lsAnswersPerReferenceLine.Add(pCircles[j]);
            //        }

            //        // CodesNumbers Circles
            //        else if (pCircles[j].Center.Y > pCodeNumberReferenceLines[0].P1.Y &&
            //                 pCircles[j].Center.Y < pCodeNumberReferenceLines[1].P1.Y &&
            //                 lsCodeNumbers.Count < 3)
            //        {
            //            lsCodeNumbers.Add(pCircles[j]);
            //        }

            //    }

            //    lsAnswersAndCodes.Add(lsAnswersPerReferenceLine);
            //}
            ////Remenber and respect the last list of circles correspondes to CodesNumber Circles
            //lsAnswersAndCodes.Add(lsCodeNumbers);

            ////TODO: FIX = > a Bool vector for not repeating the visit to each circle
            //// ordering anwers and codes by positions in y (quickSort), it is include all the list of list since
            //// is just for orderig
            //for (int i = 0; i < lsAnswersAndCodes.Count ; i++)
            //{
            //    QuickSort(lsAnswersAndCodes[i], 0, lsAnswersAndCodes[i].Count - 1);
            //}
            //return lsAnswersAndCodes;
            #endregion
        }
 private int isInsideHorizontalBox(List<CircleF> circles, LineSegment2D line_Sup, LineSegment2D line_Inf)
 {
     for (int i = 0; i < circles.Count; i++)
     {
         if (circles[i].Center.Y > line_Sup.P1.Y && circles[i].Center.Y < line_Inf.P1.Y)
             return i;
     }
     return 99999;
 }
        private List<List<CircleF>> comparePositions(List<List<CircleF>> lsMarkedAnswersPlusCode, List<List<CircleF>> lsLeftAnswers, LineSegment2D[] rflines)
        {
            for (int i = 0; i < lsMarkedAnswersPlusCode.Count - 1; i++)
            {
                for (int j = 0; j < lsMarkedAnswersPlusCode[i].Count - 1; j++)
                {
                    if (lsMarkedAnswersPlusCode[i][j].Center.X == rflines[i].P1.X)
                    {
                        PointF p;
                        CircleF c;

                        if (lsLeftAnswers[i][j].Center.X > rflines[i].P1.X)
                        {
                            p = new PointF(rflines[i].P1.X - 60, lsLeftAnswers[i][j].Center.Y);
                        }
                        else
                        {
                            p = new PointF(rflines[i].P1.X + 60, lsLeftAnswers[i][j].Center.Y);

                        }
                        c = new CircleF(p, 20);

                        lsMarkedAnswersPlusCode[i][j] = c;
                    }
                }
            }
            return lsMarkedAnswersPlusCode;
        }
        public void drawRefenceLines(LineSegment2D[] pAnswerLines, LineSegment2D[] pCodeNumberLines, Image<Bgr, Byte> pImg)
        {
            //draw referece lines for answers
            for (int i = 0; i < pAnswerLines.Length; i++)
            {
                pImg.Draw(pAnswerLines[i], new Bgr(Color.Red), 2);
            }

            //draw referece lines for codes
            for (int i = 0; i < pCodeNumberLines.Length; i++)
            {
                pImg.Draw(pCodeNumberLines[i], new Bgr(Color.Green), 2);
            }
        }
        public void TestAngle(/*LineSegment2D HorizontalMiddleLine*/)
        {
            Image<Bgr, Byte> imgBackground = new Image<Bgr, byte>("C:\\Users\\kevin\\Downloads\\gridBackground2.jpg");
            LineSegment2D line1 = new LineSegment2D(new Point(100, 0), new Point(200, 150));
            LineSegment2D line2 = new LineSegment2D(new Point(200, 150), new Point(150, 300));

            imgBackground.Draw(line1, new Bgr(Color.Red), 1);
            imgBackground.Draw(line2, new Bgr(Color.Blue), 1);

            Double angle = 0;
            angle = (line1.GetExteriorAngleDegree(line2));//* (180.0 / Math.PI) );

            MCvFont f = new MCvFont(FONT.CV_FONT_HERSHEY_COMPLEX, 0.6, 0.6);
            imgBackground.Draw(angle.ToString(), ref f, new Point(50, 50), new Bgr(0, 0, 0));

            //ibTestAngle.Image = imgBackground;
        }
Beispiel #27
0
 private static HoughResult GroupSegments(LineSegment2D[] segments)
 {
     var solidSegments = new List<LineSegment2D>();
     var dashSegments = new List<DashLineSegment2D>();
     var grouped = GroupDirectionSerment(segments);
     foreach (var group in grouped)
     {
         var fullSegments = GroupCloseSegment(group.Item2);
         var allSegments = GroupDashSegment(fullSegments);
         var dashSegment = GroupCloseDashSegment(allSegments.Item2);
         solidSegments.AddRange(
             allSegments.Item1.Where(l => DistanceHelper.Distance(l.P1, l.P2) > MinLineFullLenght));
         dashSegments.AddRange(
             dashSegment.Where(l => DistanceHelper.Distance(l.AsSolid.P1, l.AsSolid.P2) > MinLineFullLenght));
     }
     return new HoughResult {SolidLines = solidSegments.ToArray(), DashLines = dashSegments.ToArray()};
 }
Beispiel #28
0
 /// <summary>
 /// convert a series of System.Drawing.Point to LineSegment2D
 /// </summary>
 /// <param name="points">the array of points</param>
 /// <param name="closed">if true, the last line segment is defined by the last point of the array and the first point of the array</param>
 /// <returns>array of LineSegment2D</returns>
 public static LineSegment2D[] PolyLine(Point[] points, bool closed)
 {
    LineSegment2D[] res;
    int length = points.Length;
    if (closed)
    {
       res = new LineSegment2D[length];
       for (int i = 0; i < res.Length; i++)
          res[i] = new LineSegment2D(points[i], points[(i + 1) % length]);
    }
    else
    {
       res = new LineSegment2D[length - 1];
       for (int i = 0; i < res.Length; i++)
          res[i] = new LineSegment2D(points[i], points[(i + 1)]);
    }
    return res;
 }
        private void processAnswersBlackCircleSelected(List<List<CircleF>> lsAnswersComplete, LineSegment2D[] pAnswerReferenceLines, Image<Bgr, byte> pImg)
        {
            Question question;

            for (int i = 0; i < lsAnswersComplete.Count; i++)
            {
                int maxLengthList = lsAnswersComplete[i].Count;
                for (int j = 0; j < maxLengthList; j++)
                {
                    // for Answers
                    // note that the last list of list is for CodeNumbers, so "-1" leave the last for letter...(else)
                    #region process answers

                    question = new Question();
                    if (lsAnswersComplete[i][j].Center.X == pAnswerReferenceLines[i].P1.X)
                    {
                        question.fillQuestion(ID_SEQUENCE + 1, "*************");
                        scalar = new MCvScalar(0, 255, 0);
                        color = new Bgr(Color.Green);
                    }
                    else
                    {
                        if (lsAnswersComplete[i][j].Center.X < pAnswerReferenceLines[i].P1.X)
                        {// Yes Answer
                            question.fillQuestion(ID_SEQUENCE + 1, "False");
                            scalar = new MCvScalar(0, 0, 255);
                            color = new Bgr(Color.Green);
                        }
                        else
                        {// No answer
                            question.fillQuestion(ID_SEQUENCE + 1, "Verdadero");
                            scalar = new MCvScalar(255, 0, 0);
                            color = new Bgr(Color.Green);
                        }

                    }
                    questions.Add(question);
                    ID_SEQUENCE++;
                    CvInvoke.cvCircle(pImg,
                                         new Point((int)lsAnswersComplete[i][j].Center.X,
                                                   (int)lsAnswersComplete[i][j].Center.Y),
                                                   6,
                                                   scalar,
                                                   -1,
                                                   LINE_TYPE.CV_AA,
                                                   0);
                    #endregion
                }
            }
        }
        public int _binarySearch(int posX, LineSegment2D[] pReferenceLines, int posCurrent, int posPast)
        {
            // if (posPast == 11 && posCurrent == 10)
            //     return 9;

            if (Math.Abs(posPast - posCurrent) <= 1 && posX < pReferenceLines[posCurrent].P1.X)
            {
                return posCurrent - 3;
            }
            if (Math.Abs(posPast - posCurrent) <= 1 && posX > pReferenceLines[posCurrent].P1.X)
            {
                return posCurrent - 2;
            }

            if (posX < pReferenceLines[posCurrent].P1.X)
            {
                return _binarySearch(posX, pReferenceLines, (int)Math.Floor(posCurrent / 2.0), posCurrent);
            }
            else
            {
                return _binarySearch(posX, pReferenceLines, (int)Math.Floor((posPast + posCurrent) / 2.0), posPast);
            }
        }
        private List<List<CircleF>> validateQuestionBoxes(List<List<CircleF>> lsAnswerAndCodeNumbersOrdered, LineSegment2D[] answerReferenceLines)
        {
            List<List<CircleF>> completAnswers = new List<List<CircleF>>();

            for (int k = 0; k < lsAnswerAndCodeNumbersOrdered.Count - 1; k++)
            {
                List<CircleF> completeAnswerPerReferenceLine = new List<CircleF>();

                for (int j = 5; j < 46; j++) //number if horizontal boxes
                {
                    if (j != 10 && j != 16 && j != 22 && j != 28 && j != 34 && j != 40)
                    {
                        int posCircle = isInsideHorizontalBox(lsAnswerAndCodeNumbersOrdered[k], answerReferenceLines[j], answerReferenceLines[j + 1]);
                        if (99999 != posCircle)
                        {
                            completeAnswerPerReferenceLine.Add(lsAnswerAndCodeNumbersOrdered[k][posCircle]);
                        }
                        else
                        {
                            PointF p = new PointF((answerReferenceLines[k].P1.X), (answerReferenceLines[j].P1.Y + answerReferenceLines[j + 1].P1.Y) / 2);
                            CircleF c = new CircleF(p, 12);
                            completeAnswerPerReferenceLine.Add(c);
                        }
                    }
                }

                completAnswers.Add(completeAnswerPerReferenceLine);

            }

            return completAnswers;
        }