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); }
public double[] SVDSingularMatW() { SVD svd = new SVD(e, row_size, row_size); if (svd.State == false) throw new ArithmeticException(); return svd.w; }
public Matrix4d Inverse() { SVD svd = new SVD(e, row_size, row_size); if (svd.State == false) throw new ArithmeticException(); return new Matrix4d(svd.Inverse); }
public double[] SVDSingularMat() { SVD svd = new SVD(e, 3, 3); return svd.w; }
public Matrix3d OrthogonalFactorSVD() { SVD svd = new SVD(e, 3, 3); lastSVDIsFullRank = svd.FullRank; return new Matrix3d(svd.OrthogonalFactor); }
public Matrix3d InverseSVD() { SVD svd = new SVD(e, 3, 3); Matrix3d inv = new Matrix3d(svd.Inverse); lastSVDIsFullRank = svd.FullRank; return inv; }