How to convert a matrix to an RGB image using Images.jl?

images

#1

Let’s say that I have a matrix x

x = [0 0.5 1; 0.6 0.7 08.; 1 0.1 0.2]

I can display it as a grayscale image using

Gray.(x)

How can I convert it to an RGB image using a specified color gradient?

Plots.jl allows me to do something similar with

Plots.heatmap(x, yflip=true, color=:inferno)

But I’d like the actual image rather than the plot of the image please.


#2

What do you mean by " actual image rather than the plot of the image"? An image file on disk or the image array at the REPL?

You can get both with GMT. For example this

imshow(x, cmap="rainbow", fmt="png")

creates a GMTjl_tmp.png file in you temporary dir and displays it (you need ghostscript installed too).


#3

I’d like an RGB image array (as per Images.jl) to be returned and displayed in IJulia.

The following works, but gives me a color image where ll the colours are gray

RGB.(x, x, x)

Ideally, I want to say something like

RGB(x, cmap=:inferno)

so that the colors are interpolated from a color gradient.

Thanks for your input, but I don’t really want to use ImageView (I’m in IJulia) and anyway, your example doesn’t work for me.


#4

There is no ImageView involved in what I said. But you would need GMT and Ghostscript installed and that imshow is from GMT. To have it displayed on IJulia you would need something like

GMT.imshow(x, cmap="rainbow", fmt="png", show=false)

and than load the the /tmp/GMTjl_tmp.png (or the equivalent on Windows) from within IJulia.


#5

You could use the applycolormap from the PerceptualColourMaps package, e.g.:

using TestImages
img = testimage("moonsurface") # a grayscale image
using PerceptualColourMaps
imgc = applycolormap(img, cmap("R3")) # outputs a 3-dimensional array
using Images
imgc2 = colorview(RGB, permuteddimsview(imgc, (3,1,2)))

which plots in my terminal using the nice TerminalExtensions package :slight_smile:
image

Cheers!


#6

Wow! -that looks exactly what I want - thanks.

Unfortunately on my system (Linux) with julia version 0.6.1 I get

using PerceptualColourMaps

ERROR: LoadError: LoadError: UndefVarError: AbstractImage not defined
Stacktrace:

and

cmap("R3")

ERROR: UndefVarError: bbspline not defined

Perhaps I need to clone the bleeding edge stuff from Github? Or do I need Julia 0.7.x ?


#7

Yes

Pkg.clone("https://github.com/peterkovesi/PerceptualColourMaps.jl")

and it works! many thanks. RB


#8

@robblackwell consider using Plots.jl if your goal is only plotting a 2D matrix with a custom colormap.

using Plots

heatmap(img, cmap=:inferno)

#9

These are all great suggestions. Just for the record, one other alternative is to use IndirectArrays, which can be used to lazily construct a colormap array. In this case you’d need to convert your Float64 array to an Int array, which you could do in a lazy way with MappedArrays. For example:

using MappedArrays, IndirectArrays

function color_me(A, cmap)
    n = length(cmap)
    f = s->clamp(round(Int, (n-1)*s)+1, 1, n)  # safely convert 0-1 to 1:n
    Ai = mappedarray(f, A)       # like f.(A) but does not allocate significant memory
    IndirectArray(Ai, cmap)      # colormap array
end

(For this to work you have to be running the very latest IndirectArrays.)

In most cases you may find PerceptualColourmap’s applycolormap easier, since it’s already written. Cases there might be reasons to consider IndirectArrays:

  • big data (e.g., >1TB image): the version here allocates essentially no memory and takes essentially no time (you pay only when you access the values, and then only for those values you need)
  • in applications where you’d like to pass the colorized array to a function but also have access to the original values (which you can get with parent(imgc.index)). An example might be a GUI “tooltip hover” application.

Again, these probably don’t matter in most cases. Not only is applycolormap already available, but @peterkovesi’s color maps are so well designed that you should just be using those anyway :slight_smile:.


#10

Interesting. Thanks for taking the time to respond and for all the great work!