I m trying to load an image classification model made with pytorch into a c# aplication. In order to acomplish this task i use an async task, but when i run the program it throws me a null reference exception because it seams it doesn't load the model.
using System;
using System.Threading.Tasks;
using Windows.AI.MachineLearning;
using Windows.Graphics.Imaging;
using Windows.Media;
using Windows.Storage;
using Windows.Storage.Pickers;
using Windows.Storage.Streams;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Imaging;
// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
namespace AI_Test1
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
// All the required fields declaration
private Model modelGen;
private Input image = new Input();
private Output results;
private StorageFile selectedStorageFile;
private string label = "";
private float probability = 0;
private Helper helper = new Helper();
public enum Labels
{
Has_Lighter,
Has_No_Lighter,
}
public MainPage()
{
this.InitializeComponent();
_ = loadModel();
}
private async Task loadModel()
{
// Get an access the ONNX model and save it in memory.
StorageFile modelFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri($"ms-appx:///Assets/LTM-Classic_Model.onnx"));
// Instantiate the model.
modelGen = await Model.CreateFromStreamAsync(modelFile);
}
private async void OpenFileButton_Click(object sender, RoutedEventArgs e)
{
if (!await getImage())
{
return;
}
// After the click event happened and an input selected, begin the model execution.
// Bind the model input
await imageBind();
// Model evaluation
await evaluate();
// Extract the results
ExtractResult();
// Display the results
displayResult();
}
private async Task<bool> getImage()
{
try
{
// Trigger file picker to select an image file
FileOpenPicker fileOpenPicker = new FileOpenPicker();
fileOpenPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
fileOpenPicker.FileTypeFilter.Add(".jpg");
fileOpenPicker.FileTypeFilter.Add(".png");
fileOpenPicker.ViewMode = PickerViewMode.Thumbnail;
selectedStorageFile = await fileOpenPicker.PickSingleFileAsync();
if (selectedStorageFile == null)
{
return false;
}
}
catch (Exception)
{
return false;
}
return true;
}
private async Task imageBind()
{
UIPreviewImage.Source = null;
try
{
SoftwareBitmap softwareBitmap;
using (IRandomAccessStream stream = await selectedStorageFile.OpenAsync(FileAccessMode.Read))
{
// Create the decoder from the stream
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream);
// Get the SoftwareBitmap representation of the file in BGRA8 format
softwareBitmap = await decoder.GetSoftwareBitmapAsync();
softwareBitmap = SoftwareBitmap.Convert(softwareBitmap, BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied);
}
// Display the image
SoftwareBitmapSource imageSource = new SoftwareBitmapSource();
await imageSource.SetBitmapAsync(softwareBitmap);
UIPreviewImage.Source = imageSource;
// Encapsulate the image within a VideoFrame to be bound and evaluated
VideoFrame inputImage = VideoFrame.CreateWithSoftwareBitmap(softwareBitmap);
// Resize the image size to 32x32
inputImage = await helper.CropAndDisplayInputImageAsync(inputImage);
// Bind the model input with image
ImageFeatureValue imageTensor = ImageFeatureValue.CreateFromVideoFrame(inputImage);
image.input = imageTensor;
// Encapsulate the image within a VideoFrame to be bound and evaluated
//VideoFrame inputImage = VideoFrame.CreateWithSoftwareBitmap(softwareBitmap);
// bind the input image
//ImageFeatureValue imageTensor = ImageFeatureValue.CreateFromVideoFrame(inputImage);
//image.modelInput = imageTensor;
}
catch (Exception )
{
}
}
private void ExtractResult()
{
// Retrieve the results of evaluation
var mResult = results.output as TensorFloat;
// convert the result to vector format
var resultVector = mResult.GetAsVectorView();
probability = 0;
int index = 0;
// find the maximum probability
for (int i = 0; i < resultVector.Count; i++)
{
var elementProbability = resultVector[i];
if (elementProbability > probability)
{
index = i;
}
}
label = ((Labels)index).ToString();
}
private void displayResult()
{
displayOutput.Text = label;
}
private async Task evaluate()
{
results = await modelGen.EvaluateAsync(image);
}
}
}
According to what I could understand from your code, the modelGen
is not initialized before you have called the evaluate()
method. Apparantly, you have created a method loadModel()
for this purpose, so I am guessing that you need to call the loadmodel()
before you call evaluate()
.
So edit this portion of the code
private async void OpenFileButton_Click(object sender, RoutedEventArgs e)
{
if (!await getImage())
{
return;
}
// After the click event happened and an input selected, begin the model execution.
// Bind the model input
await imageBind();
await loadModel(); // EDITED: Load Model here
// Model evaluation
await evaluate();
// Extract the results
ExtractResult();
// Display the results
displayResult();
}