Zuletzt aktiv 1 month ago

JPSS "bowdetie" script

bowdetie.go Originalformat
1package main
2
3import (
4 "os"
5 "image"
6 "log"
7 "image/png"
8 "math"
9 "time"
10 "github.com/nfnt/resize"
11)
12
13//var filename = "JPSS1_VIIRS_I01_2017-12-20T07:54:34-02:00.png"
14var filename = "JPSS1_VIIRS_I01_2017-12-20T08:39:35-02:00.png"
15
16type Setting struct {
17 id int
18 name string
19 width int
20 params [6]int
21 params2 [6]int
22 bits int
23}
24
25type BowTie struct {
26 x0 int
27 y0 int
28 x1 int
29 y1 int
30}
31
32var settings = map[string]Setting {
33 "I01": {
34 id: 818,
35 name: "I01",
36 width: 6400,
37 params: [6]int{1280, 736, 1184, 1184, 736, 1280},
38 params2: [6]int{6, 2, 0, 0, 2, 6},
39 bits: 31,
40 },
41}
42
43func IsBlack(r,g,b uint32) bool {
44 return r == 0 && g == 0 && b == 0
45}
46
47func LinearInterp(r float32, q0, q1 uint32) uint16 {
48 return uint16(float32(q0) * (1 - r) + float32(q1) * (r))
49}
50
51func CosineInterp(r float32, q0, q1 uint32) uint16 {
52 var mu = float64(r)
53 var mu2 = (1 - math.Cos(mu * math.Pi)) / 2
54
55 return uint16(float64(q0) * (1 - mu2) + float64(q1) * (mu2))
56}
57
58var numPasses = 4
59
60func ProcessBowTie(m image.Image, bt BowTie) {
61 var gm = m.(*image.Gray16)
62 var w = bt.x1 - bt.x0
63 var h = bt.y1 - bt.y0
64 var btImg = image.NewGray16(image.Rect(0, 0, w, 2))
65 // Slice Two lines
66 for x := 0; x < w; x++ {
67 btImg.Set(x, 0, gm.At(bt.x0 + x, bt.y0 - 1))
68 btImg.Set(x, 1, gm.At(bt.x0 + x, bt.y1 + 1))
69 }
70
71 btImgRes := resize.Resize(uint(float32(w)), uint(h) , btImg, resize.Lanczos3)
72
73 for x := 0; x < w; x++ {
74 for y := 0; y < h; y++ {
75 gm.Set(bt.x0 + x, bt.y0 + y, btImgRes.At(x, y))
76 }
77 }
78
79 //var gm = m.(*image.Gray16)
80 //var h = float32(bt.y1 - bt.y0) + 2
81 //for x := bt.x0; x <= bt.x1; x++ {
82 // var q0, _, _, _ = m.At(x, bt.y0 - 1).RGBA()
83 // var q1, _, _, _ = m.At(x, bt.y1 + 1).RGBA()
84 // for y := bt.y0; y <= bt.y1; y++ {
85 // // Linear / Cosine
86 // var r = float32(y - bt.y0) / float32(h)
87 // gm.Set(x, y, color.Gray16{ Y: LinearInterp(r, q0, q1) })
88 // }
89 //}
90 //for i := 0; i < numPasses; i++ {
91 // for x := bt.x0; x < bt.x1; x++ {
92 // for y := bt.y0; y < bt.y1; y++ {
93 // var q2, _, _, _= m.At(x, y).RGBA()
94 // var q3, _, _, _= m.At(x+1, y).RGBA()
95 // gm.Set(x, y, color.Gray16{Y: LinearInterp(0.5, q2, q3)})
96 // }
97 // }
98 //}
99}
100
101func main() {
102 reader, err := os.Open(filename)
103 if err != nil {
104 panic(err)
105 }
106
107 m, format, err := image.Decode(reader)
108
109 if err != nil {
110 panic(err)
111 }
112
113 log.Println("Found image format", format)
114
115 reader.Close()
116
117 var currSetting = settings["I01"]
118 var bowTies []BowTie
119
120 bounds := m.Bounds()
121
122 startTime := time.Now()
123
124 // Find head bowtie
125 var x = bounds.Min.X
126 for z := 0; z < 6; z++ {
127 if z == 2 || z == 3 {
128 x += currSetting.params[z]
129 continue
130 }
131 var csw = currSetting.params[z]
132 var csh = currSetting.params2[z]
133 for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
134 r, g, b, _ := m.At(x, y).RGBA()
135 if IsBlack(r, g, b) {
136 //log.Println("Found black pixel at", y)
137 var nextY = y + csh
138 if nextY > bounds.Max.Y || nextY + 1 > bounds.Max.Y {
139 break
140 }
141 nr, ng, nb, _ := m.At(x, nextY).RGBA()
142 n2r, n2g, n2b, _ := m.At(x, nextY + 1).RGBA()
143 if IsBlack(nr, ng, nb) && !IsBlack(n2r, n2g, n2b) {
144 bt := BowTie{
145 x0: x,
146 y0: y,
147 x1: x + csw + 1,
148 y1: y + csh + 1,
149 }
150 bowTies = append(bowTies, bt)
151 y += currSetting.params2[0]
152 }
153 }
154 }
155 x += currSetting.params[z]
156 }
157
158 // Fill Bow Ties with red
159 for i := 0; i < len(bowTies); i++ {
160 //log.Println("Paiting bowtie", i)
161 ProcessBowTie(m, bowTies[i])
162 }
163
164 delta := time.Now().Sub(startTime).Seconds()
165
166 log.Println("Took", delta, "seconds to debowtie!")
167
168 out, err := os.Create("out.png")
169 err = png.Encode(out, m)
170 if err != nil {
171 panic(err)
172 }
173 out.Close()
174}