How to apply/attach a colormap from an image to another image

2,410 views
Skip to first unread message

Matteo

unread,
Jan 28, 2016, 11:14:32 AM1/28/16
to scikit-image
Can something like this (which by the way I can't get to work) be done using scikit-image?
http://stackoverflow.com/questions/3114925/pil-convert-rgb-image-to-a-specific-8-bit-palette


I've done similar things in Matlab before:
but I'd really like to be able to do it in Python.


What I would like to do currently is:
1) Import an RGB image, which would have its own colormap - say this one
for example:
https://upload.wikimedia.org/wikipedia/commons/b/b3/Jupiter_new_hubble_view_above_pole.png

2) convert it to intensity, say like this:

intnst = 0.2989 * rgb[:,0] + 0.5870 * rgb[:,1] + 0.1140 * rgb[:,2] # get the intensity
intensity = np.rint(intnst) # rounds up to nearest integer

 
3) display the intensity color-mapped to the same colours the original RGB had.

Any tips, ideally withrcode or pseudocode would be greatly appreciated.

Thanks,
Matteo

Matteo

unread,
Jan 28, 2016, 11:39:28 AM1/28/16
to scikit-image

I've added a quick example to show where I am at. I would like to display the second image with the colors of the first one.
Matteo
example.PNG

Matthias Bussonnier

unread,
Jan 28, 2016, 2:35:44 PM1/28/16
to scikit-image
Well as was planning on writing a blog post about that, but if you ask. 

I've been playing with converting images from Jet to Viridis, as you can see here:


It's crude, but the basic idea is to use SciPy find the closest point of a colormap from a given pixel.
This can be done efficiently using KDTree of scipy (thanks Nathaniel Smith for hint), which give you a 1-255 value, 
that you can display again using your desired colormap. 

it of course sample the original colormap,so for a more precise result you might want to interpolate the value using the 2/3 closes points of the cmap, and to avoid extra pixel from the main area to be modified, you might want to use skimage connected component and pick the bigger blob. 
This woudl avoid artifact in the example I linked to, that you can see on the brush icon in the toolbar (the original brush color is red), and the close/minimize/maximise buttons that are also partially picked up. 

Is that what you like to do ?

-- 
M

Matteo

unread,
Jan 28, 2016, 3:57:39 PM1/28/16
to scikit-image

Hi Matthias

 

AWESOME!!

This is a great example, thank you, it will come handy pretty soon, if you are going to share it officially, so I'd love to see the blog post about it.

In my current particular case, the problem is that I do not know the colormap of the original img to begin with. Someone from a slack group suggested to convert it to a paletted image format (PNG or GIF) using PIL, then grab the palette shared a solution involving quantization. I asked for their permission to share it in here, I'll keep you posted.

 

 

Back on your example of converting a bad colormap to a good one, I was working on adapting a Matlab tool by Peter Kovesi 

http://peterkovesi.com/projects/colourmaps/index.html


My idea would be to make it into a web app called 'rainbowbot' which would automatically detect bad colormaps either form online images or user uploaded images, and then provide them with tools to either equalize the colormaps or replace with a perceptual version with same hue range, or.....

It is in here 

https://github.com/mycarta/rainbowbot

I am open to suggestions, and offers to collaborate.


Matteo

Joe Kington

unread,
Jan 28, 2016, 4:29:38 PM1/28/16
to scikit-image

Hi Folks,

Matteo, I hope it's alright that I'm chiming in.

I was the one Matteo mentioned on the slack group.  At first I thought Matteo was referring to exactly what you described: Take a colormapped single-band image and unmap/remap the color palette.

However, after farther discussion, it turns out the problem was dealing with "full" 3-band imagery (i.e. true color).  Essentially an image quantization problem.

For that particular use case, it's easier to use/abuse pre-existing image quantization methods in PIL or Pillow.  Of course, you can also roll your own, as well: http://scikit-learn.org/stable/auto_examples/cluster/plot_color_quantization.html

import Image
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors

im
= Image.open('Jupiter_new_hubble_view_above_pole.png')
imnew
= im.convert("P", palette=Image.ADAPTIVE)#, dither=Image.NONE)
data
= np.asarray(imnew)
palette
= imnew.getpalette()

colors
= np.array(palette).reshape(-1, 3) / 255.0
cmap
= mcolors.ListedColormap(colors)

fig
, axes = plt.subplots(nrows=3, figsize=(8, 15))
axes
[0].imshow(im)

for cm, ax in zip(['gray_r', cmap], axes[1:]):
    cax
= ax.imshow(data, cmap=cm)
    fig
.colorbar(cax, ax=ax)

fig
.tight_layout()
plt
.show()


Which produces:



Cheers,
-Joe

Stéfan van der Walt

unread,
Jan 28, 2016, 5:33:41 PM1/28/16
to scikit-image
On Thu, Jan 28, 2016 at 1:29 PM, Joe Kington <joferk...@gmail.com> wrote:
 
I was the one Matteo mentioned on the slack group.  At first I thought Matteo was referring to exactly what you described: Take a colormapped single-band image and unmap/remap the color palette.

In one of the threads here, I read


