public static Bitmap Binarize(Bitmap bm, double threshhold) { //Binarize int size = bm.Width * bm.Height; int[] pixels = new int[size]; bm.GetPixels( pixels, 0, bm.Width, 0, 0, bm.Width, bm.Height ); // Calculate overall lightness of image int c; for (int i = 0; i < size; i++) { c = pixels[i]; double whiteDist = Math.Sqrt(Math.Pow(0xff - ((c&0x00FF0000 )>>16),2) + Math.Pow(0xff - ((c & 0x0000FF00 )>>8), 2) + Math.Pow(0xff - (c&0x000000FF), 2)); double blackDist = Math.Sqrt(Math.Pow(0x00 - ((c&0x00FF0000 )>>16),2) + Math.Pow(0x00 - ((c & 0x0000FF00 )>>8), 2) + Math.Pow(0x00 - (c&0x000000FF), 2)); double distance = blackDist + whiteDist; if (whiteDist / distance > threshhold / 30.0) { pixels [i] = Color.Black; } else { pixels [i] = Color.White; } } Bitmap newBitmap = bm.Copy (bm.GetConfig (), true); newBitmap.SetPixels (pixels, 0, bm.Width, 0, 0, bm.Width, bm.Height); return newBitmap; }
/// <summary> /// Convert a Bitmap to and from this Mat /// </summary> /// <param name="mat">The mat to copy Bitmap into</param> /// <param name="bitmap">The bitmap to copy into mat</param> public static void SetBitmap(this Mat mat, Android.Graphics.Bitmap bitmap) { Android.Graphics.Bitmap.Config config = bitmap.GetConfig(); if (config.Equals(Android.Graphics.Bitmap.Config.Argb8888)) { using (BitmapArgb8888Image bi = new BitmapArgb8888Image(bitmap)) { CvInvoke.CvtColor(bi, mat, ColorConversion.Rgba2Bgra); } } else if (config.Equals(Android.Graphics.Bitmap.Config.Rgb565)) { Size size = new Size(bitmap.Width, bitmap.Height); int[] values = new int[size.Width * size.Height]; bitmap.GetPixels(values, 0, size.Width, 0, 0, size.Width, size.Height); GCHandle handle = GCHandle.Alloc(values, GCHandleType.Pinned); using (Mat bgra = new Mat(size, DepthType.Cv8U, 4, handle.AddrOfPinnedObject(), size.Width * 4)) { bgra.CopyTo(mat); } handle.Free(); } else { throw new NotImplementedException(String.Format("Coping from Bitmap of {0} is not implemented", config)); } }
private static Bitmap ChangeColor(Bitmap bitmap, Color fromColor, Color targetColor, float tolerance = 20) { int width = bitmap.Width; int height = bitmap.Height; int[] pixels = new int[width * height]; float[] redRange = new float[2]{ (float)Math.Max(fromColor.R - (tolerance / 2), 0.0), (float)Math.Min(fromColor.R + (tolerance / 2), 255.0)}; float[] greenRange = new float[2]{ (float)Math.Max(fromColor.G - (tolerance / 2), 0.0), (float)Math.Min(fromColor.G + (tolerance / 2), 255.0)}; float[] blueRange = new float[2]{ (float)Math.Max(fromColor.B - (tolerance / 2), 0.0), (float)Math.Min(fromColor.B + (tolerance / 2), 255.0)}; bitmap.GetPixels(pixels, 0, width, 0, 0, width, height); for (int i = 0; i < pixels.Length; i++) { if (pixels[i] == fromColor) { pixels[i] = new Color(targetColor.R, targetColor.G, targetColor.B, targetColor.A - 1); } int red = Color.GetRedComponent(pixels[i]); int green = Color.GetGreenComponent(pixels[i]); int blue = Color.GetBlueComponent(pixels[i]); int alpha = Color.GetAlphaComponent(pixels[i]); if (((red >= redRange[0]) && (red <= redRange[1])) && ((green >= greenRange[0]) && (green <= greenRange[1])) && ((blue >= blueRange[0]) && (blue <= blueRange[1])) && ((alpha > 0 && alpha < 254))) { pixels[i] = new Color(targetColor.R, targetColor.G, targetColor.B, targetColor.A - 1); } } if (bitmap.IsMutable) { bitmap.SetPixels(pixels, 0, width, 0, 0, width, height); return bitmap; } else { var mutableBitmap = bitmap.Copy(bitmap.GetConfig(), true); mutableBitmap.SetPixels(pixels, 0, width, 0, 0, width, height); return mutableBitmap; } }
/// <summary> /// Initializes a new instance of the <see cref="BitmapLuminanceSource"/> class. /// </summary> /// <param name="bitmap">The bitmap.</param> public BitmapLuminanceSource(Bitmap bitmap) : base(bitmap.Width, bitmap.Height) { // get all pixels at once from the bitmap (should be one of the fastest ways to analyze the whole picture) var pixels = new int[bitmap.Width * bitmap.Height]; bitmap.GetPixels(pixels, 0, bitmap.Width, 0, 0, bitmap.Width, bitmap.Height); // convert the pixel array to a byte array because the underlying method of // RGBLuminanceSource doesn't support an int array var pixelBytes = new byte[pixels.Length * 4]; Buffer.BlockCopy(pixels, 0, pixelBytes, 0, pixelBytes.Length); // calculating the luminance values the same way as RGBLuminanceSource CalculateLuminance(pixelBytes, BitmapFormat.RGB32); }
//#region Conversion with Bitmap /// <summary> /// The Get property provide a more efficient way to convert Image<Gray, Byte>, Image<Bgr, Byte> and Image<Bgra, Byte> into Bitmap /// such that the image data is <b>shared</b> with Bitmap. /// If you change the pixel value on the Bitmap, you change the pixel values on the Image object as well! /// For other types of image this property has the same effect as ToBitmap() /// <b>Take extra caution not to use the Bitmap after the Image object is disposed</b> /// The Set property convert the bitmap to this Image type. /// </summary> public static Image <TColor, TDepth> ToImage <TColor, TDepth>(this Bitmap bitmap) where TColor : struct, IColor where TDepth : new() { #region reallocate memory if necessary Size size = new Size(bitmap.Width, bitmap.Height); Image <TColor, TDepth> image = new Image <TColor, TDepth>(size); /* * if (image.Ptr == IntPtr.Zero) * { * image.AllocateData(size.Height, size.Width, image.NumberOfChannels); * } * else if (!Size.Equals(size)) * { * image.DisposeObject(); * image.AllocateData(size.Height, size.Width, image.NumberOfChannels); * }*/ #endregion Android.Graphics.Bitmap.Config config = bitmap.GetConfig(); if (config.Equals(Android.Graphics.Bitmap.Config.Argb8888)) { using (BitmapArgb8888Image bi = new BitmapArgb8888Image(bitmap)) { image.ConvertFrom(bi); } } else if (config.Equals(Android.Graphics.Bitmap.Config.Rgb565)) { int[] values = new int[size.Width * size.Height]; bitmap.GetPixels(values, 0, size.Width, 0, 0, size.Width, size.Height); GCHandle handle = GCHandle.Alloc(values, GCHandleType.Pinned); using (Image <Bgra, Byte> bgra = new Image <Bgra, byte>(size.Width, size.Height, size.Width * 4, handle.AddrOfPinnedObject())) { image.ConvertFrom(bgra); } handle.Free(); } else { throw new NotImplementedException(String.Format("Coping from Bitmap of {0} is not implemented", config)); } return(image); }
private static Bitmap CreateOverlayedBitmap(Bitmap bitmap, int width, int height) { int[] originalPixels = new int[bitmap.Width * bitmap.Height]; bitmap.GetPixels(originalPixels, 0, bitmap.Width, 0, 0, bitmap.Width, bitmap.Height); int[] pixels = new int[width * height]; int xStart = (width - bitmap.Width) / 2; int xEnd = (width + bitmap.Width) / 2; for (int y = 0; y < height; y++) { int rowStart = y*width; int originalRowStart = y*bitmap.Width; for (int ox = 0, x = xStart; x < xEnd; x++, ox++) { pixels[rowStart + x] = originalPixels[originalRowStart + ox]; } } return Bitmap.CreateBitmap(pixels, width, height, bitmap.GetConfig()); }
Bitmap RGB565toARGB888(Bitmap img) { int numPixels = img.Width * img.Height; //Create a Bitmap of the appropriate format. if (tmp == null) { tmp = Bitmap.CreateBitmap(img.Width, img.Height, Bitmap.Config.Argb8888); pixels = new int[numPixels]; } //Get JPEG pixels. Each int is the color values for one pixel. img.GetPixels(pixels, 0, img.Width, 0, 0, img.Width, img.Height); //Set RGB pixels. tmp.SetPixels(pixels, 0, tmp.Width, 0, 0, tmp.Width, tmp.Height); return tmp; }
// This code is a C# port of the Java code which can be found at: // http://www.java2s.com/Code/Android/2D-Graphics/Generateablurredbitmapfromgivenone.htm // // The following code is another example (Java based): // http://incubator.quasimondo.com/processing/stackblur.pde public Bitmap GetBlurredBitmap(Bitmap original, int radius) { if (radius < 1) { throw new ArgumentOutOfRangeException("radius", "Radius must be > =1."); } int width = original.Width; int height = original.Height; int wm = width - 1; int hm = height - 1; int wh = width * height; int div = radius + radius + 1; int[] r = new int[wh]; int[] g = new int[wh]; int[] b = new int[wh]; int rsum, gsum, bsum, x, y, i; int p1, p2; int[] vmin = new int[Math.Max(width, height)]; int[] vmax = new int[Math.Max(width, height)]; int[] dv = new int[256 * div]; for (i = 0; i < 256 * div; i++) { dv[i] = i / div; } int[] blurredBitmap = new int[wh]; original.GetPixels(blurredBitmap, 0, width, 0, 0, width, height); int yw = 0; int yi = 0; for (y = 0; y < height; y++) { rsum = 0; gsum = 0; bsum = 0; for (i = -radius; i <= radius; i++) { int p = blurredBitmap[yi + Math.Min(wm, Math.Max(i, 0))]; rsum += (p & 0xff0000) >> 16; gsum += (p & 0x00ff00) >> 8; bsum += p & 0x0000ff; } for (x = 0; x < width; x++) { r[yi] = dv[rsum]; g[yi] = dv[gsum]; b[yi] = dv[bsum]; if (y == 0) { vmin[x] = Math.Min(x + radius + 1, wm); vmax[x] = Math.Max(x - radius, 0); } p1 = blurredBitmap[yw + vmin[x]]; p2 = blurredBitmap[yw + vmax[x]]; rsum += ((p1 & 0xff0000) - (p2 & 0xff0000)) >> 16; gsum += ((p1 & 0x00ff00) - (p2 & 0x00ff00)) >> 8; bsum += (p1 & 0x0000ff) - (p2 & 0x0000ff); yi++; } yw += width; } for (x = 0; x < width; x++) { rsum = gsum = bsum = 0; int yp = -radius * width; for (i = -radius; i <= radius; i++) { yi = Math.Max(0, yp) + x; rsum += r[yi]; gsum += g[yi]; bsum += b[yi]; yp += width; } yi = x; for (y = 0; y < height; y++) { blurredBitmap[yi] = (int)(0xff000000 | (dv[rsum] << 16) | (dv[gsum] << 8) | dv[bsum]); if (x == 0) { vmin[y] = Math.Min(y + radius + 1, hm) * width; vmax[y] = Math.Max(y - radius, 0) * width; } p1 = x + vmin[y]; p2 = x + vmax[y]; rsum += r[p1] - r[p2]; gsum += g[p1] - g[p2]; bsum += b[p1] - b[p2]; yi += width; } } Bitmap.Config config = Bitmap.Config.Rgb565; return Bitmap.CreateBitmap(blurredBitmap, width, height, config); }
public static void ReadImageFileToTensor <T>( String fileName, IntPtr dest, int inputHeight = -1, int inputWidth = -1, float inputMean = 0.0f, float scale = 1.0f, bool flipUpSideDown = false, bool swapBR = false) where T : struct { #if __ANDROID__ if (flipUpSideDown) { throw new NotImplementedException("Flip Up Side Down is Not implemented"); } if (swapBR) { throw new NotImplementedException("swapBR is Not implemented"); } 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; } Marshal.Copy(floatValues, 0, dest, floatValues.Length); #elif __IOS__ if (flipUpSideDown) { throw new NotImplementedException("Flip Up Side Down is Not implemented"); } if (swapBR) { throw new NotImplementedException("swapBR is Not implemented"); } 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; } System.Runtime.InteropServices.Marshal.Copy(floatValues, 0, dest, floatValues.Length); #elif __UNIFIED__ if (flipUpSideDown) { throw new NotImplementedException("Flip Up Side Down is Not implemented"); } if (swapBR) { throw new NotImplementedException("swapBR is Not implemented"); } NSImage image = new NSImage(fileName); if (inputHeight > 0 || inputWidth > 0) { NSImage resized = new NSImage(new CGSize(inputWidth, inputHeight)); resized.LockFocus(); image.DrawInRect(new CGRect(0, 0, inputWidth, inputHeight), CGRect.Empty, NSCompositingOperation.SourceOver, 1.0f); resized.UnlockFocus(); 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; } System.Runtime.InteropServices.Marshal.Copy(floatValues, 0, dest, floatValues.Length); #elif UNITY_EDITOR || UNITY_IOS || UNITY_ANDROID || UNITY_STANDALONE Texture2D texture = ReadTexture2DFromFile(fileName); ReadTensorFromTexture2D <T>(texture, dest, inputHeight, inputWidth, inputMean, scale, flipUpSideDown, false); #else if (Emgu.TF.Util.Platform.OperationSystem == OS.Windows) { //Do something for Windows System.Drawing.Bitmap bmp = new Bitmap(fileName); if (inputHeight > 0 || inputWidth > 0) { //resize bmp System.Drawing.Bitmap newBmp = new Bitmap(bmp, inputWidth, inputHeight); bmp.Dispose(); bmp = newBmp; //bmp.Save("tmp.png"); } if (flipUpSideDown) { bmp.RotateFlip(RotateFlipType.RotateNoneFlipY); } byte[] byteValues = new byte[bmp.Width * bmp.Height * 3]; System.Drawing.Imaging.BitmapData bd = new System.Drawing.Imaging.BitmapData(); bmp.LockBits( new Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb, bd); Marshal.Copy(bd.Scan0, byteValues, 0, byteValues.Length); bmp.UnlockBits(bd); if (typeof(T) == typeof(float)) { int imageSize = bmp.Width * bmp.Height; float[] floatValues = new float[imageSize * 3]; if (swapBR) { for (int i = 0; i < imageSize; ++i) { floatValues[i * 3] = (byte)(((float)byteValues[i * 3 + 2] - inputMean) * scale); floatValues[i * 3 + 1] = (byte)(((float)byteValues[i * 3 + 1] - inputMean) * scale); floatValues[i * 3 + 2] = (byte)(((float)byteValues[i * 3 + 0] - inputMean) * scale); } } else { for (int i = 0; i < byteValues.Length; ++i) { floatValues[i] = ((float)byteValues[i] - inputMean) * scale; } } Marshal.Copy(floatValues, 0, dest, floatValues.Length); } else if (typeof(T) == typeof(byte)) { if (swapBR) { int imageSize = bmp.Width * bmp.Height; //byte[] bValues = new byte[imageSize * 3]; for (int i = 0; i < imageSize; ++i) { byte c0 = (byte)(((float)byteValues[i * 3 + 2] - inputMean) * scale); byte c1 = (byte)(((float)byteValues[i * 3 + 1] - inputMean) * scale); byte c2 = (byte)(((float)byteValues[i * 3 + 0] - inputMean) * scale); byteValues[i * 3] = c0; byteValues[i * 3 + 1] = c1; byteValues[i * 3 + 2] = c2; } } else { if (!(inputMean == 0.0f && scale == 1.0f)) { for (int i = 0; i < byteValues.Length; ++i) { byteValues[i] = (byte)(((float)byteValues[i] - inputMean) * scale); } } } Marshal.Copy(byteValues, 0, dest, byteValues.Length); } else { throw new Exception(String.Format("Destination data type {0} is not supported.", typeof(T).ToString())); } } else //Unix { if (flipUpSideDown) { throw new NotImplementedException("Flip Up Side Down is Not implemented"); } throw new Exception("Not implemented"); } #endif }
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 }
/// <summary> /// Read an image file, 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="fileName">The name of the image file</param> /// <param name="dest">The native pointer where the image pixels values will be saved to.</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> public static void ReadImageFileToTensor <T>( String fileName, IntPtr dest, int inputHeight = -1, int inputWidth = -1, float inputMean = 0.0f, float scale = 1.0f, bool flipUpSideDown = false, bool swapBR = false) where T : struct { if (!File.Exists(fileName)) { throw new FileNotFoundException(String.Format("File {0} do not exist.", fileName)); } Android.Graphics.Bitmap bmp = BitmapFactory.DecodeFile(fileName); if (inputHeight > 0 || inputWidth > 0) { Bitmap resized = Bitmap.CreateScaledBitmap(bmp, inputWidth, inputHeight, false); bmp.Dispose(); bmp = resized; } if (flipUpSideDown) { Matrix matrix = new Matrix(); matrix.PostScale(1, -1, bmp.Width / 2, bmp.Height / 2); Bitmap flipped = Bitmap.CreateBitmap(bmp, 0, 0, bmp.Width, bmp.Height, matrix, true); bmp.Dispose(); bmp = flipped; } 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); if (swapBR) { for (int i = 0; i < intValues.Length; ++i) { int val = intValues[i]; floatValues[i * 3 + 0] = ((val & 0xFF) - inputMean) * scale; floatValues[i * 3 + 1] = (((val >> 8) & 0xFF) - inputMean) * scale; floatValues[i * 3 + 2] = (((val >> 16) & 0xFF) - inputMean) * scale; } } else { 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; } } if (typeof(T) == typeof(float)) { Marshal.Copy(floatValues, 0, dest, floatValues.Length); } else if (typeof(T) == typeof(byte)) { //copy float to bytes byte[] byteValues = new byte[floatValues.Length]; for (int i = 0; i < floatValues.Length; i++) { byteValues[i] = (byte)floatValues[i]; } Marshal.Copy(byteValues, 0, dest, byteValues.Length); } else { throw new NotImplementedException(String.Format("Destination data type {0} is not supported.", typeof(T).ToString())); } }
public static void Blur(Bitmap original, Bitmap blurred, int radius) { if (radius < 1) { throw new ArgumentOutOfRangeException("radius", "Radius must be > 0."); } int width = original.Width; int height = original.Height; int wm = width - 1; int hm = height - 1; int wh = width * height; int div = radius + radius + 1; int[] a = new int[wh]; int[] r = new int[wh]; int[] g = new int[wh]; int[] b = new int[wh]; int asum, rsum, gsum, bsum; int x, y, i; int p1, p2; int[] vmin = new int[Math.Max(width, height)]; int[] vmax = new int[Math.Max(width, height)]; int[] dv = new int[256 * div]; for (i = 0; i < 256 * div; i++) { dv[i] = i / div; } int[] blurredBitmap = new int[wh]; original.GetPixels(blurredBitmap, 0, width, 0, 0, width, height); Premultiply(blurredBitmap); int yw = 0; int yi = 0; for (y = 0; y < height; y++) { asum = 0; rsum = 0; gsum = 0; bsum = 0; for (i = -radius; i <= radius; i++) { int p = blurredBitmap[yi + Math.Min(wm, Math.Max(i, 0))]; asum += A(p); rsum += R(p); gsum += G(p); bsum += B(p); } for (x = 0; x < width; x++) { a[yi] = dv[asum]; r[yi] = dv[rsum]; g[yi] = dv[gsum]; b[yi] = dv[bsum]; if (y == 0) { vmin[x] = Math.Min(x + radius + 1, wm); vmax[x] = Math.Max(x - radius, 0); } p1 = blurredBitmap[yw + vmin[x]]; p2 = blurredBitmap[yw + vmax[x]]; asum += A(p1) - A(p2); rsum += R(p1) - R(p2); gsum += G(p1) - G(p2); bsum += B(p1) - B(p2); yi++; } yw += width; } for (x = 0; x < width; x++) { asum = rsum = gsum = bsum = 0; int yp = -radius * width; for (i = -radius; i <= radius; i++) { yi = Math.Max(0, yp) + x; asum += a[yi]; rsum += r[yi]; gsum += g[yi]; bsum += b[yi]; yp += width; } yi = x; for (y = 0; y < height; y++) { blurredBitmap[yi] = (dv[asum] << 24) | (dv[rsum] << 16) | (dv[gsum] << 8) | (dv[bsum]); if (x == 0) { vmin[y] = Math.Min(y + radius + 1, hm) * width; vmax[y] = Math.Max(y - radius, 0) * width; } p1 = x + vmin[y]; p2 = x + vmax[y]; asum += a[p1] - a[p2]; rsum += r[p1] - r[p2]; gsum += g[p1] - g[p2]; bsum += b[p1] - b[p2]; yi += width; } } Unpremultiply(blurredBitmap); blurred.SetPixels(blurredBitmap, 0, width, 0, 0, width, height); }
// WHAT IS THE DEFAULT FONT FOR ANDROID? #endif // Partial class implementation of draw() in c# to allow use of unsafe code.. public unsafe void draw(IBitmapDrawable source, flash.geom.Matrix matrix = null, ColorTransform colorTransform = null, string blendMode = null, Rectangle clipRect = null, Boolean smoothing = false) { #if PLATFORM_MONOMAC || PLATFORM_MONOTOUCH if (source is flash.text.TextField) { flash.text.TextField tf = source as flash.text.TextField; flash.text.TextFormat format = tf.defaultTextFormat; // $$TODO figure out how to get rid of this extra data copy var sizeToDraw = (width * height) << 2; if (sizeToDraw == 0) { return; } string fontName = format.font; float fontSize = (format.size is double) ? (float)(double)format.size : ((format.size is int) ? (float)(int)format.size : 10); // Check if the font is installed? bool hasFont = true; if (!sHasFont.TryGetValue(fontName, out hasFont)) { #if PLATFORM_MONOTOUCH UIFont font = UIFont.FromName(fontName, 10); sHasFont[fontName] = hasFont = font != null; if (font != null) { font.Dispose(); } #elif PLATFORM_MONOMAC NSFont font = NSFont.FromFontName(fontName, 10); sHasFont[fontName] = hasFont = font != null; if (font != null) { font.Dispose(); } #else sHasFont[fontName] = false; #endif } if (!hasFont) { fontName = DEFAULT_FONT; } fixed(uint *data = mData) { using (CGBitmapContext context = new CGBitmapContext(new IntPtr(data), width, height, 8, 4 * width, CGColorSpace.CreateDeviceRGB(), CGImageAlphaInfo.PremultipliedLast)) { uint tfColor = format.color != null ? (uint)(format.color) : 0; float r = (float)((tfColor >> 16) & 0xFF) / 255.0f; float g = (float)((tfColor >> 8) & 0xFF) / 255.0f; float b = (float)((tfColor >> 0) & 0xFF) / 255.0f; float a = (float)(tf.alpha); CGColor color = new CGColor(r, g, b, a); context.SetFillColor(color); context.SetStrokeColor(color); context.SelectFont(fontName, fontSize, CGTextEncoding.MacRoman); context.SetAllowsAntialiasing(((tf.antiAliasType as string) == flash.text.AntiAliasType.ADVANCED)); double x = matrix.tx; double y = matrix.ty; // invert y because the CG origin is bottom,left y = height - tf.textHeight - y; // align text switch (format.align) { case TextFormatAlign.LEFT: // no adjustment required break; case TextFormatAlign.CENTER: // center x x += width / 2; x -= tf.textWidth / 2; break; case TextFormatAlign.RIGHT: // right justify x x += width; x -= tf.textWidth; break; default: throw new System.NotImplementedException(); } // draw text context.ShowTextAtPoint((float)x, (float)y, tf.text); } } } else #elif PLATFORM_MONODROID if (source is flash.text.TextField) { flash.text.TextField tf = source as flash.text.TextField; flash.text.TextFormat format = tf.defaultTextFormat; // $$TODO figure out how to get rid of this extra data copy var data = new byte[width * height * 4]; System.Buffer.BlockCopy(mData, 0, data, 0, data.Length); Android.Graphics.Bitmap.Config config = Android.Graphics.Bitmap.Config.Argb8888; Android.Graphics.Bitmap bitmap = Android.Graphics.Bitmap.CreateBitmap(width, height, config); Canvas canvas = new Canvas(bitmap); var x = matrix.tx; var y = matrix.ty; // invert y because the CG origin is bottom,left // y = height - tf.textHeight - y; // align text switch (format.align) { case TextFormatAlign.LEFT: // no adjustment required break; case TextFormatAlign.CENTER: // center x x += width / 2; x -= tf.textWidth / 2; break; case TextFormatAlign.RIGHT: // right justify x x += width; x -= tf.textWidth; break; default: throw new System.NotImplementedException(); } Paint paint = new Paint(PaintFlags.AntiAlias); paint.Color = Color.Black; paint.TextSize = (float)format.size; paint.SetTypeface(Typeface.Create(format.font, TypefaceStyle.Normal)); paint.TextAlign = Paint.Align.Center; canvas.DrawText(tf.text, (float)x, (float)y, paint); mData = new uint[bitmap.Width * bitmap.Height]; var buffer = new int[bitmap.Width * bitmap.Height]; bitmap.GetPixels(buffer, 0, width, 0, 0, width, height); for (int i = 0; i < buffer.Length; i++) { mData[i] = (uint)buffer[i]; } } else #endif if (source is flash.display.BitmapData) { //naive implementation , //to be implemented: // -smoothing / antialiasing, // -blend mode // -colorTransform // -cliprect BitmapData sourceBitmap = source as BitmapData; flash.geom.Matrix matInverse = (matrix != null) ? matrix.clone() : new flash.geom.Matrix(); matInverse.invert(); for (int y = 0; y < mHeight; y++) { for (int x = 0; x < mWidth; x++) { int x2 = (int)(x * matInverse.a + y * matInverse.c + matInverse.tx); int y2 = (int)(x * matInverse.b + y * matInverse.d + matInverse.ty); if (x2 >= 0 && y2 >= 0 && x2 < sourceBitmap.width && y2 < sourceBitmap.height) { mData[x + y * mWidth] = sourceBitmap.mData[x2 + y2 * sourceBitmap.mWidth]; } } } } else { _root.trace_fn.trace("NotImplementedWarning: BitmapData.draw()"); } }
public static void ReadImageFileToTensor(String fileName, IntPtr dest, int inputHeight = -1, int inputWidth = -1, float inputMean = 0.0f, float scale = 1.0f) { #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; } System.Runtime.InteropServices.Marshal.Copy(floatValues, 0, dest, floatValues.Length); #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; } System.Runtime.InteropServices.Marshal.Copy(floatValues, 0, dest, floatValues.Length); #elif __UNIFIED__ NSImage image = new NSImage(fileName); if (inputHeight > 0 || inputWidth > 0) { NSImage resized = new NSImage(new CGSize(inputWidth, inputHeight)); resized.LockFocus(); image.DrawInRect(new CGRect(0, 0, inputWidth, inputHeight), CGRect.Empty, NSCompositingOperation.SourceOver, 1.0f); resized.UnlockFocus(); 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; } System.Runtime.InteropServices.Marshal.Copy(floatValues, 0, dest, floatValues.Length); #else if (Emgu.TF.Util.Platform.OperationSystem == OS.Windows) { //Do something for Windows System.Drawing.Bitmap bmp = new Bitmap(fileName); if (inputHeight > 0 || inputWidth > 0) { //resize bmp System.Drawing.Bitmap newBmp = new Bitmap(bmp, inputWidth, inputHeight); bmp.Dispose(); bmp = newBmp; //bmp.Save("tmp.png"); } byte[] byteValues = new byte[bmp.Width * bmp.Height * 3]; System.Drawing.Imaging.BitmapData bd = new System.Drawing.Imaging.BitmapData(); bmp.LockBits( new Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb, bd); System.Runtime.InteropServices.Marshal.Copy(bd.Scan0, byteValues, 0, byteValues.Length); bmp.UnlockBits(bd); float[] floatValues = new float[bmp.Width * bmp.Height * 3]; for (int i = 0; i < byteValues.Length; ++i) { floatValues[i] = ((float)byteValues[i] - inputMean) * scale; } System.Runtime.InteropServices.Marshal.Copy(floatValues, 0, dest, floatValues.Length); } else { throw new Exception("Not implemented"); } #endif }
/// <summary> /// Read an image file, 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="fileName">The name of the image file</param> /// <param name="dest">The native pointer where the image pixels values will be saved to.</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 substracted from the input image pixel values</param> /// <param name="scale">The scale, after mean is substracted, 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> public static void ReadImageFileToTensor <T>( String fileName, IntPtr dest, int inputHeight = -1, int inputWidth = -1, float inputMean = 0.0f, float scale = 1.0f, bool flipUpSideDown = false, bool swapBR = false) where T : struct { if (!File.Exists(fileName)) { throw new FileNotFoundException(String.Format("File {0} do not exist.", fileName)); } #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; } if (flipUpSideDown) { Matrix matrix = new Matrix(); matrix.PostScale(1, -1, bmp.Width / 2, bmp.Height / 2); Bitmap flipped = Bitmap.CreateBitmap(bmp, 0, 0, bmp.Width, bmp.Height, matrix, true); bmp.Dispose(); bmp = flipped; } 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); if (swapBR) { for (int i = 0; i < intValues.Length; ++i) { int val = intValues[i]; floatValues[i * 3 + 0] = ((val & 0xFF) - inputMean) * scale; floatValues[i * 3 + 1] = (((val >> 8) & 0xFF) - inputMean) * scale; floatValues[i * 3 + 2] = (((val >> 16) & 0xFF) - inputMean) * scale; } } else { 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; } } if (typeof(T) == typeof(float)) { Marshal.Copy(floatValues, 0, dest, floatValues.Length); } else if (typeof(T) == typeof(byte)) { //copy float to bytes byte[] byteValues = new byte[floatValues.Length]; for (int i = 0; i < floatValues.Length; i++) { byteValues[i] = (byte)floatValues[i]; } Marshal.Copy(byteValues, 0, dest, byteValues.Length); } else { throw new NotImplementedException(String.Format("Destination data type {0} is not supported.", typeof(T).ToString())); } #elif __IOS__ if (flipUpSideDown) { throw new NotImplementedException("Flip Up Side Down is Not implemented"); } 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(); if (swapBR) { for (int i = 0; i < intValues.Length; ++i) { int val = intValues[i]; floatValues[i * 3 + 0] = ((val & 0xFF) - inputMean) * scale; floatValues[i * 3 + 1] = (((val >> 8) & 0xFF) - inputMean) * scale; floatValues[i * 3 + 2] = (((val >> 16) & 0xFF) - inputMean) * scale; } } else { 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; } } if (typeof(T) == typeof(float)) { Marshal.Copy(floatValues, 0, dest, floatValues.Length); } else if (typeof(T) == typeof(byte)) { //copy float to bytes byte[] byteValues = new byte[floatValues.Length]; for (int i = 0; i < floatValues.Length; i++) { byteValues[i] = (byte)floatValues[i]; } Marshal.Copy(byteValues, 0, dest, byteValues.Length); } else { throw new NotImplementedException(String.Format("Destination data type {0} is not supported.", typeof(T).ToString())); } //System.Runtime.InteropServices.Marshal.Copy(floatValues, 0, dest, floatValues.Length); #elif __UNIFIED__ if (flipUpSideDown) { throw new NotImplementedException("Flip Up Side Down is Not implemented"); } //if (swapBR) // throw new NotImplementedException("swapBR is Not implemented"); NSImage image = new NSImage(fileName); if (inputHeight > 0 || inputWidth > 0) { NSImage resized = new NSImage(new CGSize(inputWidth, inputHeight)); resized.LockFocus(); image.DrawInRect(new CGRect(0, 0, inputWidth, inputHeight), CGRect.Empty, NSCompositingOperation.SourceOver, 1.0f); resized.UnlockFocus(); 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(); if (swapBR) { for (int i = 0; i < intValues.Length; ++i) { int val = intValues[i]; floatValues[i * 3 + 0] = ((val & 0xFF) - inputMean) * scale; floatValues[i * 3 + 1] = (((val >> 8) & 0xFF) - inputMean) * scale; floatValues[i * 3 + 2] = (((val >> 16) & 0xFF) - inputMean) * scale; } } else { 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; } } if (typeof(T) == typeof(float)) { Marshal.Copy(floatValues, 0, dest, floatValues.Length); } else if (typeof(T) == typeof(byte)) { //copy float to bytes byte[] byteValues = new byte[floatValues.Length]; for (int i = 0; i < floatValues.Length; i++) { byteValues[i] = (byte)floatValues[i]; } Marshal.Copy(byteValues, 0, dest, byteValues.Length); } else { throw new NotImplementedException(String.Format("Destination data type {0} is not supported.", typeof(T).ToString())); } //System.Runtime.InteropServices.Marshal.Copy(floatValues, 0, dest, floatValues.Length); #elif UNITY_EDITOR || UNITY_IOS || UNITY_ANDROID || UNITY_STANDALONE Texture2D texture = ReadTexture2DFromFile(fileName); ReadTensorFromTexture2D <T>(texture, dest, inputHeight, inputWidth, inputMean, scale, flipUpSideDown, false); #else //if (System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Windows)) { //Read the file using Bitmap class System.Drawing.Bitmap bmp = new Bitmap(fileName); if (inputHeight > 0 || inputWidth > 0) { //resize bmp System.Drawing.Bitmap newBmp = new Bitmap(bmp, inputWidth, inputHeight); bmp.Dispose(); bmp = newBmp; //bmp.Save("tmp.png"); } if (flipUpSideDown) { bmp.RotateFlip(RotateFlipType.RotateNoneFlipY); } int bmpWidth = bmp.Width; int bmpHeight = bmp.Height; System.Drawing.Imaging.BitmapData bd = new System.Drawing.Imaging.BitmapData(); bmp.LockBits( new Rectangle(0, 0, bmpWidth, bmpHeight), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb, bd); int stride = bd.Stride; byte[] byteValues = new byte[bmpHeight * stride]; Marshal.Copy(bd.Scan0, byteValues, 0, byteValues.Length); bmp.UnlockBits(bd); if (typeof(T) == typeof(float)) { int imageSize = bmpWidth * bmpHeight; float[] floatValues = new float[imageSize * 3]; if (swapBR) { int idx = 0; int rowOffset = 0; for (int i = 0; i < bmpHeight; ++i) { int rowPtr = rowOffset; for (int j = 0; j < bmpWidth; ++j) { float b = ((float)byteValues[rowPtr++] - inputMean) * scale; float g = ((float)byteValues[rowPtr++] - inputMean) * scale; float r = ((float)byteValues[rowPtr++] - inputMean) * scale; floatValues[idx++] = r; floatValues[idx++] = g; floatValues[idx++] = b; } rowOffset += stride; } } else { int idx = 0; int rowOffset = 0; for (int i = 0; i < bmpHeight; ++i) { int rowPtr = rowOffset; for (int j = 0; j < bmpWidth; ++j) { floatValues[idx++] = ((float)byteValues[rowPtr++] - inputMean) * scale; floatValues[idx++] = ((float)byteValues[rowPtr++] - inputMean) * scale; floatValues[idx++] = ((float)byteValues[rowPtr++] - inputMean) * scale; } rowOffset += stride; } } Marshal.Copy(floatValues, 0, dest, floatValues.Length); } else if (typeof(T) == typeof(byte)) { int imageSize = bmp.Width * bmp.Height; if (swapBR) { int idx = 0; for (int i = 0; i < bmpHeight; ++i) { int offset = i * stride; for (int j = 0; j < bmpWidth; ++j) { byte b = (byte)(((float)byteValues[offset++] - inputMean) * scale); byte g = (byte)(((float)byteValues[offset++] - inputMean) * scale); byte r = (byte)(((float)byteValues[offset++] - inputMean) * scale); byteValues[idx++] = r; byteValues[idx++] = g; byteValues[idx++] = b; } } } else { int idx = 0; for (int i = 0; i < bmpHeight; ++i) { int offset = i * stride; for (int j = 0; j < bmpWidth * 3; ++j) { byteValues[idx++] = (byte)(((float)byteValues[offset++] - inputMean) * scale); } } } Marshal.Copy(byteValues, 0, dest, imageSize * 3); } else { throw new NotImplementedException(String.Format("Destination data type {0} is not supported.", typeof(T).ToString())); } } /* * else //Unix * { * //if (flipUpSideDown) * // throw new NotImplementedException("Flip Up Side Down is Not implemented"); * * throw new NotImplementedException("Not implemented"); * }*/ #endif }