Laden...

Custom Vision ONNX Datei in Windows Forms nutzen zum Vorhersagen von Bildklassifizierung

Erstellt von Norman9494 vor einem Jahr Letzter Beitrag vor einem Jahr 521 Views
N
Norman9494 Themenstarter:in
112 Beiträge seit 2010
vor einem Jahr
Custom Vision ONNX Datei in Windows Forms nutzen zum Vorhersagen von Bildklassifizierung

Schönen guten Tag zusammen,

ich bin leider am verzweifeln und hoffe daher hier auf Hilfe.

Vorab: Ich habe mich bereits Stunden oder eher Tage mit dem Thema Bilderkennung/Klassifizierung und Deep/Maschine Learning auseinandergesetzt.

Ich habe mich nun letztendlich für CustomVision entschieden , da ich hier die besten Resultate habe, und auch bereits ein Modell trainiert.
Ich Versuche nun dieses Modell  (offline als Datei) in meine Windows Forms Anwendung zu integrieren.

Hierfür gibt es offensichtlich 2 Möglichkeiten, das Modell als ONNX oder TensorFlow zu exportieren und zu benutzen.

Zur Zeit versuche ich mich mit ONNX. 
Als Basis dafür benutze ich folgendes Snippet: Making Predictions in C# with a Pre-Trained TensorFlow Model via ONNX

Soweit so gut.

Mein Modell input hat folgende Anforderungen:

name: data
type: float32[None,3,224,224]
denotation: Image(Bgr8,SRGB,NominalRange_0_255)
Image(s) in BGR format. It is a [N, C, H, W]-tensor. The 1st/2nd/3rd slices along the C-axis are blue, green, and red channels, respectively.

Ich habe dementsprechend den Code umgeschrieben.

Hier der Ausschnitt:

var probabilities = Predict(modelpath, PreprocessTestImage(imagePath));

Methoden:

private static float[] PreprocessTestImage(string path)
       {
           var img = new Bitmap(path);
           // Resize the image to 224x224
           var resizedImg = new Bitmap(img, new System.Drawing.Size(224, 224));
           // Convert the image to a float array with values normalized to the range 0-1
           var result = new float[1 * 3 * 224 * 224];
           for (int y = 0; y < 224; y++)
           {
               for (int x = 0; x < 224; x++)
               {
                   var pixel = resizedImg.GetPixel(x, y);
                   result[0 * 3 * 224 * 224 + 2 * 224 * 224 + y * 224 + x] = pixel.R / 255f;
                   result[0 * 3 * 224 * 224 + 1 * 224 * 224 + y * 224 + x] = pixel.G / 255f;
                   result[0 * 3 * 224 * 224 + 0 * 224 * 224 + y * 224 + x] = pixel.B / 255f;
               }
           }
           return result;
       }

       private static float[] Predict(string modelPath, float[] image)
       {
           var session = new InferenceSession(modelPath);
           var modelInputLayerName = session.InputMetadata.Keys.Single();
           var inputTensor = new DenseTensor<float>(image, new[] { 1, 3, 224, 224 });
           var modelInput = new List<NamedOnnxValue>
       {
           NamedOnnxValue.CreateFromTensor(modelInputLayerName, inputTensor)
       };
            var result= session.Run(modelInput);
           return ((DenseTensor<float>)result.Single().Value).ToArray();
       }

Meinem Verständnis nach, sollte dies den Anforderungen exakt entsprechen.
Mit diesem Code, lässt sich das Bild übergeben, und ich erhalte auch ein result.

Allerdings bekomme ich hier immer das gleiche falsche Ergebnis geliefert was mich daraus schließen lässt, das ich ein fehlerhaftes Bild übergebe. Ich vermute daher einen Fehler beim Preprocessen des Bildes.

Mit dem falschen Ergebnis meine ich natürlich, dass das Model mir über die Weboberfläche von CustomVision ein anderes (richtiges) Ergebnis liefert.
Die Domäne ist übrigens "General (compact)".

Die ONNX Datei wird daher korrekt sein, und der Fehler in meinem Code liegen.

Vielleicht hat hier ja jemand bereits Erfahrungen sammeln können und mag seinen Senf dazu geben 😉

Ich bedanke mich im Voraus.

Viele Grüße

Norman

N
Norman9494 Themenstarter:in
112 Beiträge seit 2010
vor einem Jahr

anbei noch die metadata properties meines modells:

 "CustomVision.Metadata.AdditionalModelInfo": "",
   "CustomVision.Metadata.Version": "1.2",
   "CustomVision.Postprocess.Method": "ClassificationMultiClass",
   "CustomVision.Postprocess.Yolo.Biases": "[]",
   "CustomVision.Postprocess.Yolo.NmsThreshold": "0.0",
   "CustomVision.Preprocess.CropHeight": "0",
   "CustomVision.Preprocess.CropMethod": "NoCrop",
   "CustomVision.Preprocess.CropWidth": "0",
   "CustomVision.Preprocess.MaxDimension": "0",
   "CustomVision.Preprocess.MaxScale": "0.0",
   "CustomVision.Preprocess.MinDimension": "0",
   "CustomVision.Preprocess.MinScale": "0.0",
   "CustomVision.Preprocess.NormalizeMean": "[0.0, 0.0, 0.0]",
   "CustomVision.Preprocess.NormalizeStd": "[1.0, 1.0, 1.0]",
   "CustomVision.Preprocess.ResizeMethod": "Stretch",
   "CustomVision.Preprocess.TargetHeight": "224",
   "CustomVision.Preprocess.TargetWidth": "224",
   "Image.BitmapPixelFormat": "Rgb8",
   "Image.ColorSpaceGamma": "SRGB",
   "Image.NominalPixelRange": "Normalized_0_1"