예제 #1
0
        /// <summary>
        /// Return the ground truth ellipse's parameters from the CSV file.
        /// </summary>
        /// <param name="imageFilename">Filename of the image</param>
        /// <param name="csvFilepath">Filepath to the CSV file with ground truth ellipses' parameters</param>
        /// <returns>Ground truth ellipse's parameters</returns>
        private static GtEllipse GetGtEllipseFromCsv(string imageFilename, string csvFilepath)
        {
            using (StreamReader sr = new StreamReader(csvFilepath))
            {
                GtEllipse gtEllipse;
                string    line;
                sr.ReadLine();  // skip the header
                while ((line = sr.ReadLine()) != null)
                {
                    string[] columns = line.Split(',');
                    if (string.Compare(columns[0], imageFilename) == 0)
                    {
                        if (string.IsNullOrEmpty(columns[1]))
                        {
                            gtEllipse = null;
                        }
                        else
                        {
                            Point2f center    = new Point2f(Convert.ToSingle(columns[1]), Convert.ToSingle(columns[2]));
                            Size2f  axes      = new Size2f(Convert.ToSingle(columns[3]), Convert.ToSingle(columns[4]));
                            float   angle     = Convert.ToSingle(columns[5]);
                            Size    imageSize = new Size(Convert.ToInt32(columns[6]), Convert.ToInt32(columns[7]));

                            gtEllipse = new GtEllipse(center, axes, angle, imageSize);
                        }
                        return(gtEllipse);
                    }
                    ;
                }
                throw new Exception("Filename not found in the CSV file.");
            }
        }
    static void EllipseEx(Texture2D img, Vector2 center, Size2f axes, int angle, int arc_start, int arc_end, Color color)
    {
        axes.width  = Mathf.Abs(axes.width);
        axes.height = Mathf.Abs(axes.height);

        int delta = 5;

        List <Vector2> _v = ellipse2Poly(center, axes, angle, arc_start, arc_end, delta);

        List <Vector2Int> v      = new List <Vector2Int>();
        Vector2Int        prevPt = new Vector2Int(0xFFFF, 0xFFFF);

        for (int i = 0; i < _v.Count; ++i)
        {
            Vector2Int pt = new Vector2Int();
            pt.x  = Mathf.RoundToInt(_v[i].x / XY_ONE) << XY_SHIFT;
            pt.y  = Mathf.RoundToInt(_v[i].y / XY_ONE) << XY_SHIFT;
            pt.x += Mathf.RoundToInt(_v[i].x - pt.x);
            pt.y += Mathf.RoundToInt(_v[i].y - pt.y);
            if (pt != prevPt)
            {
                v.Add(pt);
                prevPt = pt;
            }
        }

        FillConvexPoly(img, v, v.Count, 0, color);
    }
        void Canvas_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.PageUp)
            {
                ImageScale += ScaleIncrement;
            }
            if (e.KeyCode == Keys.PageDown)
            {
                ImageScale -= ScaleIncrement;
            }
            if (e.Control && e.KeyCode == Keys.Z)
            {
                commandExecutor.Undo();
            }
            if (e.Control && e.KeyCode == Keys.Y)
            {
                commandExecutor.Redo();
            }
            if (e.Control && e.KeyCode == Keys.V)
            {
                var roiText = (string)Clipboard.GetData(DataFormats.Text);
                try
                {
                    var mousePosition = PointToClient(MousePosition);
                    var offset        = NormalizedLocation(mousePosition.X, mousePosition.Y);
                    var roiData       = (float[])ArrayConvert.ToArray(roiText, 1, typeof(float));
                    var center        = new Point2f(offset.X, offset.Y);
                    var size          = new Size2f(roiData[0], roiData[1]);
                    var roi           = new RotatedRect(center, size, 0);

                    var selection = selectedRoi;
                    commandExecutor.Execute(
                        () => AddRegion(roi),
                        () => { regions.Remove(roi); SelectedRegion = selection; });
                }
                catch (ArgumentException) { }
                catch (InvalidCastException) { }
                catch (FormatException) { }
            }

            if (selectedRoi.HasValue)
            {
                if (e.Control && e.KeyCode == Keys.C)
                {
                    var roi     = regions[selectedRoi.Value];
                    var roiData = new[] { roi.Size.Width, roi.Size.Height };
                    Clipboard.SetData(DataFormats.Text, ArrayConvert.ToString(roiData));
                }

                if (e.KeyCode == Keys.Delete)
                {
                    var selection = selectedRoi.Value;
                    var region    = regions[selection];
                    commandExecutor.Execute(
                        () => { regions.RemoveAt(selection); SelectedRegion = null; },
                        () => { regions.Insert(selection, region); SelectedRegion = selection; });
                }
            }
        }