"""

My idea would be to make it into a web app called 'rainbowbot' which would automatically detect bad colormaps either form online images or user uploaded images, and then provide them with tools to either equalize the colormaps or replace with a perceptual version with same hue range, or.....

It is in here 

https://github.com/mycarta/rainbowbot

I am open to suggestions, and offers to collaborate.
"""

Otherwise, I guess the problem is as simple as:

image = color.rgb2gray(io.imread('image.jpg'))
plt.imshow(image, cmap='viridis')

If it is about turning false color maps into true color maps, that would be hard, given the many mappings out there.

Stéfan

Matthias Bussonnier

unread,
Jan 28, 2016, 9:57:01 PM1/28/16
to scikit-image


Le jeudi 28 janvier 2016 12:57:39 UTC-8, Matteo a écrit :

Hi Matthias

 

AWESOME!!

This is a great example, thank you, it will come handy pretty soon, if you are going to share it officially, so I'd love to see the blog post about it.

In my current particular case, the problem is that I do not know the colormap of the original img to begin with. Someone from a slack group suggested to convert it to a paletted image format (PNG or GIF) using PIL, then grab the palette shared a solution involving quantization. I asked for their permission to share it in here, I'll keep you posted.


Well, knowing the colormap is hard. In particular in the case of your Jupyter image, it is not a colormap, it is an actual many channel image, as the set of pixel is not a line on the RGB space:
(cf not-cmap attached file)

So "finding" the cmap and reversing it is not possible. 

One possibility would be to do a multidimentional regression on the RGB->luminosity dataset, and to project on this line. Basically "reconstructing" a colormap. 
But will inherently loose data. 

That should not even need scikit image, just scikit-learn. 

X = subset(image())
y = luminosity(subset(image))

Pca.fit(..).inverse_transform(luminosity(image)) 

 I'm not familiar enough with scikit learn to do a non-linear fit.

 

Back on your example of converting a bad colormap to a good one, I was working on adapting a Matlab tool by Peter Kovesi 

http://peterkovesi.com/projects/colourmaps/index.html


My idea would be to make it into a web app called 'rainbowbot' which would automatically detect bad colormaps either form online images or user uploaded images, and then provide them with tools to either equalize the colormaps or replace with a perceptual version with same hue range, or.....

It is in here 

https://github.com/mycarta/rainbowbot

I am open to suggestions, and offers to collaborate.


That was exactly my idea too,  but to do a twitter bot you can mention. 
I think the "detecting" from "remapping" should be separate. 

Also personally I think it would be a nice communication stunt to do at the same time matplotlib 2.0 gets out, to start to "viridize" people pictures on twitter by mentioning a bot. 

-- 
M


not-cmap.png

Stéfan van der Walt

unread,
Jan 28, 2016, 9:59:54 PM1/28/16
to scikit-image
On 28 January 2016 at 18:57, Matthias Bussonnier
<bussonnie...@gmail.com> wrote:
> Also personally I think it would be a nice communication stunt to do at the
> same time matplotlib 2.0 gets out, to start to "viridize" people pictures on
> twitter by mentioning a bot.

I look forward to the "I guess you meant to use viridis" posts!

Stéfan

Matteo Niccoli

unread,
Jan 29, 2016, 9:17:04 AM1/29/16
to scikit...@googlegroups.com
First off, thanks Joe

Your code is what I was looking for - AND, it sounds like - the thing to do, unless one wanted to embark in the kind of regression Matthias suggests.

Second, Stéfan, sorry for the confusion about the rainbowbot, that was an aside, I happened to post on both of them at the same time, but really the Jupiter idea was more because I was playing with image size reduction via conversion to intensity and component reduction via PCA, and was wondering how one could compare the quality of the result with the input image, but in color as opposed to in grayscale.

Matthias, I think it would be fun to work together on the rainbowbot idea, and then to send those 'viridize' tweets. I'll send you an email with some ideas.

Cheers,
Matteo


On Thu, Jan 28, 2016 at 3:33 PM, Stéfan van der Walt <ste...@berkeley.edu> wrote:
On Thu, Jan 28, 2016 at 1:29 PM, Joe Kington <joferk...@gmail.com> wrote:
 
I was the one Matteo mentioned on the slack group.  At first I thought Matteo was referring to exactly what you described: Take a colormapped single-band image and unmap/remap the color palette.

In one of the threads here, I read


"""

My idea would be to make it into a web app called 'rainbowbot' which would automatically detect bad colormaps either form online images or user uploaded images, and then provide them with tools to either equalize the colormaps or replace with a perceptual version with same hue range, or.....

It is in here 

https://github.com/mycarta/rainbowbot

I am open to suggestions, and offers to collaborate.
"""
Otherwise, I guess the problem is as simple as:

image = color.rgb2gray(io.imread('image.jpg'))
plt.imshow(image, cmap='viridis')

If it is about turning false color maps into true color maps, that would be hard, given the many mappings out there.

Stéfan

--
You received this message because you are subscribed to a topic in the Google Groups "scikit-image" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/scikit-image/jxD0GTK_8B4/unsubscribe.
To unsubscribe from this group and all its topics, send an email to scikit-image...@googlegroups.com.
To post to this group, send email to scikit...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/scikit-image/CABDkGQm59%2BHikycM3uxJpEw_kcbQF8bCxozivT6Ujm%3DQ57Ke4g%40mail.gmail.com.

For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages