Skip to content

Commit 2f0c263

Browse files
authored
feat: new example (#39)
1 parent 620cdbd commit 2f0c263

File tree

2 files changed

+137
-0
lines changed

2 files changed

+137
-0
lines changed

examples/emotions/README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
## Emotion fer+
2+
3+
This is an example of onnx go being able to run the emotion fer+ model
4+
5+
### Howto
6+
7+
- Download an extract the model from [the zoo](https://github.com/onnx/models/tree/master/emotion_ferplus)
8+
- take a picture of a face: the picture should be 64X64 in gray mode and in png.
9+
- run `go run main.go -model /path/to/model.onnx -input mypic.png`
10+
11+
12+
13+

examples/emotions/main.go

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
package main
2+
3+
import (
4+
"flag"
5+
"fmt"
6+
"image"
7+
"image/png"
8+
"io/ioutil"
9+
"log"
10+
"os"
11+
"sort"
12+
13+
"github.com/owulveryck/onnx-go"
14+
"github.com/owulveryck/onnx-go/backend/x/gorgonnx"
15+
"github.com/owulveryck/onnx-go/internal/x/images"
16+
"gorgonia.org/tensor"
17+
)
18+
19+
const (
20+
height = 64
21+
width = 64
22+
)
23+
24+
var emotionTable = []string{
25+
"neutral",
26+
"happiness",
27+
"surprise",
28+
"sadness",
29+
"anger",
30+
"disgust",
31+
"fear",
32+
"contempt",
33+
}
34+
35+
func main() {
36+
model := flag.String("model", "model.onnx", "path to the model file")
37+
input := flag.String("input", "file.png", "path to the input file")
38+
h := flag.Bool("h", false, "help")
39+
flag.Parse()
40+
if *h {
41+
flag.Usage()
42+
os.Exit(0)
43+
}
44+
for _, f := range []string{*model, *input} {
45+
if _, err := os.Stat(f); err != nil && os.IsNotExist(err) {
46+
log.Fatalf("%v does not exist", f)
47+
}
48+
}
49+
// Create a backend receiver
50+
backend := gorgonnx.NewGraph()
51+
// Create a model and set the execution backend
52+
m := onnx.NewModel(backend)
53+
54+
// read the onnx model
55+
b, err := ioutil.ReadFile(*model)
56+
if err != nil {
57+
log.Fatal(err)
58+
}
59+
// Decode it into the model
60+
err = m.UnmarshalBinary(b)
61+
if err != nil {
62+
log.Fatal(err)
63+
}
64+
// Set the first input, the number depends of the model
65+
// TODO
66+
inputFile, err := os.Open(*input)
67+
if err != nil {
68+
log.Fatal(err)
69+
}
70+
defer inputFile.Close()
71+
img, err := png.Decode(inputFile)
72+
if err != nil {
73+
log.Fatal(err)
74+
}
75+
imgGray, ok := img.(*image.Gray)
76+
if !ok {
77+
log.Fatal("Please give a gray image as input")
78+
}
79+
inputT := tensor.New(tensor.WithShape(1, 1, height, width), tensor.Of(tensor.Float32))
80+
err = images.GrayToBCHW(imgGray, inputT)
81+
if err != nil {
82+
log.Fatal(err)
83+
}
84+
m.SetInput(0, inputT)
85+
err = backend.Run()
86+
if err != nil {
87+
log.Fatal(err)
88+
}
89+
computedOutputT, err := m.GetOutputTensors()
90+
if err != nil {
91+
log.Fatal(err)
92+
}
93+
result := classify(computedOutputT[0].Data().([]float32))
94+
fmt.Println(result[0].emotion)
95+
fmt.Println(result[1].emotion)
96+
}
97+
98+
type testingT struct{}
99+
100+
func (t *testingT) Errorf(format string, args ...interface{}) {
101+
log.Fatalf(format, args...)
102+
}
103+
104+
func classify(input []float32) emotions {
105+
result := make(emotions, len(input))
106+
for i := 0; i < len(input); i++ {
107+
result[i] = emotion{
108+
emotion: emotionTable[i],
109+
weight: input[i],
110+
}
111+
}
112+
sort.Sort(sort.Reverse(result))
113+
return result
114+
}
115+
116+
type emotions []emotion
117+
type emotion struct {
118+
emotion string
119+
weight float32
120+
}
121+
122+
func (e emotions) Len() int { return len(e) }
123+
func (e emotions) Swap(i, j int) { e[i], e[j] = e[j], e[i] }
124+
func (e emotions) Less(i, j int) bool { return e[i].weight < e[j].weight }

0 commit comments

Comments
 (0)