Пример #1
0
        private static int DetectYoloV3(NcnnDotNet.OpenCV.Mat bgr, List <Object> objects)
        {
            using (var yolov3 = new Net())
            {
                if (Ncnn.IsSupportVulkan)
                {
                    yolov3.Opt.UseVulkanCompute = true;
                }

                // original pretrained model from https://github.com/eric612/MobileNet-YOLO
                // param : https://drive.google.com/open?id=1V9oKHP6G6XvXZqhZbzNKL6FI_clRWdC-
                // bin : https://drive.google.com/open?id=1DBcuFCr-856z3FRQznWL_S5h-Aj3RawA
                // the ncnn model https://github.com/nihui/ncnn-assets/tree/master/models
                yolov3.LoadParam("mobilenetv2_yolov3.param");
                yolov3.LoadModel("mobilenetv2_yolov3.bin");

                const int targetSize = 352;

                var imgW = bgr.Cols;
                var imgH = bgr.Rows;

                using (var @in = Mat.FromPixelsResize(bgr.Data, PixelType.Bgr, bgr.Cols, bgr.Rows, targetSize, targetSize))
                {
                    var meanVals = new[] { 127.5f, 127.5f, 127.5f };
                    var normVals = new[] { 0.007843f, 0.007843f, 0.007843f };
                    @in.SubstractMeanNormalize(meanVals, normVals);

                    using (var ex = yolov3.CreateExtractor())
                    {
                        ex.SetNumThreads(4);

                        ex.Input("data", @in);

                        using (var @out = new Mat())
                        {
                            ex.Extract("detection_out", @out);

                            //     printf("%d %d %d\n", out.w, out.h, out.c);
                            objects.Clear();
                            for (var i = 0; i < @out.H; i++)
                            {
                                var values = @out.Row(i);

                                var @object = new Object();
                                @object.Label       = (int)values[0];
                                @object.Prob        = values[1];
                                @object.Rect.X      = values[2] * imgW;
                                @object.Rect.Y      = values[3] * imgH;
                                @object.Rect.Width  = values[4] * imgW - @object.Rect.X;
                                @object.Rect.Height = values[5] * imgH - @object.Rect.Y;

                                objects.Add(@object);
                            }
                        }
                    }
                }
            }

            return(0);
        }
Пример #2
0
        private static int DetectMobileNetV3(NcnnDotNet.OpenCV.Mat bgr, List <Object> objects)
        {
            using (var mobilenetV3 = new Net())
            {
                if (Ncnn.IsSupportVulkan)
                {
                    mobilenetV3.Opt.UseVulkanCompute = true;
                }

                // converted ncnn model from https://github.com/ujsyehao/mobilenetv3-ssd
                mobilenetV3.LoadParam("mobilenetv3_ssdlite_voc.param");
                mobilenetV3.LoadModel("mobilenetv3_ssdlite_voc.bin");

                const int targetSize = 300;

                var imgW = bgr.Cols;
                var imgH = bgr.Rows;

                using var @in = Mat.FromPixelsResize(bgr.Data, PixelType.Bgr2Rgb, bgr.Cols, bgr.Rows, targetSize, targetSize);
                var meanVals = new[] { 123.675f, 116.28f, 103.53f };
                var normVals = new[] { 1.0f, 1.0f, 1.0f };
                @in.SubstractMeanNormalize(meanVals, normVals);

                using var ex = mobilenetV3.CreateExtractor();
                ex.SetLiteMode(true);
                ex.SetNumThreads(4);

                ex.Input("input", @in);

                using var @out = new Mat();
                ex.Extract("detection_out", @out);

                //     printf("%d %d %d\n", out.w, out.h, out.c);
                objects.Clear();
                for (var i = 0; i < @out.H; i++)
                {
                    var values = @out.Row(i);

                    var @object = new Object();
                    @object.Label = (int)values[0];
                    @object.Prob  = values[1];

                    // filter out cross-boundary
                    var x1 = Clamp(values[2] * targetSize, 0.0f, targetSize - 1) / targetSize * imgW;
                    var y1 = Clamp(values[3] * targetSize, 0.0f, targetSize - 1) / targetSize * imgH;
                    var x2 = Clamp(values[4] * targetSize, 0.0f, targetSize - 1) / targetSize * imgW;
                    var y2 = Clamp(values[5] * targetSize, 0.0f, targetSize - 1) / targetSize * imgH;

                    @object.Rect.X      = x1;
                    @object.Rect.Y      = y1;
                    @object.Rect.Width  = x2 - x1;
                    @object.Rect.Height = y2 - y1;

                    objects.Add(@object);
                }
            }

            return(0);
        }
