Sdílet prostřednictvím


CNTK vyhodnocení transformací obrázků

Tato stránka popisuje některé možné implementace pro transformaci obrázků před jejich vyhodnocením na CNTK modelu, který byl natrénován daty načítanými pomocí ImageReader. Pracovní příklad je poskytován jako součást ukázkového programu CSEvalClient , zejména odkaz na metodu EvaluateImageClassificationModel .

Přehled

Modul plug-in CNTK ImageReader umožňuje podávání dat obrázků do modelu CNTK pro trénování, testování a vyhodnocení. ImageReader má některé konfigurovatelné funkce, které při povolení provádějí některé místní transformace na data obrázku. Mezi možné transformace patří:

  • Oříznutí
  • Změna velikosti
  • Použití střední hodnoty
  • Intenzita
  • Barva
  • Rozložení (HWC vs. CHW)

Vyhodnocení obrázků pomocí CNTK.exe a čtečky obrázků

V tomto případě lze transformace obrázků zadat v konfiguračním souboru a Imagereader provede definované transformace.

Vyhodnocení programového obrázku prostřednictvím EvalDll(EvalWrapper)

V takovém případě musí být požadované transformace obrázků provedeny programově před předáním image do nástroje Evalwrapper.

Tato část obsahuje některé možné implementace pro provedení některých z těchto transformací před vyhodnocením.

Například statická třída s názvem CntkBitmapExtensions může obsahovat metody rozšíření uvedené níže.

Změna velikosti

    /// <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;
    }

V tomto případě může být možné vyvolání:

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

Tento příkaz změní velikost obrázku C:\rocket.bmp na velikost 224 × 224 pixelů a zachová tak vysoce kvalitní obrázek.

Převod rozložení z HWC na CHW

V CNTK se používají především dva typy rozložení: HWC a CHW. První, HWC je výchozí formát použitý v CNTK. Druhý, CHW, je formát používaný cuDNN v GPU.

Všimněte si, že skutečné rozložení souboruse může lišit. Díváme se na reprezentaci paměti, ne na obsah souboru.

Všimněte si, že výše uvedené popisy odkazují na běžně používaný zápis hlavního řádku , kde je poslední nejrychlejší pohyblivý rozměr. CNTK obvykle používá zápis hlavního sloupce, který jako první používá nejrychlejší pohyblivý rozměr a kde by se níže vyjádřil jako "CWH" a "WHC".

To znamená, že za předpokladu, že rastrový obrázek s formátem HWC o velikosti 10x10 pomocí bajtů RGB by místo v paměti odpovídalo:

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 ...

V případě CHW by rozložení bylo:

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

Možná metoda rozšíření extrahující data obrázku Bitmapdo rozložení CHW může být:

    /// <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;
    }

Metoda Bitmap.GetPixel se stará o některé drobné odlišnosti rozložení paměti, což nám umožňuje zaměřit se na samotnou transformaci.

Tuto metodu teď můžete použít v naší transformaci obrázků před vyhodnocením. Za předpokladu, že stejný rastrový obrázek jako při změně velikosti, můžeme extrahovat jeho data v rozložení CHW s následujícím vyvoláním:

var features = testBitmap.ExtractCHW();

Vektor features se teď dá použít jako vstup vrstvy do modelu klasifikace obrázků. Pracovní příklad je poskytován jako součást ukázkového CSEvalClient programu, zejména odkaz na metodu EvaluateImageClassificationModel .