コード例 #1
0
    private void DrawToTexture(Texture texture, Annotation[] annotations, Texture2D results)
    {
        if (texture is Texture2D)
        {
            Texture2D t2d = texture as Texture2D;
            _drawableTexture.SetPixels32(t2d.GetPixels32());
        }
        else
        {
            Texture2D tmp = new Texture2D(texture.width, texture.height, GraphicsFormat.R8G8B8A8_SRGB, texture.mipmapCount, TextureCreationFlags.None);
            Graphics.CopyTexture(texture, tmp);
            _drawableTexture.SetPixels32(tmp.GetPixels32());
        }

        foreach (Annotation annotation in annotations)
        {
            float left   = annotation.Rectangle[0] * _drawableTexture.width;
            float top    = annotation.Rectangle[1] * _drawableTexture.height;
            float right  = annotation.Rectangle[2] * _drawableTexture.width;
            float bottom = annotation.Rectangle[3] * _drawableTexture.height;

            Rect scaledLocation = new Rect(left, top, right - left, bottom - top);

            scaledLocation.y      = texture.height - scaledLocation.y;
            scaledLocation.height = -scaledLocation.height;

            NativeImageIO.DrawRect(_drawableTexture, scaledLocation, Color.red);
        }
        results.Apply();
    }
コード例 #2
0
ファイル: Inception.cs プロジェクト: htetmyatag/emgutf
        public RecognitionResult[] Recognize(
            Texture2D texture2D,
            int inputHeight     = 299,
            int inputWidth      = 299,
            float inputMean     = 0.0f,
            float scale         = 1.0f / 255.0f,
            bool flipUpsideDown = true,
            bool swapBR         = false)
        {
            NativeImageIO.ReadTensorFromTexture2D <float>(
                texture2D,
                _inputTensor.DataPointer,
                inputHeight,
                inputWidth,
                inputMean,
                scale,
                flipUpsideDown,
                swapBR);

            _interpreter.Invoke();

            float[] probability = _outputTensor.GetData(false) as float[];
            if (probability == null)
            {
                return(null);
            }

            return(SortResults(probability));
        }
コード例 #3
0
ファイル: CocoSsdMobilenet.cs プロジェクト: emgucv/emgutf
        private void ReadImageFileToTensor(String imageFile)
        {
            int height = _inputTensor.Dims[1];
            int width  = _inputTensor.Dims[2];

            NativeImageIO.ReadImageFileToTensor <byte>(imageFile, _inputTensor.DataPointer, height, width, 0.0f, 1.0f);
        }
コード例 #4
0
        private void onDownloadCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            Stopwatch watch  = Stopwatch.StartNew();
            var       result = _mobilenet.Recognize(_imageFiles[0], 0.5f);

            watch.Stop();

            NativeImageIO.Annotation[] annotations = new NativeImageIO.Annotation[result.Length];
            for (int i = 0; i < result.Length; i++)
            {
                NativeImageIO.Annotation annotation = new NativeImageIO.Annotation();
                annotation.Rectangle = result[i].Rectangle;
                annotation.Label     = String.Format("{0}:({1:0.00}%)", result[i].Label, result[i].Score * 100);
                annotations[i]       = annotation;
            }


            NativeImageIO.JpegData jpeg = NativeImageIO.ImageFileToJpeg(_imageFiles[0], annotations);
            //NativeImageIO.JpegData jpeg = NativeImageIO.ImageFileToJpeg(_imageFiles[0]);
            //String names = String.Join(";", Array.ConvertAll(result, r => r.Label));
            SetImage(jpeg.Raw, jpeg.Width, jpeg.Height);


            String resStr = String.Format("Detected {1} objects in {0} milliseconds.", watch.ElapsedMilliseconds, result.Length);

            SetMessage(resStr);
        }
コード例 #5
0
ファイル: ImageIO.cs プロジェクト: KwpGitHub/emgutf
        /*
         * public static Tensor ReadTensorFromTexture2D_V0(
         *  Texture2D texture, int inputHeight = -1, int inputWidth = -1,
         *  float inputMean = 0.0f, float scale = 1.0f, bool flipUpsideDown = false)
         * {
         *  Color32[] colors;
         *  Tensor t;
         *  int width, height;
         *  if (inputHeight > 0 || inputWidth > 0)
         *  {
         *      Texture2D small = Resize(texture, inputWidth, inputHeight);
         *      colors = small.GetPixels32();
         *      width = inputWidth;
         *      height = inputHeight;
         *  }
         *  else
         *  {
         *      width = texture.width;
         *      height = texture.height;
         *      colors = texture.GetPixels32();
         *  }
         *  t = new Tensor(DataType.Float, new int[] { 1, height, width, 3 });
         *
         *  float[] floatValues = new float[colors.Length*3];
         *
         *  if (flipUpsideDown)
         *  {
         *      for (int i = 0; i < height; i++)
         *      for (int j = 0; j < width; j++)
         *      {
         *          Color32 val = colors[(height - i - 1) * width + j];
         *          int idx = i * width + j;
         *          floatValues[idx * 3 + 0] = (val.r - inputMean) * scale;
         *          floatValues[idx * 3 + 1] = (val.g - inputMean) * scale;
         *          floatValues[idx * 3 + 2] = (val.b - inputMean) * scale;
         *      }
         *  }
         *  else
         *  {
         *      for (int i = 0; i < colors.Length; ++i)
         *      {
         *          Color32 val = colors[i];
         *          floatValues[i * 3 + 0] = (val.r - inputMean) * scale;
         *          floatValues[i * 3 + 1] = (val.g - inputMean) * scale;
         *          floatValues[i * 3 + 2] = (val.b - inputMean) * scale;
         *      }
         *  }
         *
         *
         *  System.Runtime.InteropServices.Marshal.Copy(floatValues, 0, t.DataPointer, floatValues.Length);
         *
         *  return t;
         * }*/
