Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Na tej stronie opisano niektóre możliwe implementacje przekształcania obrazów przed ich oceną w modelu CNTK, który został wytrenowany przy użyciu danych karmionych przy użyciu elementu ImageReader. Przykład roboczy jest dostarczany jako część przykładowego programu CSEvalClient , w szczególności odnosi się do EvaluateImageClassificationModel metody .
Omówienie
Wtyczka CNTK ImageReader umożliwia przekazywanie danych obrazu do modelu CNTK na potrzeby trenowania, testowania i oceny. Element ImageReader ma pewne konfigurowalne możliwości, które po włączeniu można wykonać pewne przekształcenia na bieżąco w danych obrazu. Te możliwe przekształcenia to:
- Przycinania
- Zmiana rozmiaru
- Stosowanie średniej
- Intensywność
- Kolor
- Układ (HWC vs CHW)
Ocena obrazu za pomocą CNTK.exe i czytnika obrazów
W takim przypadku przekształcenia obrazu można określić w pliku konfiguracji, a element Imagereader wykona zdefiniowane przekształcenia.
Programowa ocena obrazu za pośrednictwem EvalDll(EvalWrapper)
W takim przypadku wymagane przekształcenia obrazu należy wykonać programowo przed przekazaniem obrazu do programu Evalwrapper.
Ta sekcja zawiera pewne możliwe implementacje do wykonywania niektórych z tych przekształceń przed oceną.
Na przykład klasa statyczna o nazwie CntkBitmapExtensions może zawierać metody rozszerzenia pokazane poniżej.
Zmiana rozmiaru
/// <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;
}
W takim przypadku możliwe wywołanie może być następujące:
var testBitmap = new Bitmap(Bitmap.FromFile(@"C:\rocket.bmp")).Resize(224, 224, true);
To polecenie spowoduje zmianę rozmiaru C:\rocket.bmp obrazu na rozmiar 224 x 224 pikseli zachowujący wysoką jakość obrazu.
Konwersja układu z HWC na CHW
Istnieją przede wszystkim dwa typy układów używane w CNTK: HWC i CHW. Pierwszy, HWC jest domyślnym formatem używanym w CNTK. Drugi, CHW, jest format używany przez cuDNN w procesorze GPU.
Należy pamiętać, że rzeczywisty układ pliku może być inny. Patrzymy na reprezentację pamięci, a nie zawartość pliku
Należy pamiętać, że powyższe opisy odnoszą się do często używanej notacji głównej wierszy , w której ostatni jest najszybszy wymiar ruchomy. CNTK zwykle używa notacji głównej kolumny, która używa najpierw najszybszego wymiaru ruchomego i gdzie poniżej zostaną wyrażone odpowiednio jako "CWH" i "WHC".
Oznacza to, że przy założeniu, że mapa bitowa o formacie HWC o rozmiarze 10 x 10 x 10 przy użyciu bajtów RGB, przestrzeń pamięci odpowiadałaby:
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 ...
W przypadku CHW układ będzie:
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żliwą metodą rozszerzenia wyodrębniającą Bitmapdane obrazu do układu CHW może być:
/// <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 zajmuje się niektórymi niuansami układu pamięci, co pozwala skupić się na samym przekształceniu.
Tej metody można teraz użyć w transformacji obrazu przed oceną. Zakładając, że ta sama mapa bitowa co w obszarze Zmiana rozmiaru, możemy wyodrębnić jej dane w układzie CHW z następującym wywołaniem:
var features = testBitmap.ExtractCHW();
Wektor features może być teraz używany jako dane wejściowe warstwy w modelu klasyfikacji obrazów. Przykład roboczy jest dostarczany w ramach przykładowego CSEvalClient programu, w szczególności odnosi się do EvaluateImageClassificationModel metody .