Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Megtudhatja, hogyan használhatja a ML.NET a képek objektumainak észlelésére a Microsoft Custom Vision szolgáltatásban betanított ONNX-modellel.
A Microsoft Custom Vision szolgáltatás egy AI-szolgáltatás, amely a feltöltött képek alapján tanít be egy modellt. Ezután exportálhatja a modellt ONNX formátumba, és a ML.NET használatával előrejelzéseket készíthet.
Ebben az oktatóanyagban a következőket sajátíthatja el:
- ONNX-modell létrehozása a Custom Vision szolgáltatással
- Az ONNX-modell beépítése a ML.NET folyamatba
- A ML.NET modell betanítása
- Stop-jelek észlelése tesztképekben
Előfeltételek
- Visual Studio 2022 vagy újabb verzió.
- 50 megállótábla képekből álló adathalmaz letöltése.
- Azure-fiók. Ha nem rendelkezik ilyen fiókkal, hozzon létre egy ingyenes Azure-fiókot.
A modell létrehozása
A Custom Vision-projekt létrehozása
Jelentkezzen be a Microsoft Custom Vision szolgáltatásba, és válassza Új projektlehetőséget.
Az Új projekt párbeszédpanelen töltse ki a következő kötelező elemeket:
- Állítsa be a Custom Vision-projekt neveStopSignDetection.
- Válassza ki a -es erőforrást, amelyet használni fog. Ez egy Azure-erőforrás, amely a Custom Vision-projekthez lesz létrehozva. Ha egyik sem szerepel a listában, létrehozhat egyet az Új létrehozása hivatkozás kiválasztásával.
- Állítsa be a projekttípust objektumészlelésként .
- Állítsa be a besorolási típusokattöbbosztályos, mivel képenként egy osztály lesz.
- Állítsa be a(z) tartományt a Általános (kompakt) [S1]beállításra. A kompakt tartomány lehetővé teszi az ONNX-modell letöltését.
- Az Exportálási képességekaz ONNX-modell exportálásának engedélyezéséhez válassza Alapszintű platformok lehetőséget.
A fenti mezők kitöltése után válassza a Projekt létrehozásalehetőséget.
Képek hozzáadása
- A projekt létrehozása után válassza a Képek hozzáadása opciót, hogy elkezdje hozzáadni a model betanításához szükséges képeket. Válassza ki a letöltött stop-sign képeket.
- Válassza ki az első megjelenített képet. A képen kijelölheti azokat az objektumokat, amelyeket a modell észlelni szeretne. Válassza ki a stop táblát a képen. Egy felugró ablak megjeleníti és beállítja a címkét stop-sign.
- Ismételje meg az összes többi képnél. Egyes képek több stopjelet is tartalmaznak, ezért mindenképpen jelöljön meg mindent, ami a képeken található.
A modell betanítása
A feltöltött és címkézett képek után a modell betanítása is elvégezhető. Válassza Vonatot.
Megjelenik egy előugró ablak, amely megkérdezi, hogy milyen típusú betanítást használjon. Válassza a Gyors betanítás, majd a Betanításlehetőséget.
Az ONNX-modell letöltése
A betanítás befejezése után kattintson az Exportálás gombra. Amikor megjelenik az előugró ablak, válassza ONNX az ONNX-modell letöltéséhez.
ONNX-modell vizsgálata
Bontsa ki a letöltött ONNX-fájlt. A mappa több fájlt tartalmaz, de az oktatóanyagban használt kettő a következő:
- labels.txt, amely a Custom Vision szolgáltatásban definiált címkéket tartalmazó szövegfájl.
- model.onnx, amely az ONNX-modell, amellyel előrejelzéseket készíthet ML.NET.
A ML.NET folyamat létrehozásához szüksége lesz a bemeneti és kimeneti oszlopnevek nevére. Az információk beszerzéséhez használja a Netront, egy webes és asztali alkalmazást, amely képes elemezni az ONNX-modelleket, és bemutatni azok architektúráját.
Ha a Netron webes vagy asztali alkalmazását használja, nyissa meg az ONNX-modellt az alkalmazásban. Miután megnyílik, megjelenik egy gráf. Ez a gráf elárul néhány dolgot, amelyekre szüksége lesz az előrejelzésekhez az ML.NET adatfolyam létrehozásához.
Bemeneti oszlop neve – Az ONNX-modell ML.NET való alkalmazásakor szükséges bemeneti oszlopnév.
Kimeneti oszlop neve – Az ONNX-modell ML.NET való alkalmazásakor szükséges kimeneti oszlopnév.
képméret – A képek átméretezéséhez szükséges méret a ML.NET folyamatban.
C#-konzolprojekt létrehozása
A Visual Studióban hozzon létre egy "StopSignDetection" nevű C#-konzolalkalmazást. Válassza a .NET 8-at cél-keretrendszerként.
Telepítse a következő NuGet-csomagokat a projekthez:
- Microsoft.ML
- Microsoft.ML.ImageAnalytics
- Microsoft.Onnx.Transformer
Jegyzet
Ez a minta az említett NuGet-csomagok legújabb stabil verzióját használja, hacsak másként nem rendelkezik.
Referencia az ONNX-modellre
Keresse meg az ONNX-modell két fájlját (labels.txt és model.onnx) a Visual Studio Solution Explorer. Kattintson rájuk a jobb gombbal, és a Tulajdonságok ablakban állítsa be a Másolás kimeneti könyvtárbaMásolás, ha újabb.
Bemeneti és előrejelzési osztályok létrehozása
Adjon hozzá egy új osztályt a projekthez, és nevezze el
StopSignInput. Ezután adja hozzá a következő strukturát az osztályhoz:public struct ImageSettings { public const int imageHeight = 320; public const int imageWidth = 320; }Ezután adja hozzá a következő tulajdonságot az osztályhoz.
public class StopSignInput { [ImageType(ImageSettings.imageHeight, ImageSettings.imageWidth)] public Bitmap Image { get; set; } }A
Imagetulajdonság az előrejelzéshez használt kép bitképét tartalmazza. AzImageTypeattribútum azt jelzi az ML.NET számára, hogy a tulajdonság egy 320 x 320 méretű kép, amit a Netron segítségével állapítottak meg.Adjon hozzá egy másik osztályt a projekthez, és nevezze el
StopSignPrediction. Ezután adja hozzá a következő tulajdonságokat az osztályhoz.public class StopSignPrediction { [ColumnName("detected_classes")] public long[] PredictedLabels { get; set; } [ColumnName("detected_boxes")] public float[] BoundingBoxes { get; set; } [ColumnName("detected_scores")] public float[] Scores { get; set; } }A
PredictedLabelstulajdonság az egyes észlelt objektumok címkéinek előrejelzéseit tartalmazza. A típus egy lebegőpontos tömb, így a tömb minden eleme az egyes címkék előrejelzése. AColumnNameattribútum azt jelzi, hogy az ML.NET modell ezen oszlopának a neve, amelyet megadtak,detected_classes.Minden észlelt objektumhoz a
BoundingBoxestulajdonság tartalmazza a határoló kereteket. A típus egy lebegőpontos tömb, és minden észlelt objektum négy elemmel érkezik a tömbben a határoló dobozhoz. AColumnNameattribútum azt jelzi, hogy az ML.NET modell ezen oszlopának a neve, amelyet megadtak,detected_boxes.A
Scorestulajdonság az egyes előrejelzett objektumok megbízhatósági pontszámait és címkéjét tartalmazza. A típus egy lebegőpontos tömb, így a tömb minden eleme az egyes címkék megbízhatósági pontszáma. AColumnNameattribútum azt jelzi, hogy az ML.NET modell ezen oszlopának a neve, amelyet megadtak,detected_scores.
Előrejelzések készítése a modell használatával
Használati direktívák hozzáadása
A Program.cs fájlban adja hozzá a következő using irányelveket a fájl elejéhez.
using Microsoft.ML;
using Microsoft.ML.Transforms.Image;
using System.Drawing;
using WeatherRecognition;
Objektumok létrehozása
Hozza létre a
MLContextobjektumot.var context = new MLContext();Hozzon létre egy
IDataView-at egy új üresStopSignInputlista segítségével.var data = context.Data.LoadFromEnumerable(new List<StopSignInput>());A konzisztencia érdekében mentse az előrejelzett képeket az összeállítás útvonalára.
var root = new FileInfo(typeof(Program).Assembly.Location); var assemblyFolderPath = root.Directory.FullName;
A csővezeték kiépítése
Az üres IDataView létrehozásával a pipeline felépíthető, hogy bármilyen új kép előrejelzéséhez használható legyen. A folyamat több lépésből áll:
Méretezze át a bejövő képeket.
Az előrejelzés céljából a modellnek küldött kép gyakran eltérő méretarányban jelenik meg a modellen betanított képekhez viszonyítva. Ha a kép egységes marad a pontos előrejelzésekhez, méretezze át a képet 320x320-ra. Ehhez használja a
ResizeImagesmetódust, és állítsa be aimageColumnNameaStopSignInput.Imagetulajdonság neveként.var pipeline = context.Transforms.ResizeImages(resizing: ImageResizingEstimator.ResizingKind.Fill, outputColumnName: "image_tensor", imageWidth: ImageSettings.imageWidth, imageHeight: ImageSettings.imageHeight, inputColumnName: nameof(StopSignInput.Image))Bontsa ki a kép képpontjait.
A kép átméretezése után ki kell nyernie a kép képpontjait. Fűzze hozzá a
ExtractPixelsmetódust a folyamathoz, és adja meg annak az oszlopnak a nevét, amely a képpontokat aoutputColumnNameparaméter használatával adja meg..Append(context.Transforms.ExtractPixels(outputColumnName: "image_tensor"))Az ONNX-modell alkalmazása a képre előrejelzés készítéséhez. Ez néhány paramétert vesz igénybe:
- modelFile – Az ONNX-modellfájl elérési útja
- outputColumnNames – Az összes kimeneti oszlop nevének nevét tartalmazó karakterlánctömb, amely a Netronban található ONNX-modell elemzésekor található.
- inputColumnNames – Az összes bemeneti oszlop nevének nevét tartalmazó karakterlánctömb, amely a NetronBAN található ONNX-modell elemzésekor is megtalálható.
.Append(context.Transforms.ApplyOnnxModel(outputColumnNames: new string[] { "detected_boxes", "detected_scores", "detected_classes" }, inputColumnNames: new string[] { "image_tensor" }, modelFile: "./Model/model.onnx"));
A modell igazítása
Most, hogy definiált egy folyamatot, használhatja a ML.NET modell létrehozásához. Használja a Fit metódust a pipeline-on, és adja át az üres IDataView-et.
var model = pipeline.Fit(data);
Az előrejelzések készítéséhez használja a modellt egy előrejelzési motor létrehozásához. Ez egy általános módszer, ezért a korábban létrehozott StopSignInput és StopSignPrediction osztályokat veszi igénybe.
var predictionEngine = context.Model.CreatePredictionEngine<StopSignInput, StopSignPrediction>(model);
A címkék kinyerése
Ahhoz, hogy a modell kimeneteit a címkéihez rendelje, ki kell nyernie a Custom Vision által biztosított címkéket. Ezek a címkék az ONNX-modell zip-fájljában található labels.txt fájlban találhatók.
Hívja meg a ReadAllLines metódust a fájl összes címkéjének olvasásához.
var labels = File.ReadAllLines("./model/labels.txt");
Előrejelzés tesztképen
Most már használhatja a modellt az új képek előrejelzésére. A projektben van egy teszt mappa, amellyel előrejelzéseket készíthet. Ez a mappa két véletlenszerű képet tartalmaz egy stop táblával az Unsplash-ről . Az egyik kép egy leállításjellel, a másik pedig két stopjellel rendelkezik. A GetFiles metódus használatával olvassa el a könyvtárban lévő képek fájlútvonalait.
var testFiles = Directory.GetFiles("./test");
Futtasd végig a fájl elérési útjait, hogy a modellel előrejelzést készíts, és jelenítsd meg az eredményt.
Hozzon létre egy
foreachhurkot a tesztképeken való végigiteráláshoz.Bitmap testImage; foreach (var image in testFiles) { }A
foreachciklusban hozza létre a várható kép nevét az eredeti tesztkép neve alapján.var predictedImage = $"{Path.GetFileName(image)}-predicted.jpg";A
foreachhurokban hozzon létre egyFileStream-et a képből, és konvertálja egyBitmap-vé.using (var stream = new FileStream(image, FileMode.Open)) { testImage = (Bitmap)Image.FromStream(stream); }A
foreachhurokban is hívja meg aPredictmetódust az előrejelzési motoron.var prediction = predictionEngine.Predict(new StopSignInput { Image = testImage });Előrejelzéssel megkaphatja a határolókereteket. A Chunk metódus használatával meghatározhatja, hogy a modell hány objektumot észlelt. Ezt úgy teheti meg, hogy figyelembe veszi az előrejelzett határolókeretek számát, és elosztja azt az előrejelzett címkék számával. Ha például három objektumot észlelt egy képen, akkor a
BoundingBoxestömbben 12 elem és három címke van előre jelezve. AChunkmetódus ezután három négy tömböt adna az egyes objektumokhoz tartozó határolókeretek megjelenítéséhez.var boundingBoxes = prediction.BoundingBoxes.Chunk(prediction.BoundingBoxes.Count() / prediction.PredictedLabels.Count());Ezután rögzítse az előrejelzéshez használt képek eredeti szélességét és magasságát.
var originalWidth = testImage.Width; var originalHeight = testImage.Height;Számítsa ki, hogy a képen hol rajzolja meg a mezőket. Ehhez hozzon létre egy
forhurkot a határolókeretek száma alapján.for (int i = 0; i < boundingBoxes.Count(); i++) { }A
forhurokban számítsa ki az x és y koordináták pozícióját, valamint a doboz szélességét és magasságát a kép rajzolásához. Az első teendő a határolókeretek készletének lekérése aElementAtmetódus használatával.var boundingBox = boundingBoxes.ElementAt(i);Az aktuális határolókerettel mostantól kiszámíthatja, hogy hová kell rajzolni a dobozt. Használja a határolókeret első és harmadik elemének eredeti képszélességét, a második és negyedik elem eredeti képmagasságát.
var left = boundingBox[0] * originalWidth; var top = boundingBox[1] * originalHeight; var right = boundingBox[2] * originalWidth; var bottom = boundingBox[3] * originalHeight;Számítsa ki a doboz szélességét és magasságát, hogy a képen belül az észlelt objektum körül rajzoljon. Az x és y elemek az előző számítás
leftéstopváltozói. AMath.Absmetódus használatával lekérheti az abszolút értéket a szélesség- és magasságszámításból, ha az negatív.var x = left; var y = top; var width = Math.Abs(right - left); var height = Math.Abs(top - bottom);Ezután szerezze meg az előrejelzett címkét a címkék tömbjéből.
var label = labels[prediction.PredictedLabels[i]];Hozzon létre egy ábrát a tesztkép alapján a
Graphics.FromImagemetódus használatával.using var graphics = Graphics.FromImage(testImage);Rajzoljon a képre a megadott határolókeret használatával. Először rajzolja meg a téglalapot az észlelt objektumok köré azzal a
DrawRectanglemetódussal, amely egyPenobjektumban határozza meg a téglalap színét és szélességét, majd adja meg ax,y,widthésheightváltozókat.graphics.DrawRectangle(new Pen(Color.NavajoWhite, 8), x, y, width, height);Ezután jelenítse meg az előrejelzett címkét a mezőben a
DrawStringmetódussal, amely beolvassa a kinyomtatandó sztringet, és egyFontobjektummal meghatározza, hogyan rajzolja meg a sztringet, és hová helyezze el.graphics.DrawString(label, new Font(FontFamily.Families[0], 18f), Brushes.NavajoWhite, x + 5, y + 5);A
forciklus után ellenőrizze, hogy az előrejelzett fájl már létezik-e. Ha igen, törölje. Ezután mentse a megadott kimeneti elérési útra.if (File.Exists(predictedImage)) { File.Delete(predictedImage); } testImage.Save(Path.Combine(assemblyFolderPath, predictedImage));
Következő lépések
Próbálkozzon a többi képbesorolási oktatóanyag egyikével: