public void Optimize_4CP() { start_dire = ComputeStartDirecFromAxis(axis); float fov_init = m_projector.m_mainCamera.fieldOfView; Vector2 v1 = corner_points[0]; Vector2 v2 = corner_points[1]; Vector2 v3 = corner_points[2]; Vector2 v4 = corner_points[3]; ray1 = m_projector.GenerateRay(v1); ray2 = m_projector.GenerateRay(v2); ray3 = m_projector.GenerateRay(v3); ray4 = m_projector.GenerateRay(v4); Vector3 v1_3 = ray1.GetPoint(depth); Vector3 v2_3 = ray2.GetPoint(depth); Vector3 v3_3 = ray3.GetPoint(depth); // Optimal Solution double[] bndl = new double[] { 0, 0, 0, 0, 1 / fov_optimal_scale }; double[] x = new double[] { depth - 0.02, depth, depth + 0.02, depth, fov_init / fov_optimal_scale }; double[] bndu = new double[] { 20, 20, 20, 20, 179 / fov_optimal_scale }; int funNum = 11; double diffstep = 0.0001; double epsg = 0.000000000001; double epsf = 0; double epsx = 0; int maxits = 0; alglib.minlmstate state; alglib.minlmreport rep; //set timer System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch(); stopwatch.Start(); Inter_Num = 0; // Do the optima alglib.minlmcreatev(funNum, x, diffstep, out state); alglib.minlmsetbc(state, bndl, bndu); alglib.minlmsetcond(state, epsg, epsf, epsx, maxits); alglib.minlmoptimize(state, function_project_rect_4CP, null, null); alglib.minlmresults(state, out x, out rep); stopwatch.Stop(); if (!m_engine.m_is_quiet) { Debug.Log("End fitting , Total time:" + stopwatch.ElapsedMilliseconds / 1000.0 + "s"); } m_engine.m_fovOptimizer.SetFOV((float)x[4] * fov_optimal_scale); fov_face = (float)x[4] * fov_optimal_scale; ray1 = m_projector.GenerateRay(v1); ray2 = m_projector.GenerateRay(v2); ray3 = m_projector.GenerateRay(v3); ray4 = m_projector.GenerateRay(v4); x0 = (float)x[0]; x1 = (float)x[1]; x2 = (float)x[2]; x3 = (float)x[3]; v1_3 = ray1.GetPoint((float)x[0]); v2_3 = ray2.GetPoint((float)x[1]); v3_3 = ray3.GetPoint((float)x[2]); Vector3 v4_3 = ray4.GetPoint((float)x[3]); // project to a new plane List <Vector3> points = new List <Vector3>(); points.Add(v1_3); points.Add(v2_3); points.Add(v3_3); points.Add(v4_3); Vector3 mean = v1_3 + v2_3 + v3_3 + v4_3; mean /= 4; Vector3 normal = Utility.GetNormal(points); Plane newplane = new Plane(normal, mean); v1_3 = Utility.PlaneProjectPoint(newplane, v1_3); v2_3 = Utility.PlaneProjectPoint(newplane, v2_3); v3_3 = Utility.PlaneProjectPoint(newplane, v3_3); v4_3 = Utility.PlaneProjectPoint(newplane, v4_3); if (!m_engine.m_is_quiet) { Debug.Log("angle: " + Vector3.Angle(v1_3 - v2_3, v3_3 - v2_3)); } topRect = new Quad(v1_3, v2_3, v3_3); topRect.FitRect(); m_renderEngine.DrawRect3(topRect, Color.green); m_renderEngine.DrawLine(axis.First(), axis.First() + 500 * start_dire.normalized, Color.red); m_renderEngine.DrawLine(topRect.Center, topRect.Center + 2 * topRect.Normal, Color.blue); if (!m_engine.m_is_quiet) { Debug.Log("angle: " + Vector3.Angle(topRect.CornerPoints3d[0] - topRect.CornerPoints3d[1], topRect.CornerPoints3d[2] - topRect.CornerPoints3d[1])); } //List<Quad> rects = new List<Quad>(); //rects.Add(topRect); //m_engine.SaveCubeCorner(rects); }
private void function_project_rect_4CP(double[] x, double[] fi, object obj) { //m_engine.m_fovOptimizer.SetFOV((float)x[4] * fov_optimal_scale); Vector2 v1_2 = corner_points[0]; Vector2 v2_2 = corner_points[1]; Vector2 v3_2 = corner_points[2]; Vector2 v4_2 = corner_points[3]; ray1 = m_projector.GenerateRay(v1_2); ray2 = m_projector.GenerateRay(v2_2); ray3 = m_projector.GenerateRay(v3_2); ray4 = m_projector.GenerateRay(v4_2); // Step 1: Init Params Inter_Num++; Vector3 v1 = ray1.GetPoint((float)x[0]); Vector3 v2 = ray2.GetPoint((float)x[1]); Vector3 v3 = ray3.GetPoint((float)x[2]); Vector3 v4 = ray4.GetPoint((float)x[3]); // equal side length float l1 = Vector3.Distance(v1, v2); float l2 = Vector3.Distance(v2, v3); float l1_2 = Vector2.Distance(v1_2, v2_2); float l2_2 = Vector2.Distance(v2_2, v3_2); fi[0] = (Vector3.Distance(v1, v2) - Vector3.Distance(v3, v4)) * 90; fi[1] = (Vector3.Distance(v2, v3) - Vector3.Distance(v1, v4)) * 90; // ratio not boo big fi[9] = Mathf.Max(l1, l2) / Mathf.Min(l1, l2) - Mathf.Max(l1_2, l2_2) / Mathf.Min(l1_2, l2_2); // vertical 0-90 fi[2] = Mathf.Abs(Vector3.Angle(v2 - v1, v4 - v1) - 90); fi[3] = Mathf.Abs(Vector3.Angle(v1 - v2, v3 - v2) - 90); fi[4] = Mathf.Abs(Vector3.Angle(v2 - v3, v4 - v3) - 90); fi[5] = Mathf.Abs(Vector3.Angle(v1 - v4, v3 - v4) - 90); // on the same plane 0-180 fi[6] = Vector3.Angle(Vector3.Cross(v2 - v1, v4 - v1), Vector3.Cross(v4 - v3, v2 - v3)); fi[7] = Vector3.Angle(Vector3.Cross(v1 - v2, v3 - v2), Vector3.Cross(v3 - v4, v1 - v4)); // mask cover Vector3 v1_3 = ray1.GetPoint((float)x[0]); Vector3 v2_3 = ray2.GetPoint((float)x[1]); Vector3 v3_3 = ray3.GetPoint((float)x[2]); Vector3 v4_3 = ray4.GetPoint((float)x[3]); // project to a new plane List <Vector3> points = new List <Vector3>(); points.Add(v1_3); points.Add(v2_3); points.Add(v3_3); points.Add(v4_3); Vector3 mean = v1_3 + v2_3 + v3_3 + v4_3; mean /= 4; Vector3 normal = Utility.GetNormal(points); Plane newplane = new Plane(normal, mean); v1_3 = Utility.PlaneProjectPoint(newplane, v1_3); v2_3 = Utility.PlaneProjectPoint(newplane, v2_3); v3_3 = Utility.PlaneProjectPoint(newplane, v3_3); v4_3 = Utility.PlaneProjectPoint(newplane, v4_3); if (!m_engine.m_is_quiet) { Debug.Log("angle: " + Vector3.Angle(v1_3 - v2_3, v3_3 - v2_3)); } Quad tempRect = new Quad(v1_3, v2_3, v3_3); tempRect.FitRect(); m_renderEngine.DrawRect3(tempRect, Color.gray); List <Vector2> QuadPoints_2d = m_projector.WorldToImage(tempRect.SampleBoundPoints()); int notinmask_count = 0; for (int i = 0; i < QuadPoints_2d.Count; i++) { int xx = (int)QuadPoints_2d[i].x; xx = Math.Max(0, xx); xx = Math.Min(xx, this.img.Width - 1); int yy = (int)QuadPoints_2d[i].y; yy = Math.Max(0, yy); yy = Math.Min(xx, this.img.Height - 1); //Debug.Log(yy + " " + xx); if (!this.img[yy, xx].Equals(new Gray(255))) { notinmask_count++; } } //fi[8] = notinmask_count / (float)QuadPoints_2d.Count; fi[8] = 10f * notinmask_count / (float)QuadPoints_2d.Count; // axis angle with normal //Vector3 rect_normal = tempRect.Normal; //Plane cutplane = new Plane(); //List<Vector2> boundary2_face = IExtension.GetBoundary(this.img); //List<Vector2> boundary2_body = ExtractOutline(this.body_img, boundary2_face); //int[] i_corner = SelectTwoCorners(m_projector.Proj3dToImage(tempRect.CornerPoints3d), boundary2_body); //Vector3 v_inSection = tempRect.CornerPoints3d[i_corner[0]] - tempRect.CornerPoints3d[i_corner[1]]; //cutplane = new Plane(Vector3.Cross(tempRect.Normal, v_inSection).normalized, tempRect.Center); //Vector3 axis_dire = m_projector.Proj2dToPlane_v(cutplane, axis.First(), start_dire); Vector2 center2 = m_projector.WorldToImage(tempRect.Center); Vector2 end2 = m_projector.WorldToImage(tempRect.Center + 10 * tempRect.Normal); Vector2 normal2 = (end2 - center2).normalized; fi[10] = 10f * Vector2.Angle(normal2, start_dire.normalized); //fi[10] = 100f*1 / Mathf.Abs(Vector2.Dot(normal2, start_dire.normalized)); // Visualization Debug.Log("Fi[8]" + fi[8] + " FOV: " + x[4] * fov_optimal_scale + "Cost: " + fi[10]); double cost = fi[0] + fi[1] + fi[2] + fi[3] + fi[4] + fi[5] + fi[6] + fi[7] + fi[8] + fi[9] + fi[10]; }
private void function_multi(double[] x, double[] fi, object obj) { float[] weight = new float[11]; weight[8] = 5f; weight[9] = 5f; weight[10] = 10f; m_engine.m_fovOptimizer.SetFOV((float)x[x.Length - 1] * fov_optimal_scale); // Clear fi for (int i = 0; i < fi.Length; i++) { fi[i] = 0; } for (int i = 0; i < REs.Count; i++) { Vector2 v1_2 = REs[i].corner_points[0]; Vector2 v2_2 = REs[i].corner_points[1]; Vector2 v3_2 = REs[i].corner_points[2]; Vector2 v4_2 = REs[i].corner_points[3]; Ray ray1 = m_projector.GenerateRay(v1_2); Ray ray2 = m_projector.GenerateRay(v2_2); Ray ray3 = m_projector.GenerateRay(v3_2); Ray ray4 = m_projector.GenerateRay(v4_2); // Step 1: Init Params Inter_Num++; Vector3 v1 = ray1.GetPoint((float)x[4 * i]); Vector3 v2 = ray2.GetPoint((float)x[4 * i + 1]); Vector3 v3 = ray3.GetPoint((float)x[4 * i + 2]); Vector3 v4 = ray4.GetPoint((float)x[4 * i + 3]); // equal side length float l1 = Vector3.Distance(v1, v2); float l2 = Vector3.Distance(v2, v3); float l1_2 = Vector2.Distance(v1_2, v2_2); float l2_2 = Vector2.Distance(v2_2, v3_2); fi[0] += (Vector3.Distance(v1, v2) - Vector3.Distance(v3, v4)) * 90; fi[1] += (Vector3.Distance(v2, v3) - Vector3.Distance(v1, v4)) * 90; // ratio not boo big fi[9] += weight[9] * Mathf.Max(l1, l2) / Mathf.Min(l1, l2) - Mathf.Max(l1_2, l2_2) / Mathf.Min(l1_2, l2_2); // vertical 0-90 fi[2] += Mathf.Abs(Vector3.Angle(v2 - v1, v4 - v1) - 90); fi[3] += Mathf.Abs(Vector3.Angle(v1 - v2, v3 - v2) - 90); fi[4] += Mathf.Abs(Vector3.Angle(v2 - v3, v4 - v3) - 90); fi[5] += Mathf.Abs(Vector3.Angle(v1 - v4, v3 - v4) - 90); // on the same plane 0-180 fi[6] += Vector3.Angle(Vector3.Cross(v2 - v1, v4 - v1), Vector3.Cross(v4 - v3, v2 - v3)); fi[7] += Vector3.Angle(Vector3.Cross(v1 - v2, v3 - v2), Vector3.Cross(v3 - v4, v1 - v4)); // mask cover Vector3 v1_3 = ray1.GetPoint((float)x[4 * i]); Vector3 v2_3 = ray2.GetPoint((float)x[4 * i + 1]); Vector3 v3_3 = ray3.GetPoint((float)x[4 * i + 2]); Vector3 v4_3 = ray4.GetPoint((float)x[4 * i + 3]); // project to a new plane List <Vector3> points = new List <Vector3>(); points.Add(v1_3); points.Add(v2_3); points.Add(v3_3); points.Add(v4_3); Vector3 mean = v1_3 + v2_3 + v3_3 + v4_3; mean /= 4; Vector3 normal = Utility.GetNormal(points); Plane newplane = new Plane(normal, mean); v1_3 = Utility.PlaneProjectPoint(newplane, v1_3); v2_3 = Utility.PlaneProjectPoint(newplane, v2_3); v3_3 = Utility.PlaneProjectPoint(newplane, v3_3); v4_3 = Utility.PlaneProjectPoint(newplane, v4_3); if (!m_engine.m_is_quiet) { Debug.Log("angle: " + Vector3.Angle(v1_3 - v2_3, v3_3 - v2_3)); } Quad tempRect = new Quad(v1_3, v2_3, v3_3); tempRect.FitRect(); List <Vector2> QuadPoints_2d = m_projector.WorldToImage(tempRect.SampleBoundPoints()); int notinmask_count = 0; for (int i_quad = 0; i_quad < QuadPoints_2d.Count; i_quad++) { int xx = (int)QuadPoints_2d[i_quad].x; xx = Mathf.Max(0, xx); xx = Mathf.Min(xx, REs[i].img.Width - 1); int yy = (int)QuadPoints_2d[i_quad].y; yy = Mathf.Max(0, yy); yy = Mathf.Min(xx, REs[i].img.Height - 1); if (!REs[i].img[yy, xx].Equals(new Gray(255))) { notinmask_count++; } } //fi[8] += notinmask_count / (float)QuadPoints_2d.Count; fi[8] += weight[8] * notinmask_count; Vector2 center2 = m_projector.WorldToImage(tempRect.Center); Vector2 end2 = m_projector.WorldToImage(tempRect.Center + 10 * tempRect.Normal); Vector2 normal2 = (end2 - center2).normalized; fi[10] += weight[10] * Vector2.Angle(normal2, REs[i].start_dire.normalized); // Visualization //m_renderEngine.DrawRect3(tempRect); //m_renderEngine.DrawLine(tempRect.Center, tempRect.Center + 10 * rect_normal, Color.blue); } double cost = fi[0] + fi[1] + fi[2] + fi[3] + fi[4] + fi[5] + fi[6] + fi[7] + fi[8] + fi[9] + fi[10]; //Debug.Log("Fi[8]" + fi[8] + " FOV: " + x[x.Length-1] * fov_optimal_scale + "Axis: " + fi[10] + "cost: " + cost ); }