-
Notifications
You must be signed in to change notification settings - Fork 0
/
pipe.go
128 lines (108 loc) · 2.32 KB
/
pipe.go
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package cvpipe
import (
"fmt"
"image"
"gocv.io/x/gocv"
)
type PipeOptions struct {
// Enable saving of intermediate results. Will be overridden by individual step save options.
Save bool
}
type FilterOptions struct {
// Enable saving of this step's result. Takes precedence over Pipe options
Save *bool
}
type PipeMat struct {
mat *gocv.Mat
temp *gocv.Mat
kernel *gocv.Mat
}
type Pipe struct {
name string
steps []step
opts PipeOptions
results []*PipeMat
}
type step struct {
Filter
opts FilterOptions
}
func NewPipe(name string, opts PipeOptions) *Pipe {
return &Pipe{
name: name,
opts: opts,
}
}
func (p *Pipe) Close() {
for _, s := range p.steps {
s.Close()
}
}
// Add a filter to the pipe. If save is true, the result of this step will be saved to disk.
func (p *Pipe) Add(f Filter, opts ...FilterOptions) *Pipe {
if len(opts) == 0 {
p.steps = append(p.steps, step{f, FilterOptions{}})
return p
}
p.steps = append(p.steps, step{f, opts[0]})
return p
}
// Run applies all filters in the pipe to the given PipeMat.
func (p *Pipe) Run(m *PipeMat) *PipeMat {
for i, f := range p.steps {
m = f.Apply(m)
var shouldSave bool
if f.opts.Save == nil {
shouldSave = p.opts.Save
} else {
shouldSave = *f.opts.Save
}
if shouldSave {
gocv.IMWrite(fmt.Sprintf("data/%v_%03d_%v.jpg", p.name, i, f.Name()), *m.mat)
}
}
return m
}
type MatOptions struct {
Size *image.Point
Type *gocv.MatType
}
// NewPipeMat creates a new PipeMat from a gocv.Mat.
// The gocv.Mat will be cloned and stored in the PipeMat. The original Mat needs to be closed by the caller.
func NewPipeMat(mat gocv.Mat) *PipeMat {
temp := gocv.NewMat()
kernel := gocv.NewMat()
m := mat.Clone()
return &PipeMat{
mat: &m,
temp: &temp,
kernel: &kernel,
}
}
func NewPipeMatFromOptions(opts MatOptions) (*PipeMat, error) {
if opts.Size == nil && opts.Type == nil {
return nil, fmt.Errorf("Size and Type must be set")
}
mat := gocv.NewMatWithSize(opts.Size.Y, opts.Size.X, *opts.Type)
temp := gocv.NewMat()
kernel := gocv.NewMat()
return &PipeMat{
mat: &mat,
temp: &temp,
kernel: &kernel,
}, nil
}
func (m *PipeMat) Close() {
if m.mat != nil {
m.mat.Close()
m.mat = nil
}
if m.temp != nil {
m.temp.Close()
m.temp = nil
}
if m.kernel != nil {
m.kernel.Close()
m.kernel = nil
}
}