Пример #3
0
        private static int DetectYoloV2(NcnnDotNet.OpenCV.Mat bgr, List <Object> objects)
        {
            using (var yolov2 = new Net())
            {
                if (Ncnn.IsSupportVulkan)
                {
                    yolov2.Opt.UseVulkanCompute = true;
                }

                // original pretrained model from https://github.com/eric612/MobileNet-YOLO
                // https://github.com/eric612/MobileNet-YOLO/blob/master/models/yolov2/mobilenet_yolo_deploy.prototxt
                // https://github.com/eric612/MobileNet-YOLO/blob/master/models/yolov2/mobilenet_yolo_deploy_iter_80000.caffemodel
                // the ncnn model https://github.com/nihui/ncnn-assets/tree/master/models
                yolov2.LoadParam("mobilenet_yolo.param");
                yolov2.LoadModel("mobilenet_yolo.bin");

                const int targetSize = 416;

                var imgW = bgr.Cols;
                var imgH = bgr.Rows;

                using var @in = Mat.FromPixelsResize(bgr.Data, PixelType.Bgr, bgr.Cols, bgr.Rows, targetSize, targetSize);

                // the Caffe-YOLOv2-Windows style
                // X' = X * scale - mean
                var meanVals = new[] { 1.0f, 1.0f, 1.0f };
                var normVals = new[] { 0.007843f, 0.007843f, 0.007843f };
                @in.SubstractMeanNormalize(null, normVals);
                @in.SubstractMeanNormalize(meanVals, null);

                using var ex = yolov2.CreateExtractor();
                ex.SetNumThreads(4);

                ex.Input("data", @in);

                using var @out = new Mat();
                ex.Extract("detection_out", @out);

                //     printf("%d %d %d\n", out.w, out.h, out.c);
                objects.Clear();
                for (var i = 0; i < @out.H; i++)
                {
                    var values = @out.Row(i);

                    var @object = new Object();
                    @object.Label       = (int)values[0];
                    @object.Prob        = values[1];
                    @object.Rect.X      = values[2] * imgW;
                    @object.Rect.Y      = values[3] * imgH;
                    @object.Rect.Width  = values[4] * imgW - @object.Rect.X;
                    @object.Rect.Height = values[5] * imgH - @object.Rect.Y;

                    objects.Add(@object);
                }
            }

            return(0);
        }
Пример #4
0
        private static int DetectPeleeNet(NcnnDotNet.OpenCV.Mat bgr, List <Object> objects, NcnnDotNet.Mat resized)
        {
            using (var peleenet = new Net())
            {
                if (Ncnn.IsSupportVulkan)
                {
                    peleenet.Opt.UseVulkanCompute = true;
                }

                // model is converted from https://github.com/eric612/MobileNet-YOLO
                // and can be downloaded from https://drive.google.com/open?id=1Wt6jKv13sBRMHgrGAJYlOlRF-o80pC0g
                // the ncnn model https://github.com/nihui/ncnn-assets/tree/master/models
                peleenet.LoadParam("pelee.param");
                peleenet.LoadModel("pelee.bin");

                const int targetSize = 300;

                var imgW = bgr.Cols;
                var imgH = bgr.Rows;

                using var @in = Mat.FromPixelsResize(bgr.Data, PixelType.Bgr, bgr.Cols, bgr.Rows, targetSize, targetSize);
                var meanVals = new[] { 103.9f, 116.7f, 123.6f };
                var normVals = new[] { 0.017f, 0.017f, 0.017f };
                @in.SubstractMeanNormalize(meanVals, normVals);

                using var ex = peleenet.CreateExtractor();
                //ex.SetNumThreads(4);

                ex.Input("data", @in);

                using var @out = new Mat();
                ex.Extract("detection_out", @out);

                //     printf("%d %d %d\n", out.w, out.h, out.c);
                objects.Clear();
                for (var i = 0; i < @out.H; i++)
                {
                    var values = @out.Row(i);

                    var @object = new Object();
                    @object.Label       = (int)values[0];
                    @object.Prob        = values[1];
                    @object.Rect.X      = values[2] * imgW;
                    @object.Rect.Y      = values[3] * imgH;
                    @object.Rect.Width  = values[4] * imgW - @object.Rect.X;
                    @object.Rect.Height = values[5] * imgH - @object.Rect.Y;

                    objects.Add(@object);
                }

                using var segOut = new Mat();
                ex.Extract("sigmoid", segOut);
                Ncnn.ResizeBilinear(segOut, resized, imgW, imgH);
            }

            return(0);
        }