#else
        public static byte[] TensorToJpeg(Tensor image, float scale = 1.0f, float mean = 0.0f, Status status = null)
        {
#if __ANDROID__
            byte[] rawPixel = TensorToPixel(image, scale, mean, 4);
            int[]  dim      = image.Dim;
            return(NativeImageIO.PixelToJpeg(rawPixel, dim[2], dim[1], 4));
#elif __IOS__
            if (mean != 0.0)
            {
                throw new NotImplemenetedException("Not able to accept mean values on this platform");
            }
            byte[] rawPixel = TensorToPixel(image, scale, mean, 3);
            int[]  dim      = image.Dim;
            return(NativeImageIO.PixelToJpeg(rawPixel, dim[2], dim[1], 3));
#elif __UNIFIED__ //Mac OSX
            byte[] rawPixel = TensorToPixel(image, scale, mean, 4);
            int[]  dim      = image.Dim;
            return(NativeImageIO.PixelToJpeg(rawPixel, dim[2], dim[1], 4));
#else
            //if (mean != 0.0)
            //    throw new NotImplemenetedException("Not able to accept mean values on this platform");
            //byte[] rawPixel = TensorToPixel(image, scale, mean, 3);
            //int[] dim = image.Dim;
            //return NativeImageIO.PixelToJpeg(rawPixel, dim[2], dim[1], 3);
            return(EncodeJpeg(image, 1.0f, 0.0f));
#endif
        }
コード例 #6
0
        private async void OnButtonClicked(Object sender, EventArgs args)
        {
            SetMessage("Please wait while the Coco SSD Mobilenet Model is being downloaded...");
#if !DEBUG
            try
#endif
            {
                await _mobilenet.Init();
            }
#if !DEBUG
            catch (Exception e)
            {
                String msg = e.Message.Replace(System.Environment.NewLine, " ");
                SetMessage(msg);
            }
#endif

            if (this.TopButton.Text.Equals("Stop"))
            {
                // Stop camera
#if __IOS__ || __MACOS__
                this.StopCaptureSession();
#endif
                this.TopButton.Text = "Perform Object Detection";
            }
            else
            {
                String[] imageFiles = await LoadImages(new string[] { "dog416.png" });

                String imageFileName = imageFiles[0];

                if (imageFileName.Equals("Camera Stream"))
                {
#if __MACOS__ || __IOS__
                    SetMessage(String.Format("Model trained to recognize the following objects: {0}", String.Join("; ", _mobilenet.Labels)));
                    this.TopButton.Text = "Stop";
                    CheckVideoPermissionAndStart();
#else
#endif
                }
                else
                {
                    Stopwatch watch  = Stopwatch.StartNew();
                    var       result = _mobilenet.Recognize(imageFileName, 0.5f);
                    watch.Stop();

                    Annotation[] annotations = GetAnnotations(result);

                    JpegData jpeg = NativeImageIO.ImageFileToJpeg(imageFileName, annotations);
                    //NativeImageIO.JpegData jpeg = NativeImageIO.ImageFileToJpeg(_imageFiles[0]);
                    //String names = String.Join(";", Array.ConvertAll(result, r => r.Label));
                    SetImage(jpeg.Raw, jpeg.Width, jpeg.Height);

                    String resStr = String.Format("Detected {1} objects in {0} milliseconds.", watch.ElapsedMilliseconds, result.Length);
                    SetMessage(resStr);
                }
            }
        }
コード例 #7
0
        public float[] Recognize(String imageFile)
        {
            NativeImageIO.ReadImageFileToTensor <float>(imageFile, _inputTensor.DataPointer, 224, 224, 128.0f, 1.0f / 128.0f);

            _interpreter.Invoke();

            float[] probability = _outputTensor.Data as float[];
            return(probability);
        }
コード例 #8
0
ファイル: CocoSsdMobilenet.cs プロジェクト: emgucv/emgutf
        /// <summary>
        /// Perform Coco Ssd Mobilenet detection
        /// </summary>
        /// <param name="image">The image where we will ran the network through</param>
        /// <param name="scoreThreshold">If non-positive, will return all results. If positive, we will only return results with score larger than this value</param>
        /// <returns>The result of the detection.</returns>
        public RecognitionResult[] Recognize(NSImage image, float scoreThreshold = 0.0f)
        {
            int height = _inputTensor.Dims[1];
            int width  = _inputTensor.Dims[2];

            NativeImageIO.ReadImageToTensor <byte>(image, _inputTensor.DataPointer, height, width, 0.0f, 1.0f);

            _interpreter.Invoke();

            return(GetResults(scoreThreshold));
        }
コード例 #9
0
ファイル: CocoSsdMobilenetPage.cs プロジェクト: emgucv/emgutf
        //private int _counter = 0;
        private void OutputRecorder_BufferReceived(object sender, OutputRecorder.BufferReceivedEventArgs e)
        {
            try
            {
                //_counter++;
#if __IOS__
                UIImage image = e.Buffer.ToUIImage();
                CocoSsdMobilenet.RecognitionResult[] result = _mobilenet.Recognize(image, 0.5f);
                Annotation[] annotations    = GetAnnotations(result);
                UIImage      annotatedImage = NativeImageIO.DrawAnnotations(image, annotations);
                image.Dispose();
#else
                NSImage image = e.Buffer.ToNSImage();
                CocoSsdMobilenet.RecognitionResult[] result = _mobilenet.Recognize(image, 0.5f);
                Annotation[] annotations = GetAnnotations(result);
#endif

                //Debug.WriteLine(image == null ? "null image" : String.Format(">image {0} x {1}", image.Size.Width, image.Size.Height));
                // Do something with the image, we just stuff it in our main view.
                Xamarin.Forms.Device.BeginInvokeOnMainThread(delegate
                {
                    //Debug.WriteLine(image == null ? "null image" : String.Format(">>image {0} x {1}", image.Size.Width, image.Size.Height));
#if __IOS__
                    //if (UIImageView.Frame.Size != annotatedImage.Size)
                    //    UIImageView.Frame = new CGRect(CGPoint.Empty, annotatedImage.Size);
                    //SetMessage( String.Format("{0} image", _counter) );
                    //UIImage oldImage = UIImageView.Image;
                    //UIImageView.Image = annotatedImage;
                    //if (oldImage != null)
                    //    oldImage.Dispose();
                    SetImage(annotatedImage);
#else
                    NativeImageIO.DrawAnnotations(image, annotations);

                    //SetMessage(String.Format("{0} image", _counter));
                    SetImage(image);
#endif
                });

                //
                // Although this looks innocent "Oh, he is just optimizing this case away"
                // this is incredibly important to call on this callback, because the AVFoundation
                // has a fixed number of buffers and if it runs out of free buffers, it will stop
                // delivering frames.
                //

                //Console.WriteLine(String.Format("Frame at: {0}", DateTime.Now));
            }
            catch (Exception ex)
            {
                Console.WriteLine(e);
                SetMessage(ex.Message);
            }
        }
