Image Processing - Removing Color

466 views
Skip to first unread message

William Kennedy

unread,
Aug 24, 2013, 9:44:00 PM8/24/13
to golan...@googlegroups.com
Hi Gophers, before I go ahead and use image magic I wanted to ask.


There are blue colors that represent radar noise. If I run these image magic commands the image cleans up nicely. 

convert radar.gif -channel rgba -alpha set -fuzz 10% -fill none -opaque "#3030CE" test.gif
convert test.gif -channel rgba -alpha set -fuzz 10% -fill none -opaque "#04e9e7" test.gif
convert test.gif -channel rgba -alpha set -fuzz 10% -fill none -opaque "#019ff4" test.gif
convert test.gif -channel rgba -alpha set -fuzz 10% -fill none -opaque "#0300f4" test.gif
convert test.gif -channel RGBA -blur 2x2 test.gif

I was curious if there was a smaller and/or native package that could do the same thing?

andrey mirtchovski

unread,
Aug 24, 2013, 10:48:23 PM8/24/13
to William Kennedy, golang-nuts
there is a pretty nice C wrapper for ImageMagick at
github.com/gographics/imagick. i had only heard of it and not played
with it until 30 minutes ago, but it seems to be pretty complete,
installs fine on my mac (already had imagemagick libraries from
macports, zero configuration necessary) and i was able to whip up an
example in 30 minutes that does all the things you mention and
provides a visually similar result to yours. the only problem i had is
that godoc.org wouldn't display docs for the package. i had to use a
local godoc copy. small price to pay, but otherwise "yes, go is _that_
nice!" :)

http://play.golang.org/p/4evP5Bp3Qa

cheers, and hope that helps. feel free to use the code as a basis of
your explorations.

(apologies for not checking all the errors in the code above, it is bad style)

andrey mirtchovski

unread,
Aug 24, 2013, 10:51:10 PM8/24/13
to William Kennedy, golang-nuts
small bug in the defer statements for the filter colors -- copy/paste
strikes again :)

Benjamin Measures

unread,
Aug 25, 2013, 10:02:57 AM8/25/13
to golan...@googlegroups.com
On Sunday, 25 August 2013 02:44:00 UTC+1, William Kennedy wrote:

There are blue colors that represent radar noise. If I run these image magic commands the image cleans up nicely. 

[...]


I was curious if there was a smaller and/or native package that could do the same thing?


The gif will be paletted - to clean up colours you can just edit the palette (set alpha or whatever).

If a png destination is acceptable, you might have some success with using the std library to decode the gif, edit the palette entries then encode to png. This will be cheap and can be effectively lossless (reversable).

Nigel Tao

unread,
Aug 26, 2013, 12:36:37 AM8/26/13
to William Kennedy, golang-nuts
On Sun, Aug 25, 2013 at 11:44 AM, William Kennedy
<bi...@thekennedyclan.net> wrote:
> I was curious if there was a smaller and/or native package that could do the
> same thing?

You can do it natively:

package main

import (
"image"
"image/color"
"image/gif"
"image/png"
"log"
"os"
)

var strip = [][3]uint32{
{0x30, 0x30, 0xce},
{0x04, 0xe9, 0xe7},
{0x01, 0x9f, 0xf4},
{0x03, 0x00, 0xf4},
}

func main() {
src, err := os.Open("radar.gif")
if err != nil {
log.Fatalf("Open: %v", err)
}
defer src.Close()

m, err := gif.Decode(src)
if err != nil {
log.Fatalf("Decode: %v", err)
}
p := m.(*image.Paletted)
for i, c := range p.Palette {
r, g, b, _ := c.RGBA()
r, g, b = r>>8, g>>8, b>>8
for _, stripc := range strip {
if [3]uint32{r, g, b} == stripc {
p.Palette[i] = color.Transparent
break
}
}
}

m = blur(m)

dst, err := os.Create("out.png")
if err != nil {
log.Fatalf("Create: %v", err)
}
defer dst.Close()
err = png.Encode(dst, m)
if err != nil {
log.Fatalf("Encode: %v", err)
}
}

var weights = [5]uint32{1, 2, 5, 2, 1}

