Image Classification
unity-sentis
ONNX
File size: 2,952 Bytes
c0392be
 
 
 
a92657c
 
 
 
 
 
 
 
 
 
 
 
 
 
c0392be
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
using System.Collections.Generic;
using Unity.Sentis;
using UnityEngine;

/*
 *  MovileNetV2 Inference Script
 *  ============================
 *  
 *  Place this script on the Main Camera
 *  
 *  Drag an image to the inputImage field
 *  
 *  When run the prediction of what the image is will output to the console window.
 *  You can modify the script to make it do something more interesting.
 * 
 */


public class RunMobileNet : MonoBehaviour
{
    const string modelName = "mobilenet_v2.sentis";

    //The image to classify here:
    public Texture2D inputImage;

    //Link class_desc.txt here:
    public TextAsset labelsAsset;

    //All images are resized to these values:
    const int imageHeight = 224;
    const int imageWidth = 224;

    const BackendType backend = BackendType.GPUCompute;
    private Model model;
    private IWorker engine;
    private string[] labels;

    static Ops ops;
    ITensorAllocator allocator;

    void Start()
    {
        //These are used for tensor operations
        allocator = new TensorCachingAllocator();
        ops = WorkerFactory.CreateOps(backend, allocator);

        //Parse neural net labels
        labels = labelsAsset.text.Split('\n');

        //Load model
        model = ModelLoader.Load(Application.streamingAssetsPath + "/" + modelName);

        //Setup the engine to run the model
        engine = WorkerFactory.CreateWorker(backend, model);

        //Execute inference
        ExecuteML();
    }

    public void ExecuteML()
    {
        //Preprocess image for input
        using var rawinput = TextureConverter.ToTensor(inputImage, 224, 224, 3);
        using var input = Normalise(rawinput);
        
        //Execute neural net
        engine.Execute(input);

        //Read output tensor
        var output = engine.PeekOutput() as TensorFloat;
        var argmax = ops.ArgMax(output, 1, false);
        argmax.MakeReadable();

        //Select the best output class and print the results
        var res = argmax[0];
        var label = labels[res];

        output.MakeReadable();
        var accuracy = output[res];

        //The result is output to the console window
        int percent = Mathf.FloorToInt(accuracy * 100f + 0.5f);
        Debug.Log($"{label} {percent}﹪");

        //Clean memory
        Resources.UnloadUnusedAssets();
    }

    //This scales and shifts the RGB values for input into the model
    TensorFloat Normalise(TensorFloat image)
    {
        using var M = new TensorFloat(new TensorShape(1, 3, 1, 1), new float[]
        {
           1/0.229f, 1/0.224f, 1/0.225f
        });
        using var P = new TensorFloat(new TensorShape(1, 3, 1, 1), new float[]
        {
            0.485f, 0.456f, 0.406f
        });
        using var image2 = ops.Sub(image, P);
        return ops.Mul(image2, M);
    }
    
    private void OnDestroy()
    {
        engine?.Dispose();
        ops?.Dispose();
        allocator?.Dispose();
    }
}