2

I have been given a segmentation mask: a HxW numpy array in which each location represents a pixel. The value at each location is not RGB, however; it is an arbitrary integer in the range 0-60, where the integer is simply a code representing a type of image content.

E.g. array locations whose value is 12 indicate pixels categorized as 'table'; locations whose value is 34 indicate pixels categorized as 'carpet'.

I want to load this segmentation mask into a canvas using tkinter, so I need to make an image out of it, and I need each of the values 0-60 to correspond to colors whose hues are as distinct as can be.

How do I choose these colors? How do I convert my HxW array into an RGB image?

1
  • you shouldn't need to convert to rgb. simply visualise your array via pcolor using a custom colormap Commented Nov 27, 2018 at 22:01

2 Answers 2

3

You don't need to convert to RGB. Just use pcolor with an appropriate colormap.

It could be something as simple as this:

import matplotlib.pyplot as plt
import numpy

M = numpy.array([[1,2,3,4,5,6,7,8,9,10], [11,12,13,14,15,16,17,18,19,20]])
plt.pcolor( M , cmap = 'hsv' )
plt.show()

Added by Mark Setchell:

Sign up to request clarification or add additional context in comments.

3 Comments

It would be helpful to show how that looks and also to explain how to make that into something OP can load into a TkInter canvas. I hope you don't mind my adding the plot - just delete it if you do.
@MarkSetchell ah apologies, I missed the tkinter bit, thanks for pointing it out. I haven't done it in a while, but effectively, one can use a matplotlib object in a tkinter gui, e.g. as in this post: stackoverflow.com/q/4073660/4183191 Again, there would be no need to convert to RGB, just use the resulting figure in the tkinter gui.
I had to use pcolormesh instead of pcolor because the former was too slow
2

IMHO, the obvious thing to do would be to make a palettised image where you have a palette of 60 colours and an index into the palette at each location. That is very simple with PIL/Pillow.

Now you come to choosing those 60 colours. I would think of using HSL (Hue, Saturation and Lightness) colourspace. Now you need 60 different values. So you could use full Saturation and Lightness for all pixels and spread the available 360 degrees of Hue into 6 degree chunks for 60 colours. Or you could use 100% Lightness and 50% Lightness plus 100% Saturation and 50% Saturation to give you 4x as many Lightness/Saturation combinations meaning you could rotate 24 degrees of Hue for greater separation.

See here for example of how to make an image from a Numpy array, add a palette to an image and make into Pillow image and save.

I am basically suggesting a 60-entry palette, with the following values:

Hue, Saturation, Lightness
0    50%         50%
0    50%         100%
0    100%        50%
0    100%        100%
23   50%         50%
23   50%         100%
23   100%        50%
23   100%        100%
47   50%         50%
47   50%         100%
47   100%        50%
47   100%        100%
61   ...

1 Comment

I like this method, but I'm having scant luck. I'm trying the toy example Image.fromarray([[0,1,2,3,4]], mode='P') and am getting a single, solid color which matches the first color in my palette.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.