예제 #4
0
        public void Size2f()
        {
            var obj = new Size2f(0.5, 0.5);

            Assert.Equal(0.5, obj.Width, 6);
            Assert.Equal(0.5, obj.Height, 6);

            obj = new Size2f(0.5f, 0.5f);
            Assert.Equal(0.5f, obj.Width, 6);
            Assert.Equal(0.5f, obj.Height, 6);
        }
        static RotatedRect ScaleRegion(RotatedRect region, Point target, bool uniformScaling)
        {
            var size = new Size2f(
                2 * Math.Abs(target.X - region.Center.X),
                2 * Math.Abs(target.Y - region.Center.Y));

            if (uniformScaling)
            {
                var sizeNorm = (float)Math.Sqrt(size.Width * size.Width + size.Height * size.Height);
                region.Size.Width  = sizeNorm;
                region.Size.Height = sizeNorm;
            }
            else
            {
                region.Size = size;
            }
            return(region);
        }
예제 #6
0
 /// <summary>
 /// 旋转
 /// </summary>
 /// <param name="image">图片对象</param>
 /// <param name="angle">角度</param>
 /// <returns>旋转后的图像</returns>
 public static Image Rotate(this Image image, float angle)
 {
     using (Mat dst = new Bitmap(image).ToMat())
     {
         Point2f center = new Point2f(dst.Cols / 2, dst.Rows / 2);
         using (Mat rot = Cv2.GetRotationMatrix2D(center, -angle, 1))
         {
             Size2f s2f = new Size2f(dst.Size().Width, dst.Size().Height);
             Rect   box = new RotatedRect(new Point2f(0, 0), s2f, -angle).BoundingRect();
             double xx = rot.At <double>(0, 2) + box.Width / 2 - dst.Cols / 2, zz = rot.At <double>(1, 2) + box.Height / 2 - dst.Rows / 2;
             rot.Set(0, 2, xx);
             rot.Set(1, 2, zz);
             Cv2.WarpAffine(dst, dst, rot, box.Size);
             GC.SuppressFinalize(s2f);
             GC.SuppressFinalize(box);
             GC.SuppressFinalize(xx);
             GC.SuppressFinalize(zz);
             GC.Collect();
             GC.WaitForPendingFinalizers();
             return(dst.ToBitmap());
         }
     }
 }
예제 #7
0
 public static extern ExceptionStatus core_FileStorage_shift_Size2f(IntPtr fs, Size2f val);
예제 #8
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="box"></param>
 public RotatedRect(CvBox2D box)
 {
     Center = box.Center;
     Size = box.Size;
     Angle = box.Angle;
 }
