ImageEstimatorsCatalog.ConvertToGrayscale Method

Definition

Create a ImageGrayscalingEstimator, which converts images in the column specified in InputColumnName to grayscale images in a new column: OutputColumnName.

public static Microsoft.ML.Transforms.Image.ImageGrayscalingEstimator ConvertToGrayscale (this Microsoft.ML.TransformsCatalog catalog, string outputColumnName, string inputColumnName = default);
static member ConvertToGrayscale : Microsoft.ML.TransformsCatalog * string * string -> Microsoft.ML.Transforms.Image.ImageGrayscalingEstimator
<Extension()>
Public Function ConvertToGrayscale (catalog As TransformsCatalog, outputColumnName As String, Optional inputColumnName As String = Nothing) As ImageGrayscalingEstimator

Parameters

catalog
TransformsCatalog

The transform's catalog.

outputColumnName
String

Name of the column resulting from the transformation of inputColumnName. This column's data type will be the same as that of the input column.

inputColumnName
String

Name of the column to convert images to grayscale from. This estimator operates only on MLImage.

Returns

Examples

using System;
using System.IO;
using Microsoft.ML;
using Microsoft.ML.Data;

namespace Samples.Dynamic
{
    public static class ConvertToGrayscale
    {
        // Sample that loads images from the file system, and converts them to
        // grayscale.
        public static void Example()
        {
            // Create a new ML context, for ML.NET operations. It can be used for
            // exception tracking and logging, as well as the source of randomness.
            var mlContext = new MLContext();

            // Downloading a few images, and an images.tsv file, which contains a
            // list of the files from the dotnet/machinelearning/test/data/images/.
            // If you inspect the fileSystem, after running this line, an "images"
            // folder will be created, containing 4 images, and a .tsv file
            // enumerating the images.
            var imagesDataFile = Microsoft.ML.SamplesUtils.DatasetUtils
                .GetSampleImages();

            // Preview of the content of the images.tsv file
            //
            // imagePath    imageType
            // tomato.bmp   tomato
            // banana.jpg   banana
            // hotdog.jpg   hotdog
            // tomato.jpg   tomato

            var data = mlContext.Data.CreateTextLoader(new TextLoader.Options()
            {
                Columns = new[]
                {
                        new TextLoader.Column("ImagePath", DataKind.String, 0),
                        new TextLoader.Column("Name", DataKind.String, 1),
                 }
            }).Load(imagesDataFile);

            var imagesFolder = Path.GetDirectoryName(imagesDataFile);
            // Image loading pipeline.
            var pipeline = mlContext.Transforms.LoadImages("ImageObject",
                imagesFolder, "ImagePath")
                .Append(mlContext.Transforms.ConvertToGrayscale("Grayscale",
                "ImageObject"));

            var transformedData = pipeline.Fit(data).Transform(data);

            PrintColumns(transformedData);
            // ImagePath    Name         ImageObject              Grayscale
            // tomato.bmp   tomato       {Width=800, Height=534}  {Width=800, Height=534}
            // banana.jpg   banana       {Width=800, Height=288}  {Width=800, Height=288}
            // hotdog.jpg   hotdog       {Width=800, Height=391}  {Width=800, Height=391}
            // tomato.jpg   tomato       {Width=800, Height=534}  {Width=800, Height=534}
        }

        private static void PrintColumns(IDataView transformedData)
        {
            Console.WriteLine("{0, -25} {1, -25} {2, -25} {3, -25}", "ImagePath",
                "Name", "ImageObject", "Grayscale");

            using (var cursor = transformedData.GetRowCursor(transformedData
                .Schema))
            {
                // Note that it is best to get the getters and values *before*
                // iteration, so as to facilitate buffer sharing (if applicable), and
                // column -type validation once, rather than many times.
                ReadOnlyMemory<char> imagePath = default;
                ReadOnlyMemory<char> name = default;
                MLImage imageObject = null;
                MLImage grayscaleImageObject = null;

                var imagePathGetter = cursor.GetGetter<ReadOnlyMemory<char>>(cursor
                    .Schema["ImagePath"]);

                var nameGetter = cursor.GetGetter<ReadOnlyMemory<char>>(cursor
                    .Schema["Name"]);

                var imageObjectGetter = cursor.GetGetter<MLImage>(cursor.Schema[
                    "ImageObject"]);

                var grayscaleGetter = cursor.GetGetter<MLImage>(cursor.Schema[
                    "Grayscale"]);

                while (cursor.MoveNext())
                {
                    imagePathGetter(ref imagePath);
                    nameGetter(ref name);
                    imageObjectGetter(ref imageObject);
                    grayscaleGetter(ref grayscaleImageObject);

                    Console.WriteLine("{0, -25} {1, -25} {2, -25} {3, -25}",
                        imagePath, name, $"Width={imageObject.Width}, Height={imageObject.Height}",
                        $"Width={grayscaleImageObject.Width}, Height={grayscaleImageObject.Height}");
                }

                // Dispose the image.
                imageObject.Dispose();
                grayscaleImageObject.Dispose();
            }
        }
    }
}
using System;
using Microsoft.ML;
using Microsoft.ML.Data;
using Microsoft.ML.Transforms.Image;

