Using Image.jl for false-color maps

455 views
Skip to first unread message

Adrian Cuthbertson

unread,
Sep 18, 2013, 11:21:52 AM9/18/13
to julia...@googlegroups.com
I have a 2-d array with sensor data ranging in values from 0.5 to 1.5. I would like to represent this in a "map" image with pixel values being colours ranging from 0.5 = blue, to 1.0 = white, to 1.5 = red, with intermediate values being hues of blue-to-white-to-red. 

I know I could write code to generate a 3-d RGB array (or similar), but could this be done using ImageCmap? If so, how would I structure cmap to map from the raw data to a Color object?

Any assistance would be appreciated.

Regards, Adrian.

Tim Holy

unread,
Sep 19, 2013, 9:57:15 AM9/19/13
to julia...@googlegroups.com
First, a one-liner:

ImageView.display(datafloat-1, scalei = ScaleSigned(1/0.5))

This will give you a green (negative)/magenta (positive) colormap rather than
your blue/red. If you can live with that, this is easy. (Note: you may need to
do Pkg.update(), because only in recent masters have I been exporting
ScaleSigned; there are also some other fixes for the demo below.)


Only slightly more difficult, but more flexible: as you say, use ImageCmap:

using Images, ImageView, Color
# build a sample image
datafloat = reshape(linspace(0.5, 1.5, 60000), 200, 300)
# convert the raw 0.5:1.5 data to a integer type, so we can index
dataint = iround(Uint8, 254*(datafloat - 0.5) + 1) # ranges from 1 to 255
# build our colormap
b = RGB(0,0,1)
w = RGB(1,1,1)
r = RGB(1,0,0)
cmaprgb = Array(RGB, 255)
f = linspace(0,1,128)
cmaprgb[1:128] = [(1-x)*b + x*w for x in f]
cmaprgb[129:end] = [(1-x)*w + x*r for x in f[2:end]]

img = ImageCmap(dataint, cmaprgb)

ImageView.display(img)

To simplify this process, I would be amenable to having a colormap() function
that constructs piecewise-linear colormaps. Also, if you need the utmost in
performance, you'd be best converting your cmaprgb array to Uint32 before
constructing the image, perhaps like this:

img = ImageCmap(dataint, uint32(cmaprgb))


More generally, the support for indexed/colormap images in Images is likely to
be somewhat rudimentary. I haven't used them a lot, and one of the barriers is
that I can't figure out how to get ImageMagick to return the raw Cmap for
standard image formats. I even have a question posted on the forum:
http://www.imagemagick.org/discourse-
server/viewtopic.php?f=1&t=22916&hilit=colormap
but the answers get us only partway. If you know how to solve that problem, it
would be most welcome.

Best,
--Tim

Steven G. Johnson

unread,
Sep 19, 2013, 10:04:14 AM9/19/13
to julia...@googlegroups.com

To simplify this process, I would be amenable to having a colormap() function
that constructs piecewise-linear colormaps.

linspace(color1, color2, n) works.

(There is also a more general colormap-creation functionality in the PyPlot package, inherited from matplotlib but adapted to work with Color.jl.)

Tim Holy

unread,
Sep 19, 2013, 10:29:14 AM9/19/13
to julia...@googlegroups.com
On Thursday, September 19, 2013 07:04:14 AM Steven G. Johnson wrote:
> linspace(color1, color2, n) works.

For two endpoints, yes. This case also had a midpoint. I didn't know about the
one in PyPlot, that looks like the kind of thing I had in mind. From a brief
glance, though, I was confused about one thing: why is each of r, g, b a
vector of 3-tuples? I would have assumed that r, g, and b would each be a
single element of such a 3-tuple.

--Tim

Adrian Cuthbertson

unread,
Sep 19, 2013, 11:51:19 AM9/19/13
to julia...@googlegroups.com
Awesome! That example with the midpoint is exactly what I was looking for. It gives a nice sense of the slope around the midpoint values and also emphasises jagged regions in the map. I probably need a lower-level approach anyway, as in my case negative values in the original float data indicate bad values and those pixels need to be black. 

I'm going to be doing quite a lot of work with this type of imaging, so I'll try and contribute if I can. I'll also check out the colormap functions in PyPlot. 

Thanks Tim and Steven. The Julia imaging and plotting story gets better and better!

  

Tim Holy

unread,
Sep 19, 2013, 1:16:29 PM9/19/13
to julia...@googlegroups.com
Glad it looks promising.

ImageCmap might indeed be the way to go; alternatively, if it's unattractive
to generate the integer-indexed images directly, you could consider an "on-
the-fly" approach using a custom ScaleInfo type and a custom version of
uint32color! to work with it. It's essentially a lazy-evaluation approach to
colormaps, and you can set up an arbitrary mapping between values and screen-
colors this way. I default to this approach in my own work, because I work
with terabyte-sized multidimensional images, and it lets me display just the
portions of the image I'm interested in without requiring a lot of conversions
in portions of the image that I'll likely never even look at.

If you decide to go this way, the implementation of ScaleSigned and the
version of uint32color! that works with this type should show you how to
proceed.

Best,
--Tim

Steven G. Johnson

unread,
Sep 21, 2013, 12:41:53 PM9/21/13
to julia...@googlegroups.com

In the simple case, you can just pass an array of ColorValue colors to PyPlot and that will do what you expect.  However, Matplotlib allows you to do more complex things like introduce discontinuities or have different components changing with different endpoints; see:
     http://matplotlib.org/api/colors_api.html#matplotlib.colors.LinearSegmentedColormap

Steven G. Johnson

unread,
Sep 21, 2013, 12:46:48 PM9/21/13
to julia...@googlegroups.com
See also https://github.com/stevengj/PyPlot.jl#color-maps  ... note that matplotlib actually has quite a nice collection of built-in colormaps, as you can see if you run `get_cmaps()` in IJulia.

Tim Holy

unread,
Sep 21, 2013, 1:05:16 PM9/21/13
to julia...@googlegroups.com
Very helpful, thanks.

--Tim

Yakir Gagnon

unread,
Jun 19, 2014, 2:38:41 AM6/19/14
to julia...@googlegroups.com
How do you extract the colors from the colormap?
So if I have some colormap:
a = ColorMap([RGB(1,0,0),RGB(0,0,1)],100,1.)
How do I get the vector of colors (should contain 100 colors from red to blue)?
Reply all
Reply to author
Forward
0 new messages