예제 #9
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="center"></param>
 /// <param name="size"></param>
 /// <param name="angle"></param>
 public RotatedRect(Point2f center, Size2f size, float angle)
 {
     Center = center;
     Size = size;
     Angle = angle;
 }
 public static extern ExceptionStatus core_Mat_push_back_Size2f(IntPtr self, Size2f v);
    public void DewIt() // demo function
    {
        Texture2D tex = new Texture2D(1080, 2168, TextureFormat.RGBA32, false);

        Color fillColor = new Color(0, 0, 0, 0);

        Color [] fillColorArray = tex.GetPixels();
        for (var i = 0; i < fillColorArray.Length; ++i)
        {
            fillColorArray[i] = fillColor;
        }
        tex.SetPixels(fillColorArray);

        List <Vector2Int> points = new List <Vector2Int>();

        points.Add(new Vector2Int(158, 1101));
        points.Add(new Vector2Int(158, 1108));
        points.Add(new Vector2Int(165, 1198));
        points.Add(new Vector2Int(178, 1281));
        points.Add(new Vector2Int(199, 1363));
        points.Add(new Vector2Int(239, 1434));
        points.Add(new Vector2Int(297, 1490));
        points.Add(new Vector2Int(365, 1531));
        points.Add(new Vector2Int(442, 1569));
        points.Add(new Vector2Int(529, 1528));
        points.Add(new Vector2Int(613, 1572));
        points.Add(new Vector2Int(682, 1537));
        points.Add(new Vector2Int(744, 1493));
        points.Add(new Vector2Int(793, 1436));
        points.Add(new Vector2Int(818, 1366));
        points.Add(new Vector2Int(830, 1289));
        points.Add(new Vector2Int(839, 1209));
        points.Add(new Vector2Int(842, 1124));
        points.Add(new Vector2Int(841, 1089));
        points.Add(new Vector2Int(158, 1101));

        float time = Time.realtimeSinceStartup;

        DrawPolygon(tex, points, includeColor);
        Debug.Log("Execution time of DrawPolygon 1 is " + (Time.realtimeSinceStartup - time));

        Vector2 center = new Vector2(499, 1094);
        Size2f  axes   = new Size2f(341, 375);

        time = Time.realtimeSinceStartup;
        EllipseEx(tex, center, axes, 0, 180, 360, includeColor);
        Debug.Log("Execution time of EllipseEx 1 is " + (Time.realtimeSinceStartup - time));

        Vector2 center2 = new Vector2(390, 1096);
        Size2f  axes2   = new Size2f(73, 32);

        time = Time.realtimeSinceStartup;
        EllipseEx(tex, center2, axes2, 0, 0, 360, excludeColor);
        Debug.Log("Execution time of EllipseEx 2 is " + (Time.realtimeSinceStartup - time));

        Vector2 center3 = new Vector2(688, 1091);
        Size2f  axes3   = new Size2f(69, 33);

        time = Time.realtimeSinceStartup;
        EllipseEx(tex, center3, axes3, 0, 0, 360, excludeColor);
        Debug.Log("Execution time of EllipseEx 3 is " + (Time.realtimeSinceStartup - time));

        points.Clear();
        points.Add(new Vector2Int(247, 1044));
        points.Add(new Vector2Int(295, 996));
        points.Add(new Vector2Int(363, 979));
        points.Add(new Vector2Int(433, 989));
        points.Add(new Vector2Int(497, 1018));
        points.Add(new Vector2Int(498, 1052));
        points.Add(new Vector2Int(434, 1021));
        points.Add(new Vector2Int(363, 1008));
        points.Add(new Vector2Int(295, 1022));
        points.Add(new Vector2Int(247, 1067));
        points.Add(new Vector2Int(247, 1044));

        time = Time.realtimeSinceStartup;
        DrawPolygon(tex, points, excludeColor);
        Debug.Log("Execution time of DrawPolygon 2 is " + (Time.realtimeSinceStartup - time));

        points.Clear();
        points.Add(new Vector2Int(585, 1011));
        points.Add(new Vector2Int(641, 986));
        points.Add(new Vector2Int(701, 977));
        points.Add(new Vector2Int(762, 987));
        points.Add(new Vector2Int(804, 1028));
        points.Add(new Vector2Int(804, 1051));
        points.Add(new Vector2Int(762, 1010));
        points.Add(new Vector2Int(701, 1000));
        points.Add(new Vector2Int(641, 1009));
        points.Add(new Vector2Int(585, 1034));
        points.Add(new Vector2Int(585, 1011));

        time = Time.realtimeSinceStartup;
        DrawPolygon(tex, points, excludeColor);
        Debug.Log("Execution time of DrawPolygon 3 is " + (Time.realtimeSinceStartup - time));

        tex.Apply();

        GetComponent <RawImage>().texture = tex;
    }