コード例 #10
0
ファイル: Inception.cs プロジェクト: htetmyatag/emgutf
        /// <summary>
        /// Load the file, ran it through the mobile net graph and return the recognition results
        /// </summary>
        /// <param name="imageFile">The image to be loaded</param>
        /// <param name="width">The width of the input tensor</param>
        /// <param name="height">The height of the input tensor</param>
        /// <param name="mean">The mean to be subtracted when converting the image to input tensor</param>
        /// <param name="scale">The scale to be multiplied when converting the image to input tensor</param>
        /// <param name="flipUpsideDown">If true, the image will be flipped upside down when it is coverted to input tensor</param>
        /// <param name="swapBR">If true, the blue and red channel will be swapped when converting the image to input tensor </param>
        /// <returns>The recognition result sorted by probability</returns>
        public RecognitionResult[] Recognize(String imageFile, int width = 299, int height = 299, float mean = 0.0f, float scale = 1.0f / 255.0f, bool flipUpsideDown = false, bool swapBR = true)
        {
            NativeImageIO.ReadImageFileToTensor <float>(imageFile, _inputTensor.DataPointer, height, width, mean, scale, flipUpsideDown, swapBR);

            _interpreter.Invoke();

            float[] probability = _outputTensor.Data as float[];
            if (probability == null)
            {
                return(null);
            }
            return(SortResults(probability));
        }
コード例 #11
0
        /// <summary>
        /// Load the file, ran it through the mobile net graph and return the recognition results
        /// </summary>
        /// <param name="imageFile">The image to be loaded</param>
        /// <returns>The recognition result sorted by probability</returns>
        public RecognitionResult[] Recognize(String imageFile)
        {
            NativeImageIO.ReadImageFileToTensor <float>(imageFile, _inputTensor.DataPointer, 224, 224, 128.0f, 1.0f / 128.0f);

            _interpreter.Invoke();

            float[] probability = _outputTensor.Data as float[];
            if (probability == null)
            {
                return(null);
            }
            return(SortResults(probability));
        }
コード例 #12
0
        /// <summary>
        /// Perform Coco Ssd Mobilenet detection
        /// </summary>
        /// <param name="imageFile">The image file where we will ran the network through</param>
        /// <param name="scoreThreshold">If non-positive, will return all results. If positive, we will only return results with score larger than this value</param>
        /// <returns>The result of the detection.</returns>
        public RecognitionResult[] Recognize(String imageFile, float scoreThreshold = 0.0f)
        {
            //NativeImageIO.ReadImageFileToTensor<byte>(imageFile, _inputTensor.DataPointer, _inputTensor.Dims[1], _inputTensor.Dims[2], _inputTensor.QuantizationParams.ZeroPoint, _inputTensor.QuantizationParams.Scale);
            int height = _inputTensor.Dims[1];
            int width  = _inputTensor.Dims[2];

            NativeImageIO.ReadImageFileToTensor <byte>(imageFile, _inputTensor.DataPointer, height, width, 0.0f, 1.0f);

            _interpreter.Invoke();

            float[,,] outputLocations = _interpreter.Outputs[0].JaggedData as float[, , ];
            float[] classes       = _interpreter.Outputs[1].Data as float[];
            float[] scores        = _interpreter.Outputs[2].Data as float[];
            int     numDetections = (int)Math.Round((_interpreter.Outputs[3].Data as float[])[0]);

            // SSD Mobilenet V1 Model assumes class 0 is background class
            // in label file and class labels start from 1 to number_of_classes+1,
            // while outputClasses correspond to class index from 0 to number_of_classes
            List <RecognitionResult> results = new List <RecognitionResult>();

            int labelOffset = 1;

            for (int i = 0; i < numDetections; i++)
            {
                if (classes[i] == 0) //background class
                {
                    continue;
                }

                if (scoreThreshold > 0.0f && scores[i] < scoreThreshold)
                {
                    continue;
                }

                RecognitionResult r = new RecognitionResult();
                r.Class = (int)Math.Round(classes[i]);
                r.Label = _labels[r.Class + labelOffset];
                r.Score = scores[i];
                float x0 = outputLocations[0, i, 1];
                float y0 = outputLocations[0, i, 0];
                float x1 = outputLocations[0, i, 3];
                float y1 = outputLocations[0, i, 2];
                r.Rectangle = new float[] { x0, y0, x1, y1 };

                results.Add(r);
            }

            return(results.ToArray());
        }
コード例 #13
0
        private void onDownloadCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            if (e != null && e.Error != null)
            {
                SetMessage(e.Error.Message);
                return;
            }

            String _imageFileName = _imageFiles[0];

            if (_imageFileName.Equals("Camera Stream"))
            {
#if __MACOS__ || __IOS__
                SetMessage(String.Format("Model trained to recognize the following objects: {0}", String.Join("; ", _mobilenet.Labels)));
                this.TopButton.Text = "Stop";
                CheckVideoPermissionAndStart();
#else
#endif
            }
            else
            {
                Stopwatch watch  = Stopwatch.StartNew();
                var       result = _mobilenet.Recognize(_imageFiles[0], 0.5f);
                watch.Stop();

                Annotation[] annotations = GetAnnotations(result);

                /*
                 * Annotation[] annotations = new Annotation[result.Length];
                 * for (int i = 0; i < result.Length; i++)
                 * {
                 *  Annotation annotation = new Annotation();
                 *  annotation.Rectangle = result[i].Rectangle;
                 *  annotation.Label = String.Format("{0}:({1:0.00}%)", result[i].Label, result[i].Score * 100);
                 *  annotations[i] = annotation;
                 * }*/


                JpegData jpeg = NativeImageIO.ImageFileToJpeg(_imageFiles[0], annotations);
                //NativeImageIO.JpegData jpeg = NativeImageIO.ImageFileToJpeg(_imageFiles[0]);
                //String names = String.Join(";", Array.ConvertAll(result, r => r.Label));
                SetImage(jpeg.Raw, jpeg.Width, jpeg.Height);


                String resStr = String.Format("Detected {1} objects in {0} milliseconds.", watch.ElapsedMilliseconds, result.Length);
                SetMessage(resStr);
            }
        }