Пример #5
0
        private static int DetectMobileNetV2(NcnnDotNet.OpenCV.Mat bgr, List <Object> objects)
        {
            using (var mobilenetV2 = new Net())
            {
                if (Ncnn.IsSupportVulkan)
                {
                    mobilenetV2.Opt.UseVulkanCompute = true;
                }

                // ToDo: Support Custom Layer from C#
                //mobilenetV2.register_custom_layer("Silence", Noop_layer_creator);

                // original pretrained model from https://github.com/chuanqi305/MobileNetv2-SSDLite
                // https://github.com/chuanqi305/MobileNetv2-SSDLite/blob/master/ssdlite/voc/deploy.prototxt
                // the ncnn model https://github.com/nihui/ncnn-assets/tree/master/models
                mobilenetV2.LoadParam("mobilenetv2_ssdlite_voc.param");
                mobilenetV2.LoadModel("mobilenetv2_ssdlite_voc.bin");

                const int targetSize = 300;

                var imgW = bgr.Cols;
                var imgH = bgr.Rows;

                using var @in = Mat.FromPixelsResize(bgr.Data, PixelType.Bgr, bgr.Cols, bgr.Rows, targetSize, targetSize);
                var meanVals = new[] { 127.5f, 127.5f, 127.5f };
                var normVals = new[] { (float)(1.0 / 127.5), (float)(1.0 / 127.5), (float)(1.0 / 127.5) };
                @in.SubstractMeanNormalize(meanVals, normVals);

                using var ex = mobilenetV2.CreateExtractor();
                ex.SetLiteMode(true);
                ex.SetNumThreads(4);

                ex.Input("data", @in);

                using var @out = new Mat();
                ex.Extract("detection_out", @out);

                //     printf("%d %d %d\n", out.w, out.h, out.c);
                objects.Clear();
                for (var i = 0; i < @out.H; i++)
                {
                    var values = @out.Row(i);

                    var @object = new Object();
                    @object.Label       = (int)values[0];
                    @object.Prob        = values[1];
                    @object.Rect.X      = values[2] * imgW;
                    @object.Rect.Y      = values[3] * imgH;
                    @object.Rect.Width  = values[4] * imgW - @object.Rect.X;
                    @object.Rect.Height = values[5] * imgH - @object.Rect.Y;

                    objects.Add(@object);
                }
            }

            return(0);
        }
