Поделиться через


CNTK вычисление преобразований изображений

На этой странице описываются некоторые возможные реализации для преобразования изображений перед их оценкой в модели CNTK, которая была обучена с данными, поступающими с помощью ImageReader. Рабочий пример предоставляется как часть примера программы CSEvalClient , в частности, относится к методу EvaluateImageClassificationModel .

Обзор

Подключаемый модуль ImageReader CNTK позволяет передавать данные изображений в модель CNTK для обучения, тестирования и оценки. ImageReader имеет некоторые настраиваемые возможности, которые при включении выполняют некоторые преобразования во время полета к данным изображения. Ниже перечислены возможные преобразования.

  • Обрезка
  • Изменить размер
  • Применение среднего значения
  • Интенсивность
  • Цвет
  • Макет (HWC и CHW)

Оценка изображений с помощью CNTK.exe и средства чтения изображений

В этом случае преобразования изображений можно указать в файле конфигурации, а Imagereader выполнит определенные преобразования.

Программная оценка образа с помощью EvalDll(EvalWrapper)

В этом случае необходимо выполнить необходимые преобразования изображений программным способом, прежде чем образ передается в Evalwrapper.

В этом разделе приводятся некоторые возможные реализации для выполнения некоторых из этих преобразований до оценки.

Например, статический класс cntkBitmapExtensions может содержать методы расширения, показанные ниже.

Изменить размер

    /// <summary>
    /// Resizes an image
    /// </summary>
    /// <param name="image">The image to resize</param>
    /// <param name="width">New width in pixels</param>
    /// <param name="height">New height in pixesl</param>
    /// <param name="useHighQuality">Resize quality</param>
    /// <returns>The resized image</returns>
    public static Bitmap Resize(this Bitmap image, int width, int height, bool useHighQuality)
    {
        var rect = new Rectangle(0, 0, width, height);
        var newImg = new Bitmap(width, height);

        newImg.SetResolution(image.HorizontalResolution, image.VerticalResolution);

        using (var g = Graphics.FromImage(newImg))
        {
            g.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy;
            if (useHighQuality)
            {
                g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
            }
            else
            {
                g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Default;
                g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.Default;
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.Default;
                g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Default;
            }

            var attributes = new ImageAttributes();
            attributes.SetWrapMode(System.Drawing.Drawing2D.WrapMode.TileFlipXY);
            g.DrawImage(image, rect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, attributes);
        }

        return newImg;
    }

В этом случае возможное вызов может быть следующим:

 var testBitmap = new Bitmap(Bitmap.FromFile(@"C:\rocket.bmp")).Resize(224, 224, true);

Эта команда изменит C:\rocket.bmp размер изображения на 224 x 224 пикселя, поддерживая высокое качество изображения.

Преобразование макета из HWC в CHW

В CNTK используются два типа макета: HWC и CHW. Во-первых, HWC — это формат по умолчанию, используемый в CNTK. Во-вторых, CHW, — это формат, используемый cuDNN в GPU.

Обратите внимание, что фактический макет файламожет отличаться. Мы рассматриваем представление памяти, а не содержимое файла

Обратите внимание, что описанные выше описания относятся к часто используемой нотации с основной строкой , где самое быстрое движущееся измерение приходит в последний раз. CNTK обычно использует нотацию с основным столбцом, которая использует самое быстрое движущееся измерение первым и где ниже будет выражено как "CWH" и "WHC", соответственно.

Это означает, что при условии, что растровое изображение с форматом HWC размером 10 x 10 x 10 с использованием RGB-байтов пространство памяти будет соответствовать следующим требованиям:

Offset (byte) :  0  1  2  3  4  5  6  7  8 ...29 30 31 32 33 34 35 36 37 ...
Height Pos    :  0  0  0  0  0  0  0  0  0 ... 0  0  0  1  1  1  1  1  1 ...
Width Pos     :  0  0  0  1  1  1  2  2  2 ... 9  9  9  0  0  0  1  1  1 ...
Color Index   :  B  G  R  B  G  R  B  G  R ... B  G  R  B  G  R  B  G  R ...

В случае с chW макет будет следующим:

Offset (byte) :  0  1  2  3 ... 9 10 11 12 13 ...90 91 92 93 ... 99 100 ... 199 200 ... 299 
Color Index   :  B  B  B  B ... B  B  B  B  B ... B  B  B  B ...  B   G ...   G   R ...   R
Height Pos    :  0  0  0  0 ... 0  0  0  0  0 ... 9  9  9  9 ...  9   0 ...   9   0 ...   9
Width Pos     :  0  1  2  3 ... 9  0  1  2  3 ... 0  1  2  3 ...  9   0 ...   9   0 ...   9

Возможный метод расширения, извлекающий Bitmapданные изображения в макет CHW, может быть следующим:

    /// <summary>
    /// Extracts image pixels in CHW
    /// </summary>
    /// <param name="image">The bitmap image to extract features from</param>
    /// <returns>A list of pixels in HWC order</returns>
    public static List<float> ExtractCHW(this Bitmap image)
    {
        var features = new List<float>(image.Width * image.Height * 3);
        for (int c = 0; c < 3; c++)
        {
            for (int h = 0; h < image.Height; h++)
            {
                for (int w = 0; w < image.Width; w++)
                {
                    var pixel = image.GetPixel(w, h);
                    float v = c == 0 ? pixel.B : c == 1 ? pixel.G : pixel.R;

                    features.Add(v);
                }
            }
        }

        return features;
    }

Этот Bitmap.GetPixel метод заботится о некоторых нюансах макета памяти, что позволяет сосредоточиться на самом преобразовании.

Этот метод теперь можно использовать в преобразовании изображений перед вычислением. Предположим, что то же растровое изображение, что и в режиме изменения размера, мы можем извлечь свои данные в макете CHW со следующим вызовом:

var features = testBitmap.ExtractCHW();

Теперь вектор features можно использовать в качестве входных данных слоя в модель классификации изображений. Рабочий пример предоставляется как часть CSEvalClient примера программы, в частности, относится к методу EvaluateImageClassificationModel .