コード例 #14
0
ファイル: CocoSsdMobilenet.cs プロジェクト: emgucv/emgutf
        public RecognitionResult[] Recognize(Texture texture, bool flipUpsideDown = true, bool swapBR = false, float scoreThreshold = 0.0f)
        {
            int height = _inputTensor.Dims[1];
            int width  = _inputTensor.Dims[2];

            NativeImageIO.ReadTensorFromTexture <byte>(
                texture,
                _inputTensor.DataPointer,
                height, width, 0.0f, 1.0f,
                flipUpsideDown,
                swapBR);

            _interpreter.Invoke();

            return(GetResults(scoreThreshold));
        }
コード例 #15
0
        /*
         * public static Tensor ReadTensorFromTexture2D_V0(
         *  Texture2D texture, int inputHeight = -1, int inputWidth = -1,
         *  float inputMean = 0.0f, float scale = 1.0f, bool flipUpsideDown = false)
         * {
         *  Color32[] colors;
         *  Tensor t;
         *  int width, height;
         *  if (inputHeight > 0 || inputWidth > 0)
         *  {
         *      Texture2D small = Resize(texture, inputWidth, inputHeight);
         *      colors = small.GetPixels32();
         *      width = inputWidth;
         *      height = inputHeight;
         *  }
         *  else
         *  {
         *      width = texture.width;
         *      height = texture.height;
         *      colors = texture.GetPixels32();
         *  }
         *  t = new Tensor(DataType.Float, new int[] { 1, height, width, 3 });
         *
         *  float[] floatValues = new float[colors.Length*3];
         *
         *  if (flipUpsideDown)
         *  {
         *      for (int i = 0; i < height; i++)
         *      for (int j = 0; j < width; j++)
         *      {
         *          Color32 val = colors[(height - i - 1) * width + j];
         *          int idx = i * width + j;
         *          floatValues[idx * 3 + 0] = (val.r - inputMean) * scale;
         *          floatValues[idx * 3 + 1] = (val.g - inputMean) * scale;
         *          floatValues[idx * 3 + 2] = (val.b - inputMean) * scale;
         *      }
         *  }
         *  else
         *  {
         *      for (int i = 0; i < colors.Length; ++i)
         *      {
         *          Color32 val = colors[i];
         *          floatValues[i * 3 + 0] = (val.r - inputMean) * scale;
         *          floatValues[i * 3 + 1] = (val.g - inputMean) * scale;
         *          floatValues[i * 3 + 2] = (val.b - inputMean) * scale;
         *      }
         *  }
         *
         *
         *  System.Runtime.InteropServices.Marshal.Copy(floatValues, 0, t.DataPointer, floatValues.Length);
         *
         *  return t;
         * }*/
#else
        public static byte[] TensorToJpeg(Tensor stylizedImage, float scale = 1.0f, Status status = null)
        {
#if __ANDROID__
            byte[] rawPixel = TensorToPixel(stylizedImage, scale, 4);
            int[]  dim      = stylizedImage.Dim;
            return(NativeImageIO.PixelToJpeg(rawPixel, dim[2], dim[1], 4));
#elif __IOS__
            byte[] rawPixel = TensorToPixel(stylizedImage, scale, 3);
            int[]  dim      = stylizedImage.Dim;
            return(NativeImageIO.PixelToJpeg(rawPixel, dim[2], dim[1], 3));
#elif __UNIFIED__ //Mac OSX
            byte[] rawPixel = TensorToPixel(stylizedImage, scale, 4);
            int[]  dim      = stylizedImage.Dim;
            return(NativeImageIO.PixelToJpeg(rawPixel, dim[2], dim[1], 4));
#else
            return(null);
#endif
        }
コード例 #16
0
        public RecognitionResult[] Recognize(Texture2D texture2D, bool flipUpsideDown = true, bool swapBR = false)
        {
            NativeImageIO.ReadTensorFromTexture2D <float>(
                texture2D,
                _inputTensor.DataPointer,
                224, 224, 128.0f, 1.0f / 128.0f,
                flipUpsideDown,
                swapBR);

            _interpreter.Invoke();

            float[] probability = _outputTensor.GetData(false) as float[];
            if (probability == null)
            {
                return(null);
            }

            return(SortResults(probability));
        }
コード例 #17
0
 private void OnDownloadComplete(object sender, AsyncCompletedEventArgs e)
 {
     try
     {
         using (var imageTensor = ImageIO.ReadTensorFromImageFile <float>(_fileName, 224, 224, 128.0f, 1.0f / 128.0f))
         {
             var detectionResult      = _graph.Detect(imageTensor);
             var detectionAnnotations = MultiboxGraph.FilterResults(detectionResult, 0.1f);
             var detectionImage       = NativeImageIO.ImageFileToJpeg(_fileName, detectionAnnotations);
             var typeConverter        = TypeDescriptor.GetConverter(typeof(Bitmap));
             var detectionBmpImage    = (Bitmap)typeConverter.ConvertFrom(detectionImage.Raw);
             ImageSource = BitmapConverter.ConvertBitmap(detectionBmpImage);
         }
         IsModalVisible = false;
     }
     catch (Exception ex)
     {
         _exceptionLogDataAccess.LogException(ex.ToString());
         IsModalVisible = false;
     }
 }
コード例 #18
0
    private static void DrawToTexture(Texture texture, Annotation[] annotations, Texture2D results)
    {
        Debug.Assert(texture.width == results.width && texture.height == results.height, "Input texture and output texture must have the same width & height.");
        Color32[] pixels;
        if (texture is Texture2D)
        {
            Texture2D t2d = texture as Texture2D;
            pixels = t2d.GetPixels32();
        }
        else if (texture is WebCamTexture)
        {
            WebCamTexture wct = texture as WebCamTexture;
            pixels = wct.GetPixels32();
        }
        else
        {
            Texture2D tmp = new Texture2D(texture.width, texture.height, GraphicsFormat.R8G8B8A8_SRGB, texture.mipmapCount, TextureCreationFlags.None);
            Graphics.CopyTexture(texture, tmp);
            pixels = tmp.GetPixels32();
            Destroy(tmp);
        }

        foreach (Annotation annotation in annotations)
        {
            float left   = annotation.Rectangle[0] * texture.width;
            float top    = annotation.Rectangle[1] * texture.height;
            float right  = annotation.Rectangle[2] * texture.width;
            float bottom = annotation.Rectangle[3] * texture.height;

            Rect scaledLocation = new Rect(left, top, right - left, bottom - top);

            scaledLocation.y      = texture.height - scaledLocation.y;
            scaledLocation.height = -scaledLocation.height;

            NativeImageIO.DrawRect(pixels, texture.width, texture.height, scaledLocation, Color.red);
        }
        results.SetPixels32(pixels);
        results.Apply();
    }
