コード例 #1
0
    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);
        //}
    }
コード例 #2
0
    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);
    }
コード例 #3
0
    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);
    }
コード例 #4
0
    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);
    }
コード例 #5
0
    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
    }
コード例 #6
0
 public List <Vector2> GetBoundaryPoints()
 {
     return(IExtension.GetBoundary(body, width, height));
 }
コード例 #7
0
    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);
    }
コード例 #8
0
    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);
    }