From 1ef3625c993455f0785287bbacf59e4c6fd9f4d7 Mon Sep 17 00:00:00 2001 From: J2ghz Date: Wed, 1 May 2019 13:03:14 +0200 Subject: [PATCH 1/2] use heatmap.py's palette --- internal/gopow/table.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/internal/gopow/table.go b/internal/gopow/table.go index 194631e..0383fed 100644 --- a/internal/gopow/table.go +++ b/internal/gopow/table.go @@ -199,8 +199,8 @@ func (t *TableComplex) ColorAt(x, y int) color.Color { cell := t.Rows[y].Sample(x) - hueStart := 236.0 - hueEnd := 0.0 + hueStart := 0.0 + hueEnd := 1.0 span := (*t.Config.MinPower - *t.Config.MaxPower) * -1 hPerDeg := (hueStart - hueEnd) / span @@ -208,13 +208,13 @@ func (t *TableComplex) ColorAt(x, y int) color.Color { powDegrees := powNormalized * hPerDeg hue := hueStart - powDegrees - if hue > hueStart { + if hue < hueStart { hue = hueStart } - if hue < hueEnd { + if hue > hueEnd { hue = hueEnd } - return colorful.Hsv(hue, 1, 0.90) + return colorful.Color{hue, hue, 0} } From c30e2324b610b32aa377d12d6a07b2f50fb675fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Ho=CC=88gborg?= Date: Sat, 18 Jul 2020 19:50:26 +0200 Subject: [PATCH 2/2] Configurable palette --- gopow.go | 8 +++-- internal/gopow/gopow.go | 16 ++++++---- internal/gopow/palette.go | 61 +++++++++++++++++++++++++++++++++++++++ internal/gopow/table.go | 37 ------------------------ 4 files changed, 77 insertions(+), 45 deletions(-) create mode 100644 internal/gopow/palette.go diff --git a/gopow.go b/gopow.go index ba53058..1b8fa27 100644 --- a/gopow.go +++ b/gopow.go @@ -10,7 +10,6 @@ import ( ) func main() { - app := cli.NewApp() app.Name = "RTL GoPow" app.Usage = "Render a rtl_power CSV output as waterfall image" @@ -19,7 +18,6 @@ func main() { app.Email = "d@hogborg.se" app.Action = func(c *cli.Context) { - if c.Bool("verbose") == true { log.SetLevel(log.DebugLevel) } else { @@ -49,7 +47,6 @@ func main() { }).Fatal("write failed") return } - } app.Flags = []cli.Flag{ @@ -86,6 +83,11 @@ func main() { Name: "no-annotations", Usage: "Disabled annotations such as time and frequency scales", }, + cli.StringFlag{ + Name: "palette", + Usage: "Select the palette for output image. [spectrum,yellow]", + Value: "spectrum", + }, } app.Run(os.Args) diff --git a/internal/gopow/gopow.go b/internal/gopow/gopow.go index 3c96a6c..6c0be88 100644 --- a/internal/gopow/gopow.go +++ b/internal/gopow/gopow.go @@ -24,6 +24,7 @@ type RunConfig struct { Annotations bool MaxPower float64 MinPower float64 + Palette string } type GoPow struct { @@ -33,7 +34,6 @@ type GoPow struct { } func NewGoPow(c *cli.Context) (*GoPow, error) { - config := &RunConfig{ InputFile: c.String("input"), OutputFile: c.String("output"), @@ -41,6 +41,7 @@ func NewGoPow(c *cli.Context) (*GoPow, error) { Annotations: !c.Bool("no-annotations"), MaxPower: c.Float64("max-power"), MinPower: c.Float64("min-power"), + Palette: c.String("palette"), } if !c.IsSet("max-power") { @@ -80,7 +81,6 @@ func NewGoPow(c *cli.Context) (*GoPow, error) { } func (g *GoPow) Render() error { - conf := &RenderConfig{} if g.config.MaxPower != PowerConfigAuto { @@ -91,6 +91,14 @@ func (g *GoPow) Render() error { conf.MinPower = &g.config.MinPower } + var palette Palette + switch g.config.Palette { + case "yellow": + palette = &YellowPalette{} + default: + palette = &SpectrumPalette{} + } + log.Debug("staring render") g.timestamp = time.Now() @@ -103,12 +111,11 @@ func (g *GoPow) Render() error { for y, row := range table.Rows { for x := range row.Samples { - g.image.Set(x, y, table.ColorAt(x, y)) + g.image.Set(x, y, palette.ColorAt(table, x, y)) } } if g.config.Annotations { - annotator, err := NewAnnotator(g.image, table) if err != nil { return err @@ -124,7 +131,6 @@ func (g *GoPow) Render() error { } func (g *GoPow) Write() error { - log.WithFields(log.Fields{ "file": g.config.OutputFile, }).Debug("staring output write") diff --git a/internal/gopow/palette.go b/internal/gopow/palette.go new file mode 100644 index 0000000..a7f8c58 --- /dev/null +++ b/internal/gopow/palette.go @@ -0,0 +1,61 @@ +package gopow + +import ( + "image/color" + + "github.com/lucasb-eyer/go-colorful" +) + +type Palette interface { + ColorAt(table *TableComplex, x, y int) color.Color +} + +type YellowPalette struct { +} + +func (p *YellowPalette) ColorAt(table *TableComplex, x, y int) color.Color { + cell := table.Rows[y].Sample(x) + + hueStart := 0.0 + hueEnd := 1.0 + + span := (*table.Config.MinPower - *table.Config.MaxPower) * -1 + hPerDeg := (hueStart - hueEnd) / span + powNormalized := cell - *table.Config.MinPower + powDegrees := powNormalized * hPerDeg + hue := hueStart - powDegrees + + if hue < hueStart { + hue = hueStart + } + if hue > hueEnd { + hue = hueEnd + } + + return colorful.Color{hue, hue, 0} +} + +type SpectrumPalette struct { +} + +func (p *SpectrumPalette) ColorAt(table *TableComplex, x, y int) color.Color { + cell := table.Rows[y].Sample(x) + + hueStart := 236.0 + hueEnd := 0.0 + + span := (*table.Config.MinPower - *table.Config.MaxPower) * -1 + hPerDeg := (hueStart - hueEnd) / span + powNormalized := cell - *table.Config.MinPower + powDegrees := powNormalized * hPerDeg + hue := hueStart - powDegrees + + if hue > hueStart { + hue = hueStart + } + if hue < hueEnd { + hue = hueEnd + } + + return colorful.Hsv(hue, 1, 0.90) +} diff --git a/internal/gopow/table.go b/internal/gopow/table.go index 0383fed..c49a7f8 100644 --- a/internal/gopow/table.go +++ b/internal/gopow/table.go @@ -3,7 +3,6 @@ package gopow import ( "bytes" "image" - "image/color" "io/ioutil" "math" "sort" @@ -11,7 +10,6 @@ import ( "time" "github.com/dustin/go-humanize" - "github.com/lucasb-eyer/go-colorful" log "github.com/sirupsen/logrus" ) @@ -38,7 +36,6 @@ type RenderConfig struct { } func NewTable(file string, conf *RenderConfig) (*TableComplex, error) { - log.Debug("creating table") t := &TableComplex{ @@ -54,7 +51,6 @@ func NewTable(file string, conf *RenderConfig) (*TableComplex, error) { } func (t *TableComplex) Load(file string) error { - log.Debug("loading table") t.File = file @@ -75,7 +71,6 @@ func (t *TableComplex) Load(file string) error { } func (t *TableComplex) parseBuffer(filebuffer []byte) []*LineComplex { - var max = float64(math.MaxFloat64 * -1) var min = float64(math.MaxFloat64) @@ -84,7 +79,6 @@ func (t *TableComplex) parseBuffer(filebuffer []byte) []*LineComplex { table := map[string][]*LineComplex{} for _, l := range lines { - cells := strings.Split(string(l), ",") line := NewLineComplex(cells) @@ -99,11 +93,8 @@ func (t *TableComplex) parseBuffer(filebuffer []byte) []*LineComplex { // loop over hash keys with lines for _, lines := range table { - row := t.IntegrateLines(lines) - if row != nil { - rows = append(rows, row) if min > row.LowSample() { @@ -117,7 +108,6 @@ func (t *TableComplex) parseBuffer(filebuffer []byte) []*LineComplex { t.HzHigh = row.HzHigh if row.Time != nil { - if t.TimeStart == nil { t.TimeStart = row.Time } @@ -134,7 +124,6 @@ func (t *TableComplex) parseBuffer(filebuffer []byte) []*LineComplex { t.TimeEnd = row.Time } } - } } @@ -170,7 +159,6 @@ func (t *TableComplex) parseBuffer(filebuffer []byte) []*LineComplex { } func (t *TableComplex) Image() *image.RGBA { - log.WithFields(log.Fields{ "width": t.Bins, "height": t.Integrations, @@ -180,7 +168,6 @@ func (t *TableComplex) Image() *image.RGBA { } func (t *TableComplex) IntegrateLines(lines []*LineComplex) *LineComplex { - if len(lines) == 0 { return nil } @@ -194,27 +181,3 @@ func (t *TableComplex) IntegrateLines(lines []*LineComplex) *LineComplex { return masterline } - -func (t *TableComplex) ColorAt(x, y int) color.Color { - - cell := t.Rows[y].Sample(x) - - hueStart := 0.0 - hueEnd := 1.0 - - span := (*t.Config.MinPower - *t.Config.MaxPower) * -1 - hPerDeg := (hueStart - hueEnd) / span - powNormalized := cell - *t.Config.MinPower - powDegrees := powNormalized * hPerDeg - hue := hueStart - powDegrees - - if hue < hueStart { - hue = hueStart - } - if hue > hueEnd { - hue = hueEnd - } - - return colorful.Color{hue, hue, 0} - -}