Example #1
0
        public static List <SegmentExtended> MergeSegmentWithLSM(List <SegmentExtended> list_of_segments, double spatial_distance, double tau_theta)
        {
            int n;
            List <SegmentExtended> list_of_merged_segments = list_of_segments;

            do
            {
                n = list_of_merged_segments.Count();

                list_of_merged_segments = list_of_merged_segments.OrderByDescending(x => Toolbox.Distance(x)).ToList();

                for (int i = 0; i < list_of_merged_segments.Count; i++)
                {
                    SegmentExtended L1 = list_of_merged_segments[i];

                    double l1      = Toolbox.Distance(L1);
                    double theta_1 = Toolbox.Angle(L1);

                    double tau_s = spatial_distance * l1;

                    double x_11 = L1.Segment.X1;
                    double x_12 = L1.Segment.X2;
                    double y_11 = L1.Segment.Y1;
                    double y_12 = L1.Segment.Y2;

                    List <SegmentExtended> P = list_of_merged_segments.Where(x => Math.Abs(Toolbox.Angle(x) - theta_1) < tau_theta).ToList();
                    P = P.Where(
                        s => Math.Abs(x_11 - s.Segment.X1) < tau_s || Math.Abs(x_11 - s.Segment.X2) < tau_s || Math.Abs(x_12 - s.Segment.X1) < tau_s || Math.Abs(x_12 - s.Segment.X2) < tau_s
                        ).ToList();

                    P = P.Where(
                        s => Math.Abs(y_11 - s.Segment.Y1) < tau_s || Math.Abs(y_11 - s.Segment.Y2) < tau_s || Math.Abs(y_12 - s.Segment.Y1) < tau_s || Math.Abs(y_12 - s.Segment.Y2) < tau_s
                        ).ToList();

                    List <SegmentExtended> R = new List <SegmentExtended>();
                    foreach (SegmentExtended L2 in P)
                    {
                        SegmentExtended M = LSMSegmentMerger(L1, L2, spatial_distance, tau_theta);
                        if (M != null)
                        {
                            L1 = M;
                            list_of_merged_segments[i] = M;
                            R.Add(L2);
                        }
                    }

                    R.ForEach(x => list_of_merged_segments.Remove(x));
                }
            }while (n != list_of_merged_segments.Count());


            return(list_of_merged_segments);
        }
Example #2
0
        /// <summary>
        /// Return a list of Segment where all parallel and continuous segment are Merge
        /// </summary>
        /// <param name="segments"></param>
        /// <param name="threshold"></param>
        /// <returns></returns>
        public static List <SegmentExtended> MergeSegment(List <SegmentExtended> segments, double threshold)
        {
            List <SegmentExtended> merged_segment;

            merged_segment = new List <SegmentExtended>();

            for (int i = 0; i < segments.Count; i++)
            {
                /// On ajoute le segment courant à la liste des segments fusionnés
                /// il faudra donc éliminer les segments mergeable au fur et à mesure de l'algo
                merged_segment.Add(segments[i]);
                for (int j = i + 1; j < segments.Count; j++)
                {
                    if (testIfSegmentAreParrallel(merged_segment[i], segments[j]))
                    {
                        /// Les segments sont bien parallèles
                        if (Toolbox.DistancePointToLine(new PointD(segments[j].Segment.X1, segments[j].Segment.Y1),
                                                        new PointD(merged_segment[i].Segment.X1, merged_segment[i].Segment.Y1),
                                                        new PointD(merged_segment[i].Segment.X2, merged_segment[i].Segment.Y2)) < threshold)
                        {
                            /// Le pt 1 appartient au merged_segment[i]
                            if (Toolbox.DistancePointToLine(new PointD(segments[j].Segment.X2, segments[j].Segment.Y2),
                                                            new PointD(merged_segment[i].Segment.X1, merged_segment[i].Segment.Y1),
                                                            new PointD(merged_segment[i].Segment.X2, merged_segment[i].Segment.Y2)) < threshold)
                            {
                                /// Le pt 2 appartient au merged_segment[i]
                                /// On fusionne les segments !!!
                                double xMin = Math.Min(Math.Min(merged_segment[i].Segment.X1, merged_segment[i].Segment.X2), Math.Min(segments[j].Segment.X1, segments[j].Segment.X2));
                                double xMax = Math.Max(Math.Max(merged_segment[i].Segment.X1, merged_segment[i].Segment.X2), Math.Max(segments[j].Segment.X1, segments[j].Segment.X2));
                                double yMin = Math.Min(Math.Min(merged_segment[i].Segment.Y1, merged_segment[i].Segment.Y2), Math.Min(segments[j].Segment.Y1, segments[j].Segment.Y2));
                                double yMax = Math.Max(Math.Max(merged_segment[i].Segment.Y1, merged_segment[i].Segment.Y2), Math.Max(segments[j].Segment.Y1, segments[j].Segment.Y2));

                                if (Toolbox.ModuloPiAngleRadian(Math.Atan2(merged_segment[i].Segment.Y2 - merged_segment[i].Segment.Y1, merged_segment[i].Segment.X2 - merged_segment[i].Segment.X1)) > 0)
                                {
                                    merged_segment[i] = new SegmentExtended(new PointD(xMin, yMin), new PointD(xMax, yMax), merged_segment[i].Color, merged_segment[i].Width);
                                }
                                else
                                {
                                    merged_segment[i] = new SegmentExtended(new PointD(xMin, yMax), new PointD(xMax, yMin), merged_segment[i].Color, merged_segment[i].Width);
                                }

                                /// On supprime le segment fusionné
                                segments.RemoveAt(j);
                            }
                        }
                    }
                }
            }

            return(merged_segment);
        }