コード例 #19
0
        private static Tensor NativeReadTensorFromImageFile <T>(
            String fileName,

            int inputHeight     = -1,
            int inputWidth      = -1,
            float inputMean     = 0.0f,
            float scale         = 1.0f,
            bool flipUpSideDown = false,
            bool swapBR         = false,
            Status status       = null) where T : struct
        {
            //Use native Image handler to import the file
            Tensor t;

            if (typeof(T) == typeof(float))
            {
                t = new Tensor(DataType.Float, new int[] { 1, (int)inputHeight, (int)inputWidth, 3 });
            }
            else if (typeof(T) == typeof(byte))
            {
                t = new Tensor(DataType.Uint8, new int[] { 1, (int)inputHeight, (int)inputWidth, 3 });
            }
            else
            {
                throw new Exception(String.Format("Conversion to tensor of type {0} is not implemented", typeof(T)));
            }

            NativeImageIO.ReadImageFileToTensor <T>(
                fileName,
                t.DataPointer,
                inputHeight,
                inputWidth,
                inputMean,
                scale,
                flipUpSideDown,
                !swapBR //No swapping BR in tensorflow is the equivalent of swapping BR in Bitmap
                );
            return(t);
        }
コード例 #20
0
        public void TestNativeImageIO()
        {
            int    inputHeight = 299;
            int    inputWidth  = 299;
            String file        = "surfers.jpg";
            Tensor t0          = new Tensor(DataType.Uint8, new int[] { 1, (int)inputHeight, (int)inputWidth, 3 });

            NativeImageIO.ReadImageFileToTensor <float>(file, t0.DataPointer, inputHeight, inputWidth, 0.0f,
                                                        1.0f / 255.0f);
            Tensor t1      = ImageIO.ReadTensorFromImageFile <float>(file);
            float  maxDiff = 0.0f;
            var    ta0     = t0.GetData(false) as float[];
            var    ta1     = t1.GetData(false) as float[];

            for (int i = 0; i < ta0.Length; i++)
            {
                float diff = Math.Abs(ta0[i] - ta1[i]);
                if (diff < maxDiff)
                {
                    maxDiff = diff;
                }
            }
        }
コード例 #21
0
ファイル: Multibox.cs プロジェクト: radtek/emgutf
        public static void DrawResults(Texture2D image, MultiboxGraph.Result[] results, float scoreThreshold, bool flipUpSideDown = false)
        {
            Annotation[] annotations = FilterResults(results, scoreThreshold);

            Color color = new Color(1.0f, 0, 0);//Set color to red

            for (int i = 0; i < annotations.Length; i++)
            {
                Rect[] rects = ScaleLocation(annotations[i].Rectangle, image.width, image.height, flipUpSideDown);

                foreach (Rect r in rects)
                {
                    NativeImageIO.DrawRect(image, r, color);
                }
            }
            image.Apply();
            //GUI.color = Color.white;//Reset color to white

            /*
             * Android.Graphics.Paint p = new Android.Graphics.Paint();
             * p.SetStyle(Paint.Style.Stroke);
             * p.AntiAlias = true;
             * p.Color = Android.Graphics.Color.Red;
             * Canvas c = new Canvas(bmp);
             *
             *
             * for (int i = 0; i < result.Scores.Length; i++)
             * {
             *  if (result.Scores[i] > scoreThreshold)
             *  {
             *      Rectangle rect = locations[result.Indices[i]];
             *      Android.Graphics.Rect r = new Rect(rect.Left, rect.Top, rect.Right, rect.Bottom);
             *      c.DrawRect(r, p);
             *  }
             * }*/
        }
コード例 #22
0
ファイル: MobilenetBehavior.cs プロジェクト: wensincai/emgutf
    //private Inception _inceptionGraph = null;

    private void RecognizeAndUpdateText(Texture2D texture)
    {
        int[] input  = _interpreter.GetInput();
        int[] output = _interpreter.GetOutput();

        Tensor inputTensor  = _interpreter.GetTensor(input[0]);
        Tensor outputTensor = _interpreter.GetTensor(output[0]);

        NativeImageIO.ReadImageFileToTensor(_image[0], inputTensor.DataPointer, 224, 224, 128.0f, 1.0f / 128.0f);
        Stopwatch watch = Stopwatch.StartNew();

        _interpreter.Invoke();
        watch.Stop();

        float[] probability = outputTensor.GetData() as float[];

        String resStr = String.Empty;

        if (probability != null)
        {
            float maxVal = 0;
            int   maxIdx = 0;
            for (int i = 0; i < probability.Length; i++)
            {
                if (probability[i] > maxVal)
                {
                    maxVal = probability[i];
                    maxIdx = i;
                }
            }
            resStr = String.Format("Object is {0} with {1}% probability. Recognition completed in {2} milliseconds.", _labels[maxIdx], maxVal * 100, watch.ElapsedMilliseconds);
        }

        //SetImage(_image[0]);
        _displayMessage = resStr;
    }
コード例 #23
0
ファイル: MobilenetPage.cs プロジェクト: svija/emgutf
        private void onDownloadCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            String localFileName = _downloadManager.Files[0].LocalFile;

            if (_labels == null)
            {
                _labels = File.ReadAllLines(_downloadManager.Files[1].LocalFile);
            }

            System.Diagnostics.Debug.Assert(File.Exists(localFileName), "File doesn't exist");
            FileInfo file = new FileInfo(localFileName);

            if (_model == null)
            {
                _model = new FlatBufferModel(localFileName);
                if (!_model.CheckModelIdentifier())
                {
                    throw new Exception("Model indentifier check failed");
                }
            }

            if (_resolver == null)
            {
                _resolver = new BuildinOpResolver();
            }

            if (_interpreter == null)
            {
                _interpreter = new Interpreter(_model, _resolver);
                Status allocateTensorStatus = _interpreter.AllocateTensors();
                if (allocateTensorStatus == Status.Error)
                {
                    throw new Exception("Failed to allocate tensor");
                }
            }

            int[] input  = _interpreter.GetInput();
            int[] output = _interpreter.GetOutput();

            Tensor inputTensor  = _interpreter.GetTensor(input[0]);
            Tensor outputTensor = _interpreter.GetTensor(output[0]);

            NativeImageIO.ReadImageFileToTensor(_image[0], inputTensor.DataPointer, 224, 224, 128.0f, 1.0f / 128.0f);
            Stopwatch watch = Stopwatch.StartNew();

            _interpreter.Invoke();
            watch.Stop();

            float[] probability = outputTensor.GetData() as float[];

            String resStr = String.Empty;

            if (probability != null)
            {
                float maxVal = 0;
                int   maxIdx = 0;
                for (int i = 0; i < probability.Length; i++)
                {
                    if (probability[i] > maxVal)
                    {
                        maxVal = probability[i];
                        maxIdx = i;
                    }
                }
                resStr = String.Format("Object is {0} with {1}% probability. Recognition completed in {2} milliseconds.", _labels[maxIdx], maxVal * 100, watch.ElapsedMilliseconds);
            }

            SetImage(_image[0]);
            SetMessage(resStr);
        }
