// dir distance
    public double Distance(double[] x, double[] y)
    {
        Vector2 s1 = new Vector2((float)x[0], (float)x[1]);
        Vector2 e1 = new Vector2((float)x[2], (float)x[3]);
        Vector2 s2 = new Vector2((float)y[0], (float)y[1]);
        Vector2 e2 = new Vector2((float)y[2], (float)y[3]);

        Line2 l1 = new Line2(s1, e1);
        Line2 l2 = new Line2(s2, e2);

        double cos = Math.Abs(Vector2.Dot(l1.dir, l2.dir));

        if (cos > Math.Cos(10 * Math.PI / 180))
        {
            cos = 1;
        }

        double d1     = Math.Min(l1.DistanceToLine(s2), l1.DistanceToLine(e2));
        double d2     = Math.Min(l2.DistanceToLine(s1), l2.DistanceToLine(e1));
        double mindis = Math.Min(d1, d2);



        return(1 - cos + mindis * 4 / SkeletonExtractor.IMGSIZE);
    }
    private Line2 FitSimilarLine(List <Line2> lines, Line2 target, double angle = 20)
    {
        NumericalRecipes.RansacLine2d rcl = new NumericalRecipes.RansacLine2d();
        List <Vector2> linepoints         = new List <Vector2>();

        linepoints.AddRange(target.SamplePoints());
        //ransac
        for (int i = 0; i < lines.Count; i++)
        {
            if (Line2.IsParallel(lines[i], target, angle))
            {
                if (target.DistanceToLine(lines[i].start) < 30 && target.DistanceToLine(lines[i].end) < 30)
                {
                    linepoints.AddRange(lines[i].SamplePoints());
                }
            }
        }
        Line2 bestline = rcl.Estimate(linepoints);

        if (bestline == null)
        {
            return(target);
        }
        if (Vector2.Dot(bestline.dir, target.dir) < 0)
        {
            bestline.Flip();
        }
        return(bestline);
    }
    private bool IsCurveAxis(List <Line2> skel_lines, Line2 main_axis_straight)
    {
        List <Vector2> skel_points = new List <Vector2>();

        foreach (Line2 sl in skel_lines)
        {
            skel_points.AddRange(sl.SamplePoints());
        }
        int onlinecount = 0;

        foreach (Vector2 p in skel_points)
        {
            if (main_axis_straight.DistanceToLine(p) < 2)
            {
                onlinecount++;
            }
        }
        double ratio = onlinecount * 1.0 / skel_points.Count;

        Debug.Log("is curve ratio: " + ratio);
        if (ratio <= 0.4)
        {
            return(true);
        }
        else
        {
            return(false);
        }
    }
    public double MinDisBetweenLine2(Line2 a, Line2 b)
    {
        if (!Line2.IsParallel(a, b, 5))
        {
            double dis1 = a.DistanceToLine(b.start);
            double dis2 = a.DistanceToLine(b.end);
            double dis3 = b.DistanceToLine(a.start);
            double dis4 = b.DistanceToLine(a.end);

            double meandis = Math.Min(Math.Min(dis1, dis2), Math.Min(dis3, dis4));
            //double meandis = (dis1 + dis2 + dis3 + dis4) / 4.0;
            return(meandis);
        }
        else
        {
            return(0);
        }
    }