예제 #12
0
 public Ellipse(Point2f center, Size2f axes, float angle)
 {
     Center = center;
     Axes   = axes;
     Angle  = angle;
 }
예제 #13
0
 public static extern ExceptionStatus core_FileNode_read_Size2f(IntPtr node, out Size2f returnValue);
예제 #14
0
 static OpenCvSharp.Size ToSize(Size2f size)
 {
     return(new OpenCvSharp.Size(size.Width, size.Height));
 }
예제 #15
0
 public static extern void core_Mat_push_back_Size2f(IntPtr self, Size2f v);
예제 #16
0
 public GtEllipse(Point2f center, Size2f axes, float angle, Size imageSize) : base(center, axes, angle)
 {
     ImageSize = imageSize;
 }
    static List <Vector2> ellipse2Poly(Vector2 center, Size2f axes, int angle, int arc_start, int arc_end, int delta)
    {
        List <Vector2> points = new List <Vector2>();

        float alpha, beta;
        int   i;

        while (angle < 0)
        {
            angle += 360;
        }
        while (angle > 360)
        {
            angle -= 360;
        }

        if (arc_start > arc_end)
        {
            i         = arc_start;
            arc_start = arc_end;
            arc_end   = i;
        }
        while (arc_start < 0)
        {
            arc_start += 360;
            arc_end   += 360;
        }
        while (arc_end > 360)
        {
            arc_end   -= 360;
            arc_start -= 360;
        }
        if (arc_end - arc_start > 360)
        {
            arc_start = 0;
            arc_end   = 360;
        }

        sincos(angle, out alpha, out beta);

        points.Clear();

        for (i = arc_start; i < arc_end + delta; i += delta)
        {
            float x, y;
            angle = i;
            if (angle > arc_end)
            {
                angle = arc_end;
            }
            if (angle < 0)
            {
                angle += 360;
            }

            x = axes.width * SinTable[450 - angle];
            y = axes.height * SinTable[angle];
            Vector2 pt;
            pt.x = center.x + x * alpha - y * beta;
            pt.y = center.y + x * beta + y * alpha;
            points.Add(pt);
        }

        return(points);
    }
        public ExtractRectangleAction()
        {
            Name   = "Extract rectangle";
            Action = (input) =>
            {
                input.FindContours(out var contours, out var hierarchy, RetrievalModes.List, ContourApproximationModes.ApproxNone);

                var m = input.CvtColor(ColorConversionCodes.GRAY2BGR);

                var imageArea = m.Width * m.Height;

                var allContoursSelect = from contour in contours
                                        let boundingRect = Cv2.MinAreaRect(contour)
                                                           let boundingRectArea = boundingRect.Size.Width * boundingRect.Size.Height
                                                                                  let convexHull = Cv2.ConvexHull(contour)
                                                                                                   let hullArea = Cv2.ContourArea(convexHull)
                                                                                                                  let contourPercentage                                                        = hullArea / boundingRectArea
                                                                                                                                                                let wtoh                       = boundingRect.Size.Width / boundingRect.Size.Height
                                                                                                                                                                                      let htow = boundingRect.Size.Height / boundingRect.Size.Width
                                                                                                                                                                                                 select new
                {
                    boundingRect.Center,
                    Wtoh         = wtoh,
                    Htow         = htow,
                    ImageArea    = hullArea / imageArea,
                    BoundingRect = boundingRect,
                    Pixels       = boundingRect.Size.Width * boundingRect.Size.Height,
                    ContourPerc  = contourPercentage,
                    ConvexHull   = convexHull,
                    HullArea     = hullArea,
                    RectArea     = boundingRect.Size.Width * boundingRect.Size.Height
                };

                if (this.EnableFilters)
                {
                    allContoursSelect = allContoursSelect
                                        .Where(i => i.Pixels >= this.MinRectPixels && i.Pixels <= this.MaxRectPixels &&
                                               i.ContourPerc >= this.MinRectShapeArea &&
                                               (Math.Abs(i.Wtoh - this.WidthToHeightRatio) <= this.WidthToHeightRatioDeviation ||
                                                Math.Abs(i.Htow - this.WidthToHeightRatio) <= this.WidthToHeightRatioDeviation));

                    switch (this.SelectionMode)
                    {
                    case RectangleSelectionMode.MostNorth:
                        allContoursSelect = allContoursSelect.OrderByDescending(c => c.Center.Y);
                        break;

                    case RectangleSelectionMode.MostSouth:
                        allContoursSelect = allContoursSelect.OrderBy(c => c.Center.Y);
                        break;

                    case RectangleSelectionMode.MostEast:
                        allContoursSelect = allContoursSelect.OrderByDescending(c => c.Center.Y);
                        break;

                    case RectangleSelectionMode.MostWest:
                        allContoursSelect = allContoursSelect.OrderBy(c => c.Center.Y);
                        break;

                    case RectangleSelectionMode.BiggestBoundingRectArea:
                        allContoursSelect = allContoursSelect.OrderBy(c => c.RectArea);
                        break;

                    case RectangleSelectionMode.SmallestBoundingRectArea:
                        allContoursSelect = allContoursSelect.OrderByDescending(c => c.RectArea);
                        break;

                    case RectangleSelectionMode.BiggestConvexHullArea:
                        allContoursSelect = allContoursSelect.OrderBy(c => c.HullArea);
                        break;

                    case RectangleSelectionMode.SmallestConvexHullArea:
                        allContoursSelect = allContoursSelect.OrderByDescending(c => c.HullArea);
                        break;

                    default:
                        throw new Exception($"Missing mode handling: {this.SelectionMode}");
                    }
                }

                var allContours = allContoursSelect
                                  .ToArray();

                this.Status       = $"{allContours.Length} found ({contours.Length} unfiltered)";
                this.DetectedRect = string.Empty;

                if (allContours.Length == 0)
                {
                    throw new Exception("No contours found that match the criteria.");
                }

                var contourOfInterest = allContours.Last();
                this.DetectedRect = $"ImageArea: {contourOfInterest.ImageArea}\n" +
                                    $"Pixels: {contourOfInterest.Pixels:F0}\n" +
                                    $"RectShapeArea: {contourOfInterest.ContourPerc:P2}\n" +
                                    $"WidthToHeight: {contourOfInterest.Wtoh}\n" +
                                    $"HeightToWidth: {contourOfInterest.Htow}";

                if (!this.Crop)
                {
                    // Draw contours.
                    foreach (var contour in allContours)
                    {
                        var color = contour == contourOfInterest ? Scalar.Green : Scalar.Red;

                        m.Polylines(new[] { contour.BoundingRect.Points().Select(p => new Point(p.X, p.Y)) }, isClosed: true, color);
                        m.DrawContours(new[] { contour.ConvexHull }, 0, color);
                    }

                    input.Dispose();
                    return(m);
                }

                // Crop!
                var angle = contourOfInterest.BoundingRect.Angle;
                var size  = contourOfInterest.BoundingRect.Size;
                if (angle < -45)
                {
                    angle += 90.0f;
                    size   = new Size2f(size.Height, size.Width);
                }

                var rotMatrix = Cv2.GetRotationMatrix2D(contourOfInterest.BoundingRect.Center, angle, 1.0);
                var warped    = m.WarpAffine(rotMatrix, m.Size(), InterpolationFlags.Cubic);
                input.Dispose();
                m.Dispose();
                return(warped.GetRectSubPix(new Size(size.Width, size.Height), contourOfInterest.BoundingRect.Center));
            };
        }