func blur(src image.Image) image.Image {
bounds := src.Bounds()
dst := image.NewRGBA(bounds)
for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
for x := bounds.Min.X; x < bounds.Max.X; x++ {
var r, g, b, a, n uint32
for j := -2; j <= 2; j++ {
for i := -2; i <= 2; i++ {
if !(image.Point{x + i, y + j}).In(bounds) {
continue
}
w := weights[i+2] * weights[j+2]
r1, g1, b1, a1 := src.At(x+i, y+j).RGBA()
r += w * r1
g += w * g1
b += w * b1
a += w * a1
n += w
}
}
r /= n
g /= n
b /= n
a /= n
dst.SetRGBA(x, y, color.RGBA{uint8(r >> 8), uint8(g >> 8),
uint8(b >> 8), uint8(a >> 8)})
}
}
return dst
}

William Kennedy

unread,
Aug 26, 2013, 12:41:01 AM8/26/13
to golan...@googlegroups.com, William Kennedy
How do I save that back as a gif?

William Kennedy

unread,
Aug 26, 2013, 12:55:59 AM8/26/13
to golan...@googlegroups.com, William Kennedy
Actually, I need to get a []byte so I can save it.  Can't see how to convert Image to []byte

Hariharan Srinath

unread,
Aug 27, 2013, 12:57:07 AM8/27/13
to golan...@googlegroups.com
You can use the Encode function in one of the subpackages of image - possibly image/png in your case - to encode the image and send the output to an io.Writer that wraps your output file.

http://golang.org/pkg/image/png/

Reader and Writer interfaces are used repeatedly in the standard library - so good to familiarize yourself.

Regards
Srinath

Nigel Tao

unread,
Aug 27, 2013, 3:49:38 AM8/27/13
to William Kennedy, golang-nuts
On Mon, Aug 26, 2013 at 2:55 PM, William Kennedy
<bi...@thekennedyclan.net> wrote:
> Actually, I need to get a []byte so I can save it. Can't see how to convert
> Image to []byte

The png.Encode function takes an io.Writer, so if you need []byte,
import "bytes" and:

buf := bytes.NewBuffer(nil)
err = png.Encode(buf, m)
if err != nil {
log.Fatalf("Encode: %v", err)
}
return buf.Bytes()

But I'm confused by your question. My earlier code example saved the
encoded bytes to a file. If you need to write to a network connection,
pass that to png.Encode instead (a net.Conn is an io.Writer). I don't
think you need the []byte.

If you need GIF instead of PNG, call gif.Encode instead of png.Encode.

Andy Bonventre

unread,
Aug 27, 2013, 8:17:46 PM8/27/13
to Nigel Tao, William Kennedy, golang-nuts
If you need GIF instead of PNG, call gif.Encode instead of png.Encode.
 
It should be noted that gif.Encode will not be available until 1.2 is released.

dbe...@gmail.com

unread,
Sep 21, 2016, 6:44:20 PM9/21/16
to golang-nuts
This was a great find, I am doing the same now in Windows. I've had to modify it a bit, I imagine weather.gov has changed the image somewhat since the original post in 2013. I've had to remove some more of the light blue colors and then one more pass to get rid of the light grey radar "noise".

I'm also grabbing the pre-made gif loop, e.g. http://radar.weather.gov/Conus/Loop/uppermissvly_loop.gif

I put all the commands for the main colors into one convert command. Since I was grabbing the regional loop with the state lines I couldn't use the "blur".
Also, since I'm on Windows I had to make sure to not call the other "convert" (which is for NTFS filesystem conversion).

echo Processing weather gif radar_uppermissvly_loop.gif removing the blue colors from the radar...
set "imconvert=C:\Program Files (x86)\ImageMagick-6.9.2-Q8\convert.exe" 

REM the carets are for multi-lines in "DOS"
"%imconvert%" -channel rgba -alpha set -fuzz 25% -fill "#FFFFFF" -opaque "#3030CE" ^
-opaque "#04e9e7" -opaque "#019ff4" -opaque "#0300f4" -opaque "#0248F4" ^
-opaque "#69F2F0" radar_uppermissvly_loop.gif radar_grey.gif

echo Processing weather gif radar removing the greyish radar...
"%imconvert%"  -channel rgba -alpha set -fuzz 12% -fill "#FFFFFF" -opaque "#E2E2E2"  radar_grey.gif radar_clean.gif

echo Trimming down the radar to a more localized region...
%imconvert%"  -crop 260x280+277+56 -trim +repage  radar_clean.gif radar_cropped.gif


Thanks, posting in case it helps someone else who's stuck on the blue and grey colors (and is using the command line version in Windows or Linux).



Reply all
Reply to author
Forward
0 new messages