namespace Samples.Dynamic
{
    class ConvertToGrayScaleInMemory
    {
        public static void Example()
        {
            var mlContext = new MLContext();
            // Create an image list.
            var images = new[]
            {
                new ImageDataPoint(2, 3, red: 0, green: 0, blue: 255),    // Blue color
                new ImageDataPoint(2, 3, red: 255, green: 0, blue: 0) };  // red color

            // Convert the list of data points to an IDataView object, which is
            // consumable by ML.NET API.
            var data = mlContext.Data.LoadFromEnumerable(images);

            // Convert image to gray scale.
            var pipeline = mlContext.Transforms.ConvertToGrayscale("GrayImage", "Image");

            // Fit the model.
            var model = pipeline.Fit(data);

            // Test path: image files -> IDataView -> Enumerable of Bitmaps.
            var transformedData = model.Transform(data);

            // Load images in DataView back to Enumerable.
            var transformedDataPoints = mlContext.Data.CreateEnumerable<
                ImageDataPoint>(transformedData, false);

            // Print out input and output pixels.
            foreach (var dataPoint in transformedDataPoints)
            {
                var image = dataPoint.Image;
                var grayImage = dataPoint.GrayImage;

                ReadOnlySpan<byte> imageData = image.Pixels;
                (int alphaIndex, int redIndex, int greenIndex, int blueIndex) = image.PixelFormat switch
                {
                    MLPixelFormat.Bgra32 => (3, 2, 1, 0),
                    MLPixelFormat.Rgba32 => (3, 0, 1, 2),
                    _ => throw new InvalidOperationException($"Image pixel format is not supported")
                };

                ReadOnlySpan<byte> grayImageData = grayImage.Pixels;
                (int alphaIndex1, int redIndex1, int greenIndex1, int blueIndex1) = grayImage.PixelFormat switch
                {
                    MLPixelFormat.Bgra32 => (3, 2, 1, 0),
                    MLPixelFormat.Rgba32 => (3, 0, 1, 2),
                    _ => throw new InvalidOperationException($"Image pixel format is not supported")
                };

                int pixelSize = image.BitsPerPixel / 8;

                for (int i = 0; i < imageData.Length; i += pixelSize)
                {
                    string pixelString = $"[A = {imageData[i + alphaIndex]}, R = {imageData[i + redIndex]}, G = {imageData[i + greenIndex]}, B = {imageData[i + blueIndex]}]";
                    string grayPixelString = $"[A = {grayImageData[i + alphaIndex1]}, R = {grayImageData[i + redIndex1]}, G = {grayImageData[i + greenIndex1]}, B = {grayImageData[i + blueIndex1]}]";

                    Console.WriteLine($"The original pixel is {pixelString} and its pixel in gray is {grayPixelString}");
                }
            }

            // Expected output:
            //   The original pixel is Color[A = 255, R = 0, G = 0, B = 255] and its pixel in gray is Color[A = 255, R = 28, G = 28, B = 28]
            //   The original pixel is Color[A = 255, R = 0, G = 0, B = 255] and its pixel in gray is Color[A = 255, R = 28, G = 28, B = 28]
            //   The original pixel is Color[A = 255, R = 0, G = 0, B = 255] and its pixel in gray is Color[A = 255, R = 28, G = 28, B = 28]
            //   The original pixel is Color[A = 255, R = 0, G = 0, B = 255] and its pixel in gray is Color[A = 255, R = 28, G = 28, B = 28]
            //   The original pixel is Color[A = 255, R = 0, G = 0, B = 255] and its pixel in gray is Color[A = 255, R = 28, G = 28, B = 28]
            //   The original pixel is Color[A = 255, R = 0, G = 0, B = 255] and its pixel in gray is Color[A = 255, R = 28, G = 28, B = 28]
            //   The original pixel is Color[A = 255, R = 255, G = 0, B = 0] and its pixel in gray is Color[A = 255, R = 77, G = 77, B = 77]
            //   The original pixel is Color[A = 255, R = 255, G = 0, B = 0] and its pixel in gray is Color[A = 255, R = 77, G = 77, B = 77]
            //   The original pixel is Color[A = 255, R = 255, G = 0, B = 0] and its pixel in gray is Color[A = 255, R = 77, G = 77, B = 77]
            //   The original pixel is Color[A = 255, R = 255, G = 0, B = 0] and its pixel in gray is Color[A = 255, R = 77, G = 77, B = 77]
            //   The original pixel is Color[A = 255, R = 255, G = 0, B = 0] and its pixel in gray is Color[A = 255, R = 77, G = 77, B = 77]
            //   The original pixel is Color[A = 255, R = 255, G = 0, B = 0] and its pixel in gray is Color[A = 255, R = 77, G = 77, B = 77]
        }

        private class ImageDataPoint
        {
            [ImageType(3, 4)]
            public MLImage Image { get; set; }

            [ImageType(3, 4)]
            public MLImage GrayImage { get; set; }

            public ImageDataPoint()
            {
                Image = null;
                GrayImage = null;
            }

            public ImageDataPoint(int width, int height, byte red, byte green, byte blue)
            {
                byte[] imageData = new byte[width * height * 4]; // 4 for the red, green, blue and alpha colors
                for (int i = 0; i < imageData.Length; i += 4)
                {
                    // Fill the buffer with the Bgra32 format
                    imageData[i] = blue;
                    imageData[i + 1] = green;
                    imageData[i + 2] = red;
                    imageData[i + 3] = 255;
                }

                Image = MLImage.CreateFromPixels(width, height, MLPixelFormat.Bgra32, imageData);
            }
        }
    }
}

Applies to