// 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); } }
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); }