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

On Thursday, January 28, 2016 at 2:57:39 PM UTC-6, Matteo wrote:

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

On Thursday, January 28, 2016 at 12:35:44 PM UTC-7, Matthias Bussonnier wrote:
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



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

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

On Thursday, January 28, 2016 at 9:14:32 AM UTC-7, Matteo wrote:
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