Repository navigation
Expand file tree
/
Copy pathimage_preprocessor.go
More file actions
150 lines (128 loc) · 3.81 KB
/
Copy pathimage_preprocessor.go
File metadata and controls
150 lines (128 loc) · 3.81 KB
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
//go:build with_image
package cpullmapi
import (
"fmt"
"github.com/davidbyttow/govips/v2/vips"
)
type PILResampleMethod int
const (
PILResampleMethodNearest PILResampleMethod = 0
PILResampleMethodLANCZOS PILResampleMethod = 1
PILResampleMethodBilinear PILResampleMethod = 2
PILResampleMethodBicubic PILResampleMethod = 3
PILResampleMethodBox PILResampleMethod = 4
PILResampleMethodHAMMING PILResampleMethod = 5
)
type ViTImageProcessorConfig struct {
DoNormalize *bool `json:"do_normalize"`
DoRescale *bool `json:"do_rescale"`
DoResize *bool `json:"do_resize"`
ImageMean *[]float32 `json:"image_mean"`
ImageStd *[]float32 `json:"image_std"`
Resample *PILResampleMethod `json:"resample"`
RescaleFactor *float32 `json:"rescale_factor"`
Size struct {
Height int `json:"height"`
Width int `json:"width"`
} `json:"size"`
}
type ViTImageProcessor struct {
config ViTImageProcessorConfig
}
func NewViTImageProcessor(config ViTImageProcessorConfig) (*ViTImageProcessor, error) {
return &ViTImageProcessor{
config: config,
}, nil
}
func (p *ViTImageProcessor) PreprocessImage(image *vips.ImageRef) ([]float32, error) {
var err error
var resizeMethod PILResampleMethod
var rescaleFactor float32
var mean [3]float32
var std [3]float32
// 1. resize image to config.Size
if p.config.DoResize != nil && *p.config.DoResize == false {
goto skipResize
}
resizeMethod = PILResampleMethodBilinear
if p.config.Resample != nil {
resizeMethod = *p.config.Resample
}
err = InplaceResizeImage(image, p.config.Size.Width, p.config.Size.Height, resizeMethod)
if err != nil {
return nil, err
}
skipResize:
// pre-2 convert image to RGB array
rgbU8Array, err := inplaceImageToRGBU8Array(image, nil)
if err != nil {
return nil, err
}
// image reference is now pointing to the resized and converted (to rgb888) image
// so just imagine that image is freed
hwcArray := make([]float32, len(rgbU8Array))
for i := range rgbU8Array {
hwcArray[i] = float32(rgbU8Array[i])
}
// 2. rescale pixel values
if p.config.DoRescale != nil && *p.config.DoRescale == false {
goto skipRescale
}
rescaleFactor = float32(1) / float32(255)
if p.config.RescaleFactor != nil {
rescaleFactor = *p.config.RescaleFactor
}
for i := range hwcArray {
hwcArray[i] = hwcArray[i] * rescaleFactor
}
skipRescale:
// 3. normalize(-mean, /std) pixel values
if p.config.DoNormalize != nil && *p.config.DoNormalize == false {
goto skipNormalize
}
mean = [3]float32{0.5, 0.5, 0.5}
std = [3]float32{0.5, 0.5, 0.5}
if p.config.ImageMean != nil {
if len(*p.config.ImageMean) != 3 {
return nil, fmt.Errorf("image mean must be a list of 3 values")
}
mean = [3]float32{
(*p.config.ImageMean)[0],
(*p.config.ImageMean)[1],
(*p.config.ImageMean)[2],
}
}
if p.config.ImageStd != nil {
if len(*p.config.ImageStd) != 3 {
return nil, fmt.Errorf("image std must be a list of 3 values")
}
if (*p.config.ImageStd)[0] == 0 {
return nil, fmt.Errorf("image std[0] is 0")
}
if (*p.config.ImageStd)[1] == 0 {
return nil, fmt.Errorf("image std[1] is 0")
}
if (*p.config.ImageStd)[2] == 0 {
return nil, fmt.Errorf("image std[2] is 0")
}
std = [3]float32{
(*p.config.ImageStd)[0],
(*p.config.ImageStd)[1],
(*p.config.ImageStd)[2],
}
}
for i := range len(hwcArray) / 3 {
hwcArray[i*3] = (hwcArray[i*3] - mean[0]) / std[0]
hwcArray[i*3+1] = (hwcArray[i*3+1] - mean[1]) / std[1]
hwcArray[i*3+2] = (hwcArray[i*3+2] - mean[2]) / std[2]
}
skipNormalize:
// convert HWC to CHW
chwArray := make([]float32, len(hwcArray))
for i := range len(hwcArray) / 3 {
chwArray[i] = hwcArray[i*3]
chwArray[i+len(hwcArray)/3] = hwcArray[i*3+1]
chwArray[i+len(hwcArray)/3*2] = hwcArray[i*3+2]
}
return chwArray, nil
}