Пример #6
0
        private static int DetectSqueezeNet(NcnnDotNet.OpenCV.Mat bgr, List <Object> objects)
        {
            using (var squeezenet = new Net())
            {
                if (Ncnn.IsSupportVulkan)
                {
                    squeezenet.Opt.UseVulkanCompute = true;
                }

                // original pretrained model from https://github.com/chuanqi305/SqueezeNet-SSD
                // squeezenet_ssd_voc_deploy.prototxt
                // https://drive.google.com/open?id=0B3gersZ2cHIxdGpyZlZnbEQ5Snc
                // the ncnn model https://github.com/nihui/ncnn-assets/tree/master/models
                squeezenet.LoadParam("squeezenet_ssd_voc.param");
                squeezenet.LoadModel("squeezenet_ssd_voc.bin");

                const int targetSize = 300;

                var imgW = bgr.Cols;
                var imgH = bgr.Rows;

                using var @in = Mat.FromPixelsResize(bgr.Data, PixelType.Bgr, bgr.Cols, bgr.Rows, targetSize, targetSize);
                var meanVals = new[] { 104f, 117f, 123f };
                @in.SubstractMeanNormalize(meanVals, null);

                using var ex = squeezenet.CreateExtractor();
                ex.SetNumThreads(4);

                ex.Input("data", @in);

                using var @out = new Mat();
                ex.Extract("detection_out", @out);

                //     printf("%d %d %d\n", out.w, out.h, out.c);
                objects.Clear();
                for (var i = 0; i < @out.H; i++)
                {
                    var values = @out.Row(i);

                    var @object = new Object();
                    @object.Label       = (int)values[0];
                    @object.Prob        = values[1];
                    @object.Rect.X      = values[2] * imgW;
                    @object.Rect.Y      = values[3] * imgH;
                    @object.Rect.Width  = values[4] * imgW - @object.Rect.X;
                    @object.Rect.Height = values[5] * imgH - @object.Rect.Y;

                    objects.Add(@object);
                }
            }

            return(0);
        }
Пример #7
0
        private static int DetectMobileNet(NcnnDotNet.OpenCV.Mat bgr, List <Object> objects)
        {
            using (var mobilenet = new Net())
            {
                if (Ncnn.IsSupportVulkan)
                {
                    mobilenet.Opt.UseVulkanCompute = true;
                }

                // model is converted from https://github.com/chuanqi305/MobileNet-SSD
                // and can be downloaded from https://drive.google.com/open?id=0ByaKLD9QaPtucWk0Y0dha1VVY0U
                // the ncnn model https://github.com/nihui/ncnn-assets/tree/master/models
                mobilenet.LoadParam("mobilenet_ssd_voc_ncnn.param");
                mobilenet.LoadModel("mobilenet_ssd_voc_ncnn.bin");

                const int targetSize = 300;

                var imgW = bgr.Cols;
                var imgH = bgr.Rows;

                using var @in = Mat.FromPixelsResize(bgr.Data, PixelType.Bgr, bgr.Cols, bgr.Rows, targetSize, targetSize);
                var meanVals = new[] { 127.5f, 127.5f, 127.5f };
                var normVals = new[] { (float)(1.0 / 127.5), (float)(1.0 / 127.5), (float)(1.0 / 127.5) };
                @in.SubstractMeanNormalize(meanVals, normVals);

                using var ex = mobilenet.CreateExtractor();
                //ex.SetNumThreads(4);

                ex.Input("data", @in);

                using var @out = new Mat();
                ex.Extract("detection_out", @out);

                //     printf("%d %d %d\n", out.w, out.h, out.c);
                objects.Clear();
                for (var i = 0; i < @out.H; i++)
                {
                    var values = @out.Row(i);

                    var @object = new Object();
                    @object.Label       = (int)values[0];
                    @object.Prob        = values[1];
                    @object.Rect.X      = values[2] * imgW;
                    @object.Rect.Y      = values[3] * imgH;
                    @object.Rect.Width  = values[4] * imgW - @object.Rect.X;
                    @object.Rect.Height = values[5] * imgH - @object.Rect.Y;

                    objects.Add(@object);
                }
            }

            return(0);
        }
Пример #8
0
        // copy from src/layer/proposal.cpp
        private static Mat GenerateAnchors(int baseSize, Mat ratios, Mat scales)
        {
            var numRatio = ratios.W;
            var numScale = scales.W;

            var anchors = new Mat();

            anchors.Create(4, numRatio * numScale);

            var cx = baseSize * 0.5f;
            var cy = baseSize * 0.5f;

            for (var i = 0; i < numRatio; i++)
            {
                var ar = ratios[i];

                var rW = (int)Math.Round(baseSize / Math.Sqrt(ar));
                var rH = (int)Math.Round(rW * ar); //round(baseSize * sqrt(ar));

                for (var j = 0; j < numScale; j++)
                {
                    var scale = scales[j];

                    var rsW = rW * scale;
                    var rsH = rH * scale;

                    var anchor = anchors.Row(i * numScale + j);

                    anchor[0] = cx - rsW * 0.5f;
                    anchor[1] = cy - rsH * 0.5f;
                    anchor[2] = cx + rsW * 0.5f;
                    anchor[3] = cy + rsH * 0.5f;
                }
            }

            return(anchors);
        }
