bowdetie.go
· 3.5 KiB · Go
Исходник
package main
import (
"os"
"image"
"log"
"image/png"
"math"
"time"
"github.com/nfnt/resize"
)
//var filename = "JPSS1_VIIRS_I01_2017-12-20T07:54:34-02:00.png"
var filename = "JPSS1_VIIRS_I01_2017-12-20T08:39:35-02:00.png"
type Setting struct {
id int
name string
width int
params [6]int
params2 [6]int
bits int
}
type BowTie struct {
x0 int
y0 int
x1 int
y1 int
}
var settings = map[string]Setting {
"I01": {
id: 818,
name: "I01",
width: 6400,
params: [6]int{1280, 736, 1184, 1184, 736, 1280},
params2: [6]int{6, 2, 0, 0, 2, 6},
bits: 31,
},
}
func IsBlack(r,g,b uint32) bool {
return r == 0 && g == 0 && b == 0
}
func LinearInterp(r float32, q0, q1 uint32) uint16 {
return uint16(float32(q0) * (1 - r) + float32(q1) * (r))
}
func CosineInterp(r float32, q0, q1 uint32) uint16 {
var mu = float64(r)
var mu2 = (1 - math.Cos(mu * math.Pi)) / 2
return uint16(float64(q0) * (1 - mu2) + float64(q1) * (mu2))
}
var numPasses = 4
func ProcessBowTie(m image.Image, bt BowTie) {
var gm = m.(*image.Gray16)
var w = bt.x1 - bt.x0
var h = bt.y1 - bt.y0
var btImg = image.NewGray16(image.Rect(0, 0, w, 2))
// Slice Two lines
for x := 0; x < w; x++ {
btImg.Set(x, 0, gm.At(bt.x0 + x, bt.y0 - 1))
btImg.Set(x, 1, gm.At(bt.x0 + x, bt.y1 + 1))
}
btImgRes := resize.Resize(uint(float32(w)), uint(h) , btImg, resize.Lanczos3)
for x := 0; x < w; x++ {
for y := 0; y < h; y++ {
gm.Set(bt.x0 + x, bt.y0 + y, btImgRes.At(x, y))
}
}
//var gm = m.(*image.Gray16)
//var h = float32(bt.y1 - bt.y0) + 2
//for x := bt.x0; x <= bt.x1; x++ {
// var q0, _, _, _ = m.At(x, bt.y0 - 1).RGBA()
// var q1, _, _, _ = m.At(x, bt.y1 + 1).RGBA()
// for y := bt.y0; y <= bt.y1; y++ {
// // Linear / Cosine
// var r = float32(y - bt.y0) / float32(h)
// gm.Set(x, y, color.Gray16{ Y: LinearInterp(r, q0, q1) })
// }
//}
//for i := 0; i < numPasses; i++ {
// for x := bt.x0; x < bt.x1; x++ {
// for y := bt.y0; y < bt.y1; y++ {
// var q2, _, _, _= m.At(x, y).RGBA()
// var q3, _, _, _= m.At(x+1, y).RGBA()
// gm.Set(x, y, color.Gray16{Y: LinearInterp(0.5, q2, q3)})
// }
// }
//}
}
func main() {
reader, err := os.Open(filename)
if err != nil {
panic(err)
}
m, format, err := image.Decode(reader)
if err != nil {
panic(err)
}
log.Println("Found image format", format)
reader.Close()
var currSetting = settings["I01"]
var bowTies []BowTie
bounds := m.Bounds()
startTime := time.Now()
// Find head bowtie
var x = bounds.Min.X
for z := 0; z < 6; z++ {
if z == 2 || z == 3 {
x += currSetting.params[z]
continue
}
var csw = currSetting.params[z]
var csh = currSetting.params2[z]
for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
r, g, b, _ := m.At(x, y).RGBA()
if IsBlack(r, g, b) {
//log.Println("Found black pixel at", y)
var nextY = y + csh
if nextY > bounds.Max.Y || nextY + 1 > bounds.Max.Y {
break
}
nr, ng, nb, _ := m.At(x, nextY).RGBA()
n2r, n2g, n2b, _ := m.At(x, nextY + 1).RGBA()
if IsBlack(nr, ng, nb) && !IsBlack(n2r, n2g, n2b) {
bt := BowTie{
x0: x,
y0: y,
x1: x + csw + 1,
y1: y + csh + 1,
}
bowTies = append(bowTies, bt)
y += currSetting.params2[0]
}
}
}
x += currSetting.params[z]
}
// Fill Bow Ties with red
for i := 0; i < len(bowTies); i++ {
//log.Println("Paiting bowtie", i)
ProcessBowTie(m, bowTies[i])
}
delta := time.Now().Sub(startTime).Seconds()
log.Println("Took", delta, "seconds to debowtie!")
out, err := os.Create("out.png")
err = png.Encode(out, m)
if err != nil {
panic(err)
}
out.Close()
}
| 1 | package main |
| 2 | |
| 3 | import ( |
| 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" |
| 14 | var filename = "JPSS1_VIIRS_I01_2017-12-20T08:39:35-02:00.png" |
| 15 | |
| 16 | type Setting struct { |
| 17 | id int |
| 18 | name string |
| 19 | width int |
| 20 | params [6]int |
| 21 | params2 [6]int |
| 22 | bits int |
| 23 | } |
| 24 | |
| 25 | type BowTie struct { |
| 26 | x0 int |
| 27 | y0 int |
| 28 | x1 int |
| 29 | y1 int |
| 30 | } |
| 31 | |
| 32 | var 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 | |
| 43 | func IsBlack(r,g,b uint32) bool { |
| 44 | return r == 0 && g == 0 && b == 0 |
| 45 | } |
| 46 | |
| 47 | func LinearInterp(r float32, q0, q1 uint32) uint16 { |
| 48 | return uint16(float32(q0) * (1 - r) + float32(q1) * (r)) |
| 49 | } |
| 50 | |
| 51 | func 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 | |
| 58 | var numPasses = 4 |
| 59 | |
| 60 | func 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 | |
| 101 | func 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 | } |