コード例 #24
0
        public static Tensor ReadTensorFromImageFile(String fileName, int inputHeight = -1, int inputWidth = -1, float inputMean = 0.0f, float scale = 1.0f, bool flipUpsideDown = false)
        {
            Texture2D texture = NativeImageIO.ReadTexture2DFromFile(fileName);

            return(ReadTensorFromTexture2D(texture, inputHeight, inputWidth, inputMean, scale, flipUpsideDown));
        }
コード例 #25
0
        public override void DidOutputSampleBuffer(AVCaptureOutput captureOutput, CMSampleBuffer sampleBuffer, AVCaptureConnection connection)
        {
            try
            {
                _counter++;
#if __IOS__
                UIImage image = ImageFromSampleBuffer(sampleBuffer);
#else
                NSImage image = ImageFromSampleBuffer(sampleBuffer);
#endif
                CocoSsdMobilenet.RecognitionResult[] result = _mobilenet.Recognize(image, 0.5f);
                Annotation[] annotations = GetAnnotations(result);

#if __IOS__
                UIImage annotatedImage = NativeImageIO.DrawAnnotations(image, annotations);
                image.Dispose();
#endif
                //Debug.WriteLine(image == null ? "null image" : String.Format(">image {0} x {1}", image.Size.Width, image.Size.Height));
                // Do something with the image, we just stuff it in our main view.
                BeginInvokeOnMainThread(delegate
                {
                    //Debug.WriteLine(image == null ? "null image" : String.Format(">>image {0} x {1}", image.Size.Width, image.Size.Height));
#if __MACOS__
                    NativeImageIO.DrawAnnotations(image, annotations);
#endif
                    if (_imageView.Frame.Size != image.Size)
                    {
                        _imageView.Frame = new CGRect(CGPoint.Empty, image.Size);
                    }
                    _label.Text = String.Format("{0} image", _counter);

#if __IOS__
                    UIImage oldImage = _imageView.Image;
                    _imageView.Image = annotatedImage;
#else
                    NSImage oldImage = _imageView.Image;

                    //Debug.WriteLine(image == null ? "null image" : String.Format(">>>image {0} x {1}", image.Size.Width, image.Size.Height));
                    _imageView.Image = image;
#endif

                    if (oldImage != null)
                    {
                        oldImage.Dispose();
                    }
                });

                //
                // Although this looks innocent "Oh, he is just optimizing this case away"
                // this is incredibly important to call on this callback, because the AVFoundation
                // has a fixed number of buffers and if it runs out of free buffers, it will stop
                // delivering frames.
                //
                sampleBuffer.Dispose();
                //Console.WriteLine(String.Format("Frame at: {0}", DateTime.Now));
            }
            catch (Exception e)
            {
                Console.WriteLine(e);

                BeginInvokeOnMainThread(delegate
                {
                    _label.Text = String.Format("{0} image", e.Message);
                });
            }
        }
