public async Task TestMaskRCNN() { using (Tensor imageTensor = ImageIO.ReadTensorFromImageFile <byte>( "surfers.jpg", -1, -1, 0, 1.0f)) using (MaskRcnnInceptionV2Coco model = new MaskRcnnInceptionV2Coco()) { await model.Init(); MaskRcnnInceptionV2Coco.RecognitionResult[][] results = model.Recognize(imageTensor); } }
public void Recognize(Mat m) { int[] dim = new int[] { 1, m.Height, m.Width, 3 }; if (_imageTensor == null) { _imageTensor = new Tensor(Emgu.TF.DataType.Uint8, dim); } else { if (!(_imageTensor.Type == Emgu.TF.DataType.Uint8 && Enumerable.SequenceEqual(dim, _imageTensor.Dim))) { _imageTensor.Dispose(); _imageTensor = new Tensor(Emgu.TF.DataType.Uint8, dim); } } Emgu.TF.TensorConvert.ReadTensorFromMatBgr(m, _imageTensor); MaskRcnnInceptionV2Coco.RecognitionResult[] results; if (_coldSession) { //First run of the recognition graph, here we will compile the graph and initialize the session //This is expected to take much longer time than consecutive runs. results = _inceptionGraph.Recognize(_imageTensor)[0]; _coldSession = false; } //Here we are trying to time the execution of the graph after it is loaded Stopwatch sw = Stopwatch.StartNew(); results = _inceptionGraph.Recognize(_imageTensor)[0]; sw.Stop(); int goodResultCount = 0; foreach (var r in results) { if (r.Probability > 0.5) { float x1 = r.Region[0] * m.Height; float y1 = r.Region[1] * m.Width; float x2 = r.Region[2] * m.Height; float y2 = r.Region[3] * m.Width; RectangleF rectf = new RectangleF(y1, x1, y2 - y1, x2 - x1); Rectangle rect = Rectangle.Round(rectf); rect.Intersect(new Rectangle(Point.Empty, m.Size)); //only keep the region that is inside the image if (rect.IsEmpty) { continue; } //draw the rectangle around the region CvInvoke.Rectangle(m, rect, new Emgu.CV.Structure.MCvScalar(0, 0, 255), 2); #region draw the mask float[,] mask = r.Mask; GCHandle handle = GCHandle.Alloc(mask, GCHandleType.Pinned); using (Mat mk = new Mat(new Size(mask.GetLength(1), mask.GetLength(0)), Emgu.CV.CvEnum.DepthType.Cv32F, 1, handle.AddrOfPinnedObject(), mask.GetLength(1) * sizeof(float))) using (Mat subRegion = new Mat(m, rect)) using (Mat maskLarge = new Mat()) using (Mat maskLargeInv = new Mat()) using (Mat largeColor = new Mat(subRegion.Size, Emgu.CV.CvEnum.DepthType.Cv8U, 3)) { CvInvoke.Resize(mk, maskLarge, subRegion.Size); //give the mask at least 30% transparency using (ScalarArray sa = new ScalarArray(0.7)) CvInvoke.Min(sa, maskLarge, maskLarge); //Create the inverse mask for the original image using (ScalarArray sa = new ScalarArray(1.0)) CvInvoke.Subtract(sa, maskLarge, maskLargeInv); //The mask color largeColor.SetTo(new Emgu.CV.Structure.MCvScalar(255, 0, 0)); CvInvoke.BlendLinear(largeColor, subRegion, maskLarge, maskLargeInv, subRegion); } handle.Free(); #endregion //draw the label CvInvoke.PutText(m, r.Label, Point.Round(rect.Location), Emgu.CV.CvEnum.FontFace.HersheyComplex, 1.0, new Emgu.CV.Structure.MCvScalar(0, 255, 0), 1); goodResultCount++; } } String resStr = String.Format("{0} objects detected in {1} milliseconds.", goodResultCount, sw.ElapsedMilliseconds); if (_renderMat == null) { _renderMat = new Mat(); } m.CopyTo(_renderMat); //Bitmap bmp = _renderMat.ToBitmap(); if (InvokeRequired) { this.Invoke((MethodInvoker)(() => { messageLabel.Text = resStr; pictureBox.Image = _renderMat; })); } else { messageLabel.Text = resStr; pictureBox.Image = _renderMat; } }