Beispiel #5
0
        public Line2 Estimate(List <Vector2> points)
        {
            this.inliers.Clear();
            this.bestline = null;

            int iter = 200;

            if (points.Count == 0)
            {
                return(null);
            }
            System.Random rd = new System.Random();

            Vector2 A = new Vector2();
            Vector2 B = new Vector2();

            //int maxpointinline = int.MinValue;
            double maxpointinline = 2; //points.Count/2;

            bestline = null;
            for (int i = 0; i < iter; i++)
            {
                A = points[rd.Next(points.Count)];
                B = points[rd.Next(points.Count)];
                if (A == B)
                {
                    continue;          //if can't generate line
                }
                Line2 testline = new Line2(A, B);

                List <Vector2> tempinliers  = new List <Vector2>();
                int            inlierscount = 0;
                for (int j = 0; j < points.Count; j++)
                {
                    if (points[j] != A && points[j] != B)
                    {
                        if (testline.DistanceToLine(points[j]) < thres)
                        {
                            tempinliers.Add(points[j]);
                            inlierscount++;
                        }
                    }
                }

                if (inlierscount > maxpointinline)
                {
                    maxpointinline = inlierscount;
                    bestline       = new Line2(testline);
                    this.inliers.Clear();
                    foreach (Vector2 p in tempinliers)
                    {
                        this.inliers.Add(p);
                    }
                }

                if (inlierscount >= probability * points.Count)
                {
                    break;
                }
            }
            if (this.inliers.Count != 0)
            {
                double mint = double.MaxValue;
                double maxt = double.MinValue;
                foreach (Vector2 p in this.inliers)
                {
                    double t = this.bestline.ComputeT(p);
                    if (t > maxt)
                    {
                        maxt = t;
                    }
                    if (t < mint)
                    {
                        mint = t;
                    }
                }
                bestline.SetPoints((float)mint, (float)maxt);
            }


            if (bestline != null && this.inliers.Count() > 0)
            {
                return(bestline);
            }
            else
            {
                return(null);
            }
        }
    private Line2 ApproximateFromTop()
    {
        //guess axis with top face(s)

        Line2 main_axis = null;

        face_center = new List <Vector2>();
        List <Vector2> normal = new List <Vector2>();

        List <double> minoraxislength = new List <double>();

        foreach (Image <Gray, byte> fimg in face_img)
        {
            Vector2        mean   = new Vector2();
            List <Vector2> points = IExtension.GetMaskPoints(fimg);
            foreach (Vector2 p in points)
            {
                mean += p;
            }
            mean /= points.Count;
            face_center.Add(mean);
            float W = points.Count;

            float[,] C = new float[2, 2];
            foreach (Vector2 point in points)
            {
                C[0, 0] += (point.x - mean.x) * (point.x - mean.x);
                C[0, 1] += (point.x - mean.x) * (point.y - mean.y);

                C[1, 0] += (point.y - mean.y) * (point.x - mean.x);
                C[1, 1] += (point.y - mean.y) * (point.y - mean.y);
            }

            C[0, 0] /= W;
            C[0, 1] /= W;
            C[1, 0] /= W;
            C[1, 1] /= W;

            Matrix2d             CM  = new Matrix2d(C);
            NumericalRecipes.SVD svd = new NumericalRecipes.SVD(C);
            //svd.w - eigenvalue, start from 1
            //svd.u - eigenvector, start from 1

            int max = 1, min = 2;
            if (svd.w[max] < svd.w[min])
            {
                int temp = max;
                max = min;
                min = temp;
            }

            float   major     = 2 * Mathf.Sqrt(svd.w[max]);
            Vector2 majoraxis = new Vector2(svd.u[1, max], svd.u[2, max]);
            majoraxis.Normalize();
            float   minor     = 2 * Mathf.Sqrt(svd.w[min]);
            Vector2 minoraxis = new Vector2(svd.u[1, min], svd.u[2, min]);
            minoraxis.Normalize();

            Vector2 majorendp   = mean + majoraxis * major;
            Vector2 majorstartp = mean - majoraxis * major;
            Vector2 minorendp   = mean + minoraxis * minor;
            Vector2 minorstartp = mean - minoraxis * minor;


            //minoraxislength.Add(Vector2.Distance(minorendp, minorstartp));
            minoraxislength.Add((double)minor * 2);
            normal.Add(Utility.PerpendicularRight(majoraxis));
            //normal.Add(majoraxis);
        }


        if (face_center.Count > 1)
        {
            //Vector2 mean_normal = normal.First();
            Line2  best_top_normal_line = new Line2(face_center.First(), normal.First(), true);
            double maxdis         = 0;
            int    farthesttopidx = 0;
            for (int i = 1; i < face_center.Count; i++)
            {
                double tofirstcenterdis = Vector2.Distance(face_center[0], face_center[i]);
                if (tofirstcenterdis > maxdis)
                {
                    maxdis         = tofirstcenterdis;
                    farthesttopidx = i;
                }
                double dis = best_top_normal_line.DistanceToLine(face_center[i]);
                if (dis > 10)
                {
                    main_axis = null;
                }
            }
            main_axis = new Line2(face_center.First(), face_center[farthesttopidx]);
        }
        else
        {
            Line2   top_normal_line = new Line2(face_center.First(), normal.First(), true);
            Vector2 online_point    = top_normal_line.GetPointwithT((float)minoraxislength[0]);
            if (online_point.x >= 0 && online_point.y >= 0 && online_point.x < body_img.Width && online_point.y < body_img.Height)
            {
                if (!this.body_img[(int)online_point.y, (int)online_point.x].Equals(new Gray(255)))
                {
                    top_normal_line.Flip();
                }
            }
            else
            {
                top_normal_line.Flip();
            }
            main_axis = top_normal_line;
        }

        return(main_axis);
    }