コード例 #26
0
        /// <summary>
        /// Read image files, covert the data and save it to the native pointer
        /// </summary>
        /// <typeparam name="T">The type of the data to covert the image pixel values to. e.g. "float" or "byte"</typeparam>
        /// <param name="fileNames">The name of the image files</param>
        /// <param name="inputHeight">The height of the image, must match the height requirement for the tensor</param>
        /// <param name="inputWidth">The width of the image, must match the width requirement for the tensor</param>
        /// <param name="inputMean">The mean value, it will be subtracted from the input image pixel values</param>
        /// <param name="scale">The scale, after mean is subtracted, the scale will be used to multiply the pixel values</param>
        /// <param name="flipUpSideDown">If true, the image needs to be flipped up side down</param>
        /// <param name="swapBR">If true, will flip the Blue channel with the Red. e.g. If false, the tensor's color channel order will be RGB. If true, the tensor's color channle order will be BGR </param>
        /// <param name="status">Tensorflow status</param>
        /// <returns>The tensor that contains all the image files</returns>
        private static Tensor NativeReadTensorFromImageFiles <T>(
            String[] fileNames,
            int inputHeight     = -1,
            int inputWidth      = -1,
            float inputMean     = 0.0f,
            float scale         = 1.0f,
            bool flipUpSideDown = false,
            bool swapBR         = false,
            Status status       = null) where T : struct
        {
            if (fileNames.Length == 0)
            {
                throw new ArgumentException("Intput file names do not contain any files");
            }

            String fileName = fileNames[0];

            if (!File.Exists(fileName))
            {
                throw new FileNotFoundException(String.Format("File {0} do not exist.", fileName));
            }

            IntPtr dataPtr;
            int    step;
            Tensor t;

#if __ANDROID__
            using (BitmapFactory.Options options = new BitmapFactory.Options())
            {
                options.InPreferredConfig = Android.Graphics.Bitmap.Config.Argb8888; //Prefer ARGB8888 format
                using (Android.Graphics.Bitmap bmp0 = Android.Graphics.BitmapFactory.DecodeFile(fileName, options))
                {
                    if (inputHeight <= 0)
                    {
                        inputHeight = bmp0.Height;
                    }
                    if (inputWidth <= 0)
                    {
                        inputWidth = bmp0.Width;
                    }
                    if (typeof(T) == typeof(float))
                    {
                        t = new Tensor(DataType.Float,
                                       new int[] { fileNames.Length, (int)inputHeight, (int)inputWidth, 3 });
                    }
                    else if (typeof(T) == typeof(byte))
                    {
                        t = new Tensor(DataType.Uint8,
                                       new int[] { fileNames.Length, (int)inputHeight, (int)inputWidth, 3 });
                    }
                    else
                    {
                        throw new Exception(String.Format("Conversion to tensor of type {0} is not implemented",
                                                          typeof(T)));
                    }

                    dataPtr = t.DataPointer;
                    step    = NativeImageIO.ReadBitmapToTensor <T>(
                        bmp0,
                        dataPtr,
                        inputHeight,
                        inputWidth,
                        inputMean,
                        scale,
                        flipUpSideDown,
                        swapBR);
                    dataPtr = new IntPtr(dataPtr.ToInt64() + step);
                }

                for (int i = 1; i < fileNames.Length; i++)
                {
                    fileName = fileNames[i];
                    if (!File.Exists(fileName))
                    {
                        throw new FileNotFoundException(String.Format("File {0} do not exist.", fileName));
                    }

                    //Read the file using Bitmap class
                    using (Android.Graphics.Bitmap bmp = Android.Graphics.BitmapFactory.DecodeFile(fileName, options))
                    {
                        step = NativeImageIO.ReadBitmapToTensor <T>(
                            bmp,
                            dataPtr,
                            inputHeight,
                            inputWidth,
                            inputMean,
                            scale,
                            flipUpSideDown,
                            swapBR);

                        dataPtr = new IntPtr(dataPtr.ToInt64() + step);
                    }
                }
            }
#elif __MACOS__
            using (NSImage image0 = new NSImage(fileName))
            {
                if (inputHeight <= 0)
                {
                    inputHeight = (int)image0.Size.Height;
                }
                if (inputWidth <= 0)
                {
                    inputWidth = (int)image0.Size.Width;
                }
                if (typeof(T) == typeof(float))
                {
                    t = new Tensor(DataType.Float,
                                   new int[] { fileNames.Length, (int)inputHeight, (int)inputWidth, 3 });
                }
                else if (typeof(T) == typeof(byte))
                {
                    t = new Tensor(DataType.Uint8,
                                   new int[] { fileNames.Length, (int)inputHeight, (int)inputWidth, 3 });
                }
                else
                {
                    throw new Exception(String.Format("Conversion to tensor of type {0} is not implemented",
                                                      typeof(T)));
                }

                dataPtr = t.DataPointer;
                step    = NativeImageIO.ReadImageToTensor <T>(
                    image0, dataPtr, inputHeight, inputWidth, inputMean, scale,
                    flipUpSideDown, swapBR);
                dataPtr = new IntPtr(dataPtr.ToInt64() + step);
            }

            for (int i = 1; i < fileNames.Length; i++)
            {
                fileName = fileNames[i];
                if (!File.Exists(fileName))
                {
                    throw new FileNotFoundException(String.Format("File {0} do not exist.", fileName));
                }

                //Read the file using Bitmap class
                using (NSImage image = new NSImage(fileName))
                {
                    step = NativeImageIO.ReadImageToTensor <T>(image, dataPtr, inputHeight, inputWidth, inputMean, scale,
                                                               flipUpSideDown, swapBR);

                    dataPtr = new IntPtr(dataPtr.ToInt64() + step);
                }
            }
#else
            using (System.Drawing.Bitmap bmp0 = new System.Drawing.Bitmap(fileName))
            {
                if (inputHeight <= 0)
                {
                    inputHeight = bmp0.Height;
                }
                if (inputWidth <= 0)
                {
                    inputWidth = bmp0.Width;
                }
                if (typeof(T) == typeof(float))
                {
                    t = new Tensor(DataType.Float,
                                   new int[] { fileNames.Length, (int)inputHeight, (int)inputWidth, 3 });
                }
                else if (typeof(T) == typeof(byte))
                {
                    t = new Tensor(DataType.Uint8,
                                   new int[] { fileNames.Length, (int)inputHeight, (int)inputWidth, 3 });
                }
                else
                {
                    throw new Exception(String.Format("Conversion to tensor of type {0} is not implemented",
                                                      typeof(T)));
                }

                dataPtr = t.DataPointer;
                step    = NativeImageIO.ReadBitmapToTensor <T>(bmp0, dataPtr, inputHeight, inputWidth, inputMean, scale,
                                                               flipUpSideDown, swapBR);
                dataPtr = new IntPtr(dataPtr.ToInt64() + step);
            }

            for (int i = 1; i < fileNames.Length; i++)
            {
                fileName = fileNames[i];
                if (!File.Exists(fileName))
                {
                    throw new FileNotFoundException(String.Format("File {0} do not exist.", fileName));
                }

                //Read the file using Bitmap class
                using (System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(fileName))
                {
                    step = NativeImageIO.ReadBitmapToTensor <T>(bmp, dataPtr, inputHeight, inputWidth, inputMean, scale,
                                                                flipUpSideDown, swapBR);

                    dataPtr = new IntPtr(dataPtr.ToInt64() + step);
                }
            }
#endif
            return(t);
        }
コード例 #27
0
    private void RecognizeAndUpdateText(Texture2D texture)
    {
        if (_mobilenet == null)
        {
            _displayMessage = "Waiting for mobile net model to be loaded...";
            return;
        }

        Stopwatch watch = Stopwatch.StartNew();

        CocoSsdMobilenet.RecognitionResult[] results = _mobilenet.Recognize(texture, true, false, 0.5f);
        watch.Stop();

        if (drawableTexture == null || drawableTexture.width != texture.width ||
            drawableTexture.height != texture.height)
        {
            drawableTexture = new Texture2D(texture.width, texture.height, TextureFormat.ARGB32, false);
        }
        drawableTexture.SetPixels(texture.GetPixels());
        Annotation[] annotations = new Annotation[results.Length];
        for (int i = 0; i < results.Length; i++)
        {
            Annotation annotation = new Annotation();
            annotation.Rectangle = results[i].Rectangle;
            annotation.Label     = String.Format("{0}:({1:0.00}%)", results[i].Label, results[i].Score * 100);
            annotations[i]       = annotation;
        }

        String objectNames = String.Empty;

        foreach (Annotation annotation in annotations)
        {
            float left   = annotation.Rectangle[0] * drawableTexture.width;
            float top    = annotation.Rectangle[1] * drawableTexture.height;
            float right  = annotation.Rectangle[2] * drawableTexture.width;
            float bottom = annotation.Rectangle[3] * drawableTexture.height;

            Rect scaledLocation = new Rect(left, top, right - left, bottom - top);

            scaledLocation.y      = texture.height - scaledLocation.y;
            scaledLocation.height = -scaledLocation.height;

            NativeImageIO.DrawRect(drawableTexture, scaledLocation, Color.red);

            objectNames = objectNames + annotation.Label + ";";
        }
        drawableTexture.Apply();
        //MultiboxGraph.DrawResults(drawableTexture, results, 0.2f, true);
        if (!String.IsNullOrEmpty(objectNames))
        {
            objectNames = String.Format("({0})", objectNames);
        }

        String resStr = String.Empty;

        if (results != null)
        {
            resStr = String.Format("{0} objects detected{1}. Recognition completed in {2} milliseconds.", annotations.Length, objectNames, watch.ElapsedMilliseconds);
            //resStr = String.Format("Object is {0} with {1}% probability. Recognition completed in {2} milliseconds.", results[0].Label, results[0].Probability * 100, watch.ElapsedMilliseconds);
        }

        _displayMessage = resStr;
    }
