Преобразование между координатами OpenCVSharp и System.Drawing Coordinates - PullRequest
4 голосов
/ 21 мая 2019

Я немного застрял в этом:

Я пытаюсь преобразовать прямоугольник, созданный двумя OpenCvSharp.Points, в System.Drawing.Rectangle.

Я нашел интересную область в OpenCvSharp ия хочу сохранить этот регион в качестве нового растрового изображения для отображения в PictureBox или что-то в этом роде.

public static Mat Detect(string filename)
        {
            var cfg = "4000.cfg";
            var model = "4000.weights"; //YOLOv2 544x544
            var threshold = 0.3;

            var mat = Cv2.ImRead(filename);
            var w = mat.Width;
            var h = mat.Height;
            var blob = CvDnn.BlobFromImage(mat, 1 / 255.0, new OpenCvSharp.Size(416, 416), new Scalar(), true, false);
            var net = CvDnn.ReadNetFromDarknet(Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, cfg), Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, model));
            net.SetInput(blob, "data");

            Stopwatch sw = new Stopwatch();
            sw.Start();
            var prob = net.Forward(); // Process NeuralNet
            sw.Stop();
            Console.WriteLine($"Runtime:{sw.ElapsedMilliseconds} ms");


            const int prefix = 5;   //skip 0~4

            for (int i = 0; i < prob.Rows; i++)
            {
                var confidence = prob.At<float>(i, 4);
                if (confidence > threshold)
                {
                    //get classes probability
                    Cv2.MinMaxLoc(prob.Row[i].ColRange(prefix, prob.Cols), out _, out OpenCvSharp.Point max);
                    var classes = max.X;
                    var probability = prob.At<float>(i, classes + prefix);

                    if (probability > threshold) //more accuracy
                    {
                        //get center and width/height
                        var centerX = prob.At<float>(i, 0) * w;
                        var centerY = prob.At<float>(i, 1) * h;
                        var width = prob.At<float>(i, 2) * w;
                        var height = prob.At<float>(i, 3) * h;
                        //label formating
                        var label = $"{Labels[classes]} {probability * 100:0.00}%";
                        Console.WriteLine($"confidence {confidence * 100:0.00}% {label}");
                        var x1 = (centerX - width / 2) < 0 ? 0 : centerX - width / 2; //avoid left side over edge
                        //draw result
                        mat.Rectangle(new OpenCvSharp.Point(x1, centerY - height / 2), new OpenCvSharp.Point(centerX + width / 2, centerY + height / 2), Colors[classes], 2);
                        var textSize = Cv2.GetTextSize(label, HersheyFonts.HersheyTriplex, 0.5, 1, out var baseline);
                        Cv2.Rectangle(mat, new Rect(new OpenCvSharp.Point(x1, centerY - height / 2 - textSize.Height - baseline),
                                new OpenCvSharp.Size(textSize.Width, textSize.Height + baseline)), Colors[classes], Cv2.FILLED);
                        Cv2.PutText(mat, label, new OpenCvSharp.Point(x1, centerY - height / 2 - baseline), HersheyFonts.HersheyTriplex, 0.5, Scalar.Black);
                    }
                }
            }
            return mat;
        }

По сути, нужен этот OpenCvSharp Rect, который рисуется в мат в виде единого растрового изображения для отображения в картинке

Это линия, где прямоугольникнарисованный mat.Rectangle (новый OpenCvSharp.Point (x1, centerY - высота / 2), новый OpenCvSharp.Point (centerX + ширина / 2, centerY + высота / 2), цвета [классы], 2);

Кто-нибудь может мне помочь с этим?Мне очень жаль моего плохого английского!

Ответы [ 2 ]

2 голосов
/ 24 мая 2019
var centerX = prob.At<float>(i, 0) * w;
var centerY = prob.At<float>(i, 1) * h;
var width = prob.At<float>(i, 2) * w;
var height = prob.At<float>(i, 3) * h;
var top  =(centerY - height / 2) < 0 ? 0 : centerY - height  / 2;
var left =(centerX - width / 2) < 0 ? 0 : centerX - width / 2;
//just put x,y,w,h in the bounding rect
//make sure x,y,w,h will not crop the outside of the exising image
var targetbox  = Cv2.BoundingRect(left,top,width,height);

var output_mat = new Mat(input_image, targetbox); //Crop the image

Bitmap output_mat_in_bitmap = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(output_mat);

output_mat_in_bitmap - это требуемая битовая карта.Я думаю

0 голосов
/ 24 мая 2019

Если есть возможность просто преобразовать весь объект Mat - OpenCvSharp (https://github.com/shimat/opencvsharp) включает в себя ряд утилит и расширений - в частности, одну, которая позволяет прямое преобразование из Mat в Bitmap См. Этопример https://github.com/shimat/opencvsharp/wiki/Converting-Image

...