Пример #9
0
        private static void GenerateProposals(Mat anchors, int featStride, Mat scoreBlob, Mat bboxBlob, Mat landmarkBlob, float probThreshold, IList <FaceObject> faceObjects)
        {
            var w = scoreBlob.W;
            var h = scoreBlob.H;

            // generate face proposal from bbox deltas and shifted anchors
            var numAnchors = anchors.H;

            for (var q = 0; q < numAnchors; q++)
            {
                var anchor = anchors.Row(q);

                using var score    = scoreBlob.Channel(q + numAnchors);
                using var bbox     = bboxBlob.ChannelRange(q * 4, 4);
                using var landmark = landmarkBlob.ChannelRange(q * 10, 10);

                // shifted anchor
                var anchorY = anchor[1];

                var anchorW = anchor[2] - anchor[0];
                var anchorH = anchor[3] - anchor[1];

                for (var i = 0; i < h; i++)
                {
                    var anchorX = anchor[0];

                    for (var j = 0; j < w; j++)
                    {
                        var index = i * w + j;

                        var prob = score[index];

                        if (prob >= probThreshold)
                        {
                            // apply center size
                            using var mat0 = bbox.Channel(0);
                            using var mat1 = bbox.Channel(1);
                            using var mat2 = bbox.Channel(2);
                            using var mat3 = bbox.Channel(3);
                            var dx = mat0[index];
                            var dy = mat1[index];
                            var dw = mat2[index];
                            var dh = mat3[index];

                            var cx = anchorX + anchorW * 0.5f;
                            var cy = anchorY + anchorH * 0.5f;

                            var pbCx = cx + anchorW * dx;
                            var pbCy = cy + anchorH * dy;

                            var pbW = anchorW * (float)Math.Exp(dw);
                            var pbH = anchorH * (float)Math.Exp(dh);

                            var x0 = pbCx - pbW * 0.5f;
                            var y0 = pbCy - pbH * 0.5f;
                            var x1 = pbCx + pbW * 0.5f;
                            var y1 = pbCy + pbH * 0.5f;

                            var obj = new FaceObject();
                            obj.Rect.X             = x0;
                            obj.Rect.Y             = y0;
                            obj.Rect.Width         = x1 - x0 + 1;
                            obj.Rect.Height        = y1 - y0 + 1;
                            using var landmarkMat0 = landmark.Channel(0);
                            using var landmarkMat1 = landmark.Channel(1);
                            using var landmarkMat2 = landmark.Channel(2);
                            using var landmarkMat3 = landmark.Channel(3);
                            using var landmarkMat4 = landmark.Channel(4);
                            using var landmarkMat5 = landmark.Channel(5);
                            using var landmarkMat6 = landmark.Channel(6);
                            using var landmarkMat7 = landmark.Channel(7);
                            using var landmarkMat8 = landmark.Channel(8);
                            using var landmarkMat9 = landmark.Channel(9);
                            obj.Landmark[0].X      = cx + (anchorW + 1) * landmarkMat0[index];
                            obj.Landmark[0].Y      = cy + (anchorH + 1) * landmarkMat1[index];
                            obj.Landmark[1].X      = cx + (anchorW + 1) * landmarkMat2[index];
                            obj.Landmark[1].Y      = cy + (anchorH + 1) * landmarkMat3[index];
                            obj.Landmark[2].X      = cx + (anchorW + 1) * landmarkMat4[index];
                            obj.Landmark[2].Y      = cy + (anchorH + 1) * landmarkMat5[index];
                            obj.Landmark[3].X      = cx + (anchorW + 1) * landmarkMat6[index];
                            obj.Landmark[3].Y      = cy + (anchorH + 1) * landmarkMat7[index];
                            obj.Landmark[4].X      = cx + (anchorW + 1) * landmarkMat8[index];
                            obj.Landmark[4].Y      = cy + (anchorH + 1) * landmarkMat9[index];
                            obj.Prob = prob;

                            faceObjects.Add(obj);
                        }

                        anchorX += featStride;
                    }

                    anchorY += featStride;
                }
            }
        }