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); }
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); }
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); }
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); }
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); }
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); }
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); }
// 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); }
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; } } }