コード例 #28
0
        public static Tensor ReadTensorFromImageFile(String fileName, int inputHeight = -1, int inputWidth = -1, float inputMean = 0.0f, float scale = 1.0f, Status status = null)
        {
#if __ANDROID__
            Android.Graphics.Bitmap bmp = BitmapFactory.DecodeFile(fileName);

            if (inputHeight > 0 || inputWidth > 0)
            {
                Bitmap resized = Bitmap.CreateScaledBitmap(bmp, inputWidth, inputHeight, false);
                bmp.Dispose();
                bmp = resized;
            }
            int[]   intValues   = new int[bmp.Width * bmp.Height];
            float[] floatValues = new float[bmp.Width * bmp.Height * 3];
            bmp.GetPixels(intValues, 0, bmp.Width, 0, 0, bmp.Width, bmp.Height);
            for (int i = 0; i < intValues.Length; ++i)
            {
                int val = intValues[i];
                floatValues[i * 3 + 0] = (((val >> 16) & 0xFF) - inputMean) * scale;
                floatValues[i * 3 + 1] = (((val >> 8) & 0xFF) - inputMean) * scale;
                floatValues[i * 3 + 2] = ((val & 0xFF) - inputMean) * scale;
            }

            Tensor t = new Tensor(DataType.Float, new int[] { 1, bmp.Height, bmp.Width, 3 });
            System.Runtime.InteropServices.Marshal.Copy(floatValues, 0, t.DataPointer, floatValues.Length);
            return(t);
#elif __IOS__
            UIImage image = new UIImage(fileName);
            if (inputHeight > 0 || inputWidth > 0)
            {
                UIImage resized = image.Scale(new CGSize(inputWidth, inputHeight));
                image.Dispose();
                image = resized;
            }
            int[]   intValues   = new int[(int)(image.Size.Width * image.Size.Height)];
            float[] floatValues = new float[(int)(image.Size.Width * image.Size.Height * 3)];
            System.Runtime.InteropServices.GCHandle handle = System.Runtime.InteropServices.GCHandle.Alloc(intValues, System.Runtime.InteropServices.GCHandleType.Pinned);
            using (CGImage cgimage = image.CGImage)
                using (CGColorSpace cspace = CGColorSpace.CreateDeviceRGB())
                    using (CGBitmapContext context = new CGBitmapContext(
                               handle.AddrOfPinnedObject(),
                               (nint)image.Size.Width,
                               (nint)image.Size.Height,
                               8,
                               (nint)image.Size.Width * 4,
                               cspace,
                               CGImageAlphaInfo.PremultipliedLast
                               ))
                    {
                        context.DrawImage(new CGRect(new CGPoint(), image.Size), cgimage);
                    }
            handle.Free();

            for (int i = 0; i < intValues.Length; ++i)
            {
                int val = intValues[i];
                floatValues[i * 3 + 0] = (((val >> 16) & 0xFF) - inputMean) * scale;
                floatValues[i * 3 + 1] = (((val >> 8) & 0xFF) - inputMean) * scale;
                floatValues[i * 3 + 2] = ((val & 0xFF) - inputMean) * scale;
            }

            Tensor t = new Tensor(DataType.Float, new int[] { 1, (int)image.Size.Height, (int)image.Size.Width, 3 });
            System.Runtime.InteropServices.Marshal.Copy(floatValues, 0, t.DataPointer, floatValues.Length);
            return(t);
#else
            if (Emgu.TF.Util.Platform.OperationSystem == OS.Windows)
            {
                Tensor t = new Tensor(DataType.Float, new int[] { 1, (int)inputHeight, (int)inputWidth, 3 });
                NativeImageIO.ReadImageFileToTensor(fileName, t.DataPointer, inputHeight, inputWidth, inputMean, scale);
                return(t);
            }
            else
            {
                using (StatusChecker checker = new StatusChecker(status))
                {
                    var       graph = new Graph();
                    Operation input = graph.Placeholder(DataType.String);

                    Operation jpegDecoder = graph.DecodeJpeg(input, 3);                    //dimension 3

                    Operation floatCaster = graph.Cast(jpegDecoder, DstT: DataType.Float); //cast to float

                    Tensor    axis         = new Tensor(0);
                    Operation axisOp       = graph.Const(axis, axis.Type, opName: "axis");
                    Operation dimsExpander = graph.ExpandDims(floatCaster, axisOp); //turn it to dimension [1,3]

                    Operation resized;
                    bool      resizeRequired = (inputHeight > 0) && (inputWidth > 0);
                    if (resizeRequired)
                    {
                        Tensor    size   = new Tensor(new int[] { inputHeight, inputWidth }); // new size;
                        Operation sizeOp = graph.Const(size, size.Type, opName: "size");
                        resized = graph.ResizeBilinear(dimsExpander, sizeOp);                 //resize image
                    }
                    else
                    {
                        resized = dimsExpander;
                    }

                    Tensor    mean        = new Tensor(inputMean);
                    Operation meanOp      = graph.Const(mean, mean.Type, opName: "mean");
                    Operation substracted = graph.Sub(resized, meanOp);

                    Tensor    scaleTensor = new Tensor(scale);
                    Operation scaleOp     = graph.Const(scaleTensor, scaleTensor.Type, opName: "scale");
                    Operation scaled      = graph.Mul(substracted, scaleOp);

                    Session  session      = new Session(graph);
                    Tensor   imageTensor  = Tensor.FromString(File.ReadAllBytes(fileName), status);
                    Tensor[] imageResults = session.Run(new Output[] { input }, new Tensor[] { imageTensor },
                                                        new Output[] { scaled });
                    return(imageResults[0]);
                }
            }
#endif
        }