public void FitTopRectangle() { // Init FOV m_engine.m_fovOptimizer.SetFOV(20); initcenter = new Vector3(); this.inlier_list.Clear(); //m_renderEngine.ClearAll(); this.boundary2 = IExtension.GetBoundary(this.img); this.FitQuad(); Optimize_4CP(); //topRect.Save(imgPath); //// Compute center //Vector2 center_2d = new Vector2(); //foreach (Vector2 p in this.boundary2) // center_2d += p; //center_2d /= this.boundary2.Count; //initcenter = m_projector.ImageToWorld(center_2d); //m_renderEngine.DrawPoint(initcenter, Color.blue); //Vector2 diagonalIntersection = this.FindTrapezoidDiagonalIntersection(); //if (!Utility.IsNull(diagonalIntersection)) //{ // if (!m_engine.m_is_quiet) Debug.Log("Use diagonal intersection."); // initcenter = m_projector.ImageToWorld(diagonalIntersection); // //m_renderEngine.DrawPoint(initcenter, Color.red); //} }
private List <Vector2> ExtractOutline(Image <Gray, byte> image, List <Vector2> topOutline = null) { // not cut face if (topOutline == null) { List <Vector2> allBoudnary2 = IExtension.GetBoundary(image); return(allBoudnary2); } // cut face double lineDistTheshold = 5; List <Vector2> ObjectOutline = IExtension.GetBoundary(image); List <Vector2> Boundary2 = new List <Vector2>(); foreach (var p_obj in ObjectOutline) { bool IsColosed = false; foreach (var p_top in topOutline) { if (Vector2.Distance(p_obj, p_top) < lineDistTheshold) { IsColosed = true; } } if (!IsColosed) { Boundary2.Add(p_obj); } } return(Boundary2); }
public void FitTopCircle() { boundary2 = IExtension.GetBoundary(img); topCircle = SolveTopCircle(); m_renderEngine.DrawPoints(topCircle.CirclePoints, Color.yellow); //List<Vector2> circle2d = m_projector.GetProjectionPoints_2D(topCircle.CirclePoints); //Image<Bgr, byte> blobimg = new Image<Bgr, byte>(this.img.Width, this.img.Height); //foreach (Vector2 p in circle2d) //{ // int i = (int)p.y; // int j = (int)p.x; // blobimg[i, j] = new Bgr(255, 255, 255); //} //blobimg.Save("C:/Users/Dell/Desktop/blob.jpg"); //foreach (Vector2 p in boundary2) //{ // int i = (int)p.y; // int j = (int)p.x; // blobimg[i, j] = new Bgr(0, 0, 255); //} //blobimg.Save("C:/Users/Dell/Desktop/blob2.jpg"); Optimize(); ReOptimize(); //topCircle.Save(imgPath); }
public void SkeletonExtractorHandle(Image <Rgb, byte> _img, Image <Rgb, byte> _handle_img) { this.label_forname = Label.Handle; this.body_img = _handle_img.Convert <Gray, byte>(); this.attach_img = _img.Convert <Gray, byte>(); noface = true; // guess top face List <Vector2> body_points = IExtension.GetBoundary(this.body_img); List <Vector2> attach_points = IExtension.GetBoundary(this.attach_img); Vector2 attach_center = Utility.Average(attach_points); double mindis_center = double.MaxValue; //int counter = 0; List <OrderItem> dis_body = new List <OrderItem>(); Vector2 closest_body_point_to_center = new Vector2(); for (int i = 0; i < body_points.Count; i++) { double dis = Utility.DistancePoint2Set(body_points[i], attach_points); dis_body.Add(new OrderItem(dis, i)); } dis_body = dis_body.OrderBy(x => x.value).ToList(); for (int i = 0; i < dis_body.Count * 0.1; i++) { double dis_to_center = Vector2.Distance(body_points[dis_body[i].index], attach_center); if (dis_to_center < mindis_center) { mindis_center = dis_to_center; closest_body_point_to_center = body_points[dis_body[i].index]; } } Image <Gray, byte> guess_face = this.body_img.CopyBlank(); //float guess_radius = 20f * body_img.Height / 600f; float guess_radius = 10f * body_img.Height / 600f; do { guess_radius *= 1.1f; guess_face = this.body_img.CopyBlank(); guess_face.Draw(new CircleF(new PointF(closest_body_point_to_center.x, closest_body_point_to_center.y), guess_radius), new Gray(255), -1); guess_face.Save("skeleton1guessface" + guess_radius + ".png"); }while (IExtension.GetBoundary(guess_face).Count == 0); CvInvoke.BitwiseAnd(guess_face, body_img, guess_face); if (debug) { guess_face.Save("skeleton1guessface.png"); } this.face_img = new List <Image <Gray, byte> >(); this.face_img.Add(guess_face); }
public void IsolateInstance() { #region classify for (int i = 0; i < img.Height; i++) { for (int j = 0; j < img.Width; j++) { Label pixellabel = ClassifyPixelColor(img[i, j]); // if this pixel is foreground if (pixellabel != Label.Background && pixellabel != Label.None) { int instance_idx = instance_color.IndexOf(img[i, j]); // this pixel belongs to which instance if (instance_idx == -1) { instance_color.Add(img[i, j]); instance.Add(new List <Vector2>()); instance_label.Add(pixellabel); instance[instance.Count - 1].Add(new Vector2(j, i)); } else { instance[instance_idx].Add(new Vector2(j, i)); } } } } #endregion #region check valid for (int i = 0; i < instance.Count; i++) { if (!IsInstanceValid(instance[i])) { instance.RemoveAt(i); instance_label.RemoveAt(i); instance_color.RemoveAt(i); i--; } } #endregion #region Boundary extraction & seperate body with others List <List <Vector2> > body = new List <List <Vector2> >(); List <List <Vector2> > body_boundary = new List <List <Vector2> >(); List <Label> body_label = new List <Label>(); for (int i = 0; i < instance.Count; i++) { //Image<Rgb, byte> instance_img = img.CopyBlank(); //for (int j = 0; j < instance[i].Count; j++) // instance_img[(int)instance[i][j].y, (int)instance[i][j].x] = new Rgb(255, 255, 255); //instance_img.Save(instance_label[i].ToString() + "_" + i.ToString() + ".png"); if (instance_label[i] == Label.CubeBody || instance_label[i] == Label.CylinderBody) { body.Add(new List <Vector2>(instance[i])); body_label.Add(instance_label[i]); body_boundary.Add(IExtension.GetBoundary(instance[i], img.Width, img.Height)); instance.RemoveAt(i); instance_label.RemoveAt(i); instance_color.RemoveAt(i); i--; } else { instance_boundary.Add(IExtension.GetBoundary(instance[i], img.Width, img.Height)); } } #endregion #region create geometry for (int i = 0; i < body.Count; i++) { if (body_label[i] == Label.CubeBody) { Geometry a_cuboid = new Geometry(img.Width, img.Height, Label.Cube); a_cuboid.SetInitialBody(body[i]); geometries.Add(a_cuboid); //geometries.Last().GetBodyImage().Save("cube_body.png"); } else if (body_label[i] == Label.CylinderBody) { Geometry a_cylinder = new Geometry(img.Width, img.Height, Label.Cylinder); a_cylinder.SetInitialBody(body[i]); geometries.Add(a_cylinder); //geometries.Last().GetBodyImage().Save("cylinder_body.png"); } } #endregion }
public List <Vector2> GetBoundaryPoints() { return(IExtension.GetBoundary(body, width, height)); }
private List <Vector2> ApproximateCurveAxis(List <Line2> skel_lines) { Image <Rgb, byte> curveaxis_img = body_img.Copy().Convert <Rgb, byte>(); List <Vector2> skel_points = new List <Vector2>(); //Image<Gray, byte> temp = face_img[0].Copy(); //var element = CvInvoke.GetStructuringElement(ElementShape.Cross, new Size(3, 3), new Point(-1, -1)); //CvInvoke.Dilate(temp, temp, element, new Point(-1, -1), 10, BorderType.Reflect, default(MCvScalar)); //CvInvoke.Subtract(ori_prune_img, temp, ori_prune_img); skel_points = IExtension.GetMaskPoints(ori_prune_img); for (int i = 0; i < skel_points.Count; i++) { if (ori_prune_img[(int)skel_points[i].y, (int)skel_points[i].x].Equals(new Gray(128))) { this.end_points.Add(i); } } List <Vector2> path_points = new List <Vector2>(); List <Vector2> top_mask_point = IExtension.GetMaskPoints(this.face_img[0]); Vector2 top_center = Utility.Average(top_mask_point); //double guess_radius = Math.Sqrt(top_mask_point.Count / Math.PI); Vector2 start_point = top_center; List <Vector2> attach_boundary = new List <Vector2>(); if (noface) { // Vector2 attach_center = Utility.Average(IExtension.GetBoundary(this.attach_img)); // start_point = attach_center; attach_boundary = IExtension.GetBoundary(this.attach_img); } // closest to top face center int startidx = 0; double mindis_topcenter = double.MaxValue; for (int i = 0; i < end_points.Count; i++) { double dis = double.MaxValue; if (noface) { dis = Utility.DistancePoint2Set(skel_points[end_points[i]], attach_boundary); } else { dis = Vector2.Distance(skel_points[end_points[i]], start_point); } if (dis < mindis_topcenter) { mindis_topcenter = dis; startidx = end_points[i]; } } path_points = FindLongestPath(skel_points, startidx); double diss = Vector2.Distance(path_points.First(), start_point); double dise = Vector2.Distance(path_points.Last(), start_point); if (dise < diss) { path_points.Reverse(); } path_points = IExtension.ResetPath(path_points, 20); // add first point if (!noface) { path_points.Insert(0, top_center); // extend ending Line2 endray = new Line2(path_points[path_points.Count - 2], path_points[path_points.Count - 1]); path_points.Add(endray.GetPointwithT((float)endray.Length() * 10)); //reset path to 3 path_points = IExtension.ResetPath(path_points, 3); } else { path_points = IExtension.ResetPath(path_points, 3); path_points.RemoveRange(0, (int)(0.05 * path_points.Count)); //path_points.Insert(0, top_center); } #region visualize curveaxis_img = body_img.Copy().Convert <Rgb, byte>(); for (int i = 0; i < path_points.Count; i++) { curveaxis_img.Draw(new CircleF(new PointF(path_points[i].x, path_points[i].y), 2.0f), new Rgb(255, 0, i * 2), 1); } curveaxis_img.Draw(new CircleF(new PointF(path_points[0].x, path_points[0].y), 2.0f), new Rgb(0, 255, 0), 1); curveaxis_img.Save(index_forname.ToString() + this.label_forname.ToString() + "_axis_curve.png"); #endregion return(path_points); }
private Line2 ApproximateFromCubeTop() { #region get corner points // get corner points VectorOfVectorOfPoint con = new VectorOfVectorOfPoint(); Image <Gray, byte> img_copy = this.face_img[0].Copy(); CvInvoke.FindContours(img_copy, con, img_copy, RetrType.Ccomp, ChainApproxMethod.ChainApproxSimple); int maxcomp = 0, max_con_idx = -1; for (int i = 0; i < con.Size; i++) { if (con[i].Size > maxcomp) { maxcomp = con[i].Size; max_con_idx = i; } } // found max component's contour // simplify contours VectorOfPoint con2 = new VectorOfPoint(); con2 = con[max_con_idx]; double alpha = 0.01; // 越小越接近曲线 int iter = 0; List <Vector2> corner_points = new List <Vector2>(); while (con2.Size != 4) { if (iter++ > 200) { break; } double epsilon = alpha * CvInvoke.ArcLength(con[max_con_idx], true); CvInvoke.ApproxPolyDP(con[max_con_idx], con2, epsilon, true); if (con2.Size > 4) { alpha += 0.01; corner_points.Clear(); for (int i = 0; i < con2.Size; i++) { corner_points.Add(new Vector2(con2[i].X, con2[i].Y)); } } if (con2.Size < 4) { alpha -= 0.003; } } if (con2.Size == 4) { corner_points.Clear(); for (int i = 0; i < con2.Size; i++) { corner_points.Add(new Vector2(con2[i].X, con2[i].Y)); } } else { int removei = corner_points.Count - 4; for (int i = 0; i < removei; i++) { corner_points.RemoveAt(1); } } face_center = new List <Vector2>(); face_center.Add(Utility.Average(corner_points)); List <Vector2> boundary2_face = IExtension.GetBoundary(this.face_img[0]); List <Vector2> boundary2_body = ExtractOutline(this.body_img, boundary2_face); int[] i_corner = SelectTwoCorners(corner_points, boundary2_body, this.body_img); #endregion // body img fit line Image <Gray, byte> temp = body_img.Copy(); Image <Gray, byte> body_bound = temp.Canny(60, 100); LineSegment2D[] lines = body_bound.HoughLinesBinary( 1, //Distance resolution in pixel-related units Math.PI / 180.0, //Angle resolution measured in radians. 3, //threshold 4, //min Line width 1 //gap between lines )[0]; //Get the lines from the first channel var element = CvInvoke.GetStructuringElement(ElementShape.Cross, new Size(3, 3), new Point(-1, -1)); CvInvoke.Dilate(this.face_img[0], temp, element, new Point(-1, -1), 30, BorderType.Reflect, default(MCvScalar)); //temp.Save("face_dilate.png"); Image <Gray, byte> lineimg = temp.CopyBlank(); List <Line2> body_lines = new List <Line2>(); foreach (LineSegment2D line in lines) { if (!temp[line.P1.Y, line.P1.X].Equals(new Gray(255)) && !temp[line.P2.Y, line.P2.X].Equals(new Gray(255))) { body_lines.Add(new Line2(new Vector2(line.P1.X, line.P1.Y), new Vector2(line.P2.X, line.P2.Y))); lineimg.Draw(line, new Gray(255), 2); } } //lineimg.Save("body_line.png"); /// use corner points to find lines double mindis0 = double.MaxValue, mindis1 = double.MaxValue; int line0 = -1, line1 = -1; for (int i = 0; i < body_lines.Count; i++) { double dis0 = Mathf.Min(Vector2.Distance(corner_points[i_corner[0]], body_lines[i].start), Vector2.Distance(corner_points[i_corner[0]], body_lines[i].end)); double dis1 = Mathf.Min(Vector2.Distance(corner_points[i_corner[1]], body_lines[i].start), Vector2.Distance(corner_points[i_corner[1]], body_lines[i].end)); if (dis0 < mindis0) { mindis0 = dis0; line0 = i; } if (dis1 < mindis1) { mindis1 = dis1; line1 = i; } } // find similar // straight line Line2 body_line0 = FitCloseLine(body_lines, body_lines[line0], 50); Line2 body_line1 = FitCloseLine(body_lines, body_lines[line1], 50); if (Vector2.Distance(corner_points[i_corner[0]], body_line0.start) < Vector2.Distance(corner_points[i_corner[0]], body_line0.end)) { body_line0.Flip(); } if (Vector2.Distance(corner_points[i_corner[1]], body_line1.start) < Vector2.Distance(corner_points[i_corner[1]], body_line1.end)) { body_line1.Flip(); } Vector2 meandir = (body_line0.dir + body_line1.dir).normalized; Line2 top_normal_line = new Line2(face_center.First(), meandir, true); Vector2 online_point = top_normal_line.GetPointwithT(Vector2.Distance(corner_points[0], corner_points[1])); 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(); } top_normal_line.UpdateEnd(new Vector2(500, 500)); top_normal_line.UpdateEnd(new Vector2(0, 0)); if (debug) { Image <Rgb, byte> cube_outline = this.body_img.Copy().Convert <Rgb, byte>(); cube_outline.Draw(new CircleF(new PointF(corner_points[i_corner[0]].x, corner_points[i_corner[0]].y), 10.0f), new Rgb(255, 0, 0), 1); cube_outline.Draw(new CircleF(new PointF(corner_points[i_corner[1]].x, corner_points[i_corner[1]].y), 10.0f), new Rgb(255, 0, 0), 1); cube_outline.Draw(new CircleF(new PointF(corner_points[0].x, corner_points[0].y), 8), new Rgb(0, 0, 255), 1); cube_outline.Draw(new CircleF(new PointF(corner_points[1].x, corner_points[1].y), 8), new Rgb(0, 0, 255), 1); cube_outline.Draw(new CircleF(new PointF(corner_points[2].x, corner_points[2].y), 8), new Rgb(0, 0, 255), 1); cube_outline.Draw(new CircleF(new PointF(corner_points[3].x, corner_points[3].y), 8), new Rgb(0, 0, 255), 1); cube_outline.Draw(body_lines[line0].ToLineSegment2D(), new Rgb(0, 255, 0), 3); cube_outline.Draw(body_lines[line1].ToLineSegment2D(), new Rgb(0, 255, 0), 3); cube_outline.Draw(body_line0.ToLineSegment2D(), new Rgb(0, 255, 255), 3); cube_outline.Draw(body_line1.ToLineSegment2D(), new Rgb(0, 0, 255), 3); cube_outline.Save("cube_outline.png"); Image <Gray, byte> approx_top = this.body_img.Copy(); foreach (Vector2 v in top_normal_line.SamplePoints()) { approx_top.Draw(new CircleF(new PointF(v.x, v.y), 2.0f), new Gray(0), 1); } approx_top.Save("approx.png"); } return(top_normal_line); }