Example #3
0
        public static bool testIfSegmentArePerpendicular(SegmentExtended segment_1, SegmentExtended segment_2, double thresold = 3 *(Math.PI / 180))
        {
            double segment_1_angle = Toolbox.ModuloPiAngleRadian(Math.Atan2(segment_1.Segment.Y2 - segment_1.Segment.Y1, segment_1.Segment.X2 - segment_1.Segment.X1));
            double segment_2_angle = Toolbox.ModuloPiAngleRadian(Toolbox.ModuloPiAngleRadian(Math.Atan2(segment_2.Segment.Y2 - segment_2.Segment.Y1, segment_2.Segment.X2 - segment_2.Segment.X1)) + Math.PI / 2);

            if (segment_1_angle - thresold <= segment_2_angle && segment_1_angle + thresold >= segment_2_angle)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
Example #4
0
        public static List <List <SegmentExtended> > FindFamilyOfSegment(List <SegmentExtended> list_of_segments, double minimum_size = 0.0)
        {
            List <SegmentExtended>         copy_of_list_of_segment = list_of_segments;
            List <List <SegmentExtended> > list_of_family          = new List <List <SegmentExtended> >();

            while (copy_of_list_of_segment.Count > 0)
            {
                SegmentExtended selected_segment = copy_of_list_of_segment[0];
                if (Toolbox.Distance(selected_segment.Segment.X1, selected_segment.Segment.Y1, selected_segment.Segment.X2, selected_segment.Segment.Y2) > minimum_size)
                {
                    int index_of_this_family = list_of_family.Count;
                    list_of_family.Add(new List <SegmentExtended>());

                    list_of_family[index_of_this_family].Add(selected_segment);

                    for (int j = 0; j < copy_of_list_of_segment.Count; j++)
                    {
                        SegmentExtended tested_segment = copy_of_list_of_segment[j];
                        if (testIfSegmentAreParrallel(selected_segment, tested_segment) || testIfSegmentArePerpendicular(selected_segment, tested_segment))
                        {
                            list_of_family[index_of_this_family].Add(tested_segment);
                        }
                    }

                    foreach (SegmentExtended element in list_of_family[index_of_this_family])
                    {
                        copy_of_list_of_segment.Remove(element);
                    }
                }
                else
                {
                    copy_of_list_of_segment.RemoveAt(0);
                }
            }
            return(list_of_family);
        }
Example #5
0
        /// <summary>
        /// Implemenation of segment merger "LSM: perceptually accurate linesegment merging"
        /// https://doi.org/10.1117/1.JEI.25.6.061620
        /// </summary>
        /// <returns>Return the merged Segment or null if the condition are not </returns>
        public static SegmentExtended LSMSegmentMerger(SegmentExtended Global_L1, SegmentExtended Global_L2, double xi_s, double tau_theta)
        {
            SegmentExtended L1 = Global_L1;
            SegmentExtended L2 = Global_L2;

            double l1 = Toolbox.Distance(L1);
            double l2 = Toolbox.Distance(L2);

            double theta1 = Toolbox.Angle(L1);
            double theta2 = Toolbox.Angle(L2);

            if (l1 < l2)
            {
                /// Yeah i know i could have made it here but for now, it's fancier to do this
                Toolbox.SwapNum(ref L1, ref L2);
                Toolbox.SwapNum(ref l1, ref l2);
                Toolbox.SwapNum(ref theta1, ref theta2);
            }

            PointD L1_a = new PointD(L1.Segment.X1, L1.Segment.Y1);
            PointD L1_b = new PointD(L1.Segment.X2, L1.Segment.Y2);
            PointD L2_a = new PointD(L2.Segment.X1, L2.Segment.Y1);
            PointD L2_b = new PointD(L2.Segment.X2, L2.Segment.Y2);

            /// Now we Compute d (c1 and c2 are useless)
            Tuple <PointD, PointD, double> F1F2D = ComputeAndReturnF1F2AndD(L1_a, L1_b, L2_a, L2_b);

            PointD f1 = F1F2D.Item1;
            PointD f2 = F1F2D.Item2;
            double d  = F1F2D.Item3;


            double tau_s = xi_s * l1;

            if (d > tau_s)
            {
                /// We don't merge
                return(null);
            }

            /// Now we compute the adaptive angluar thresold tau_theta_prime
            double normalise_l2 = l2 / l1;
            double normalise_d  = d / tau_s;

            double lambda = normalise_l2 + normalise_d;

            double tau_theta_prime = (1 - 1 / (1 + Math.Exp(-2 * (lambda - 1.5)))) * tau_theta;

            double theta = Math.Abs(theta2 - theta1);

            if ((theta < tau_theta_prime) || (theta > (Math.PI - tau_theta_prime)))
            {
                SegmentExtended M       = new SegmentExtended(f1, f2, L1.Color, L1.Width);
                double          theta_M = Toolbox.Angle(M);

                if (Math.Abs(theta1 - theta_M) <= tau_theta / 2)
                {
                    /// We merge
                    return(M);
                }
            }

            return(null);
        }
 public void AddSegmentExtended(int id, SegmentExtended s)
 {
     segmentList.Add(s);
 }