I am trying to create a really simple colourmap using RGB triples. That has a discrete number of colours.
Here is the shape that I am trying to make it follow:
I know it is probably not a true RGB spectrum, but i wanted it to be as easy to compute as possible.
I want to be able to generate an array of N 8-bit RGB tuples that are evenly spaced along the line.
For easy instances where all of the points in the image above fall on colours, it is easy to generate using numpy.linspace()
using the following code:
import numpy as np
# number of discrete colours
N = 9
# generate R array
R = np.zeros(N).astype(np.uint8)
R[:int(N/4)] = 255
R[int(N/4):int(2*N/4)+1] = np.linspace(255,0,num=(N/4)+1,endpoint=True)
# generate G array
G = 255*np.ones(N).astype(np.uint8)
G[0:int(N/4)+1] = np.linspace(0,255,num=(N/4)+1,endpoint=True)
G[int(3*N/4):] = np.linspace(255,0,num=(N/4)+1,endpoint=True)
# generate B array
B = np.zeros(N).astype(np.uint8)
B[int(2*N/4):int(3*N/4)+1] = np.linspace(0,255,num=(N/4)+1,endpoint=True)
B[int(3*N/4)+1:] = 255
# stack arrays
RGB = np.dstack((R,G,B))[0]
This code works fine for 5 colours:
r 255 255 0 0 0
g 0 255 255 255 0
b 0 0 0 255 255
9 colours:
r 255 255 255 127 0 0 0 0 0
g 0 127 255 255 255 255 255 127 0
b 0 0 0 0 0 127 255 255 255
13 colours:
r 255 255 255 255 170 85 0 0 0 0 0 0 0
g 0 85 170 255 255 255 255 255 255 255 170 85 0
b 0 0 0 0 0 0 0 85 170 255 255 255 255
etc.. but I'm having trouble working out how to make it work for an arbitrary N number of colours because the linspace trick only works if it is going from one endpoint to another.
Can someone please help me with working out how to do it? Any ideas for how to make my code above more efficient would be great as well, I am just learning how to use numpy after putting it off for ages..
Here is one reasonably convenient method using np.clip
:
def spec(N):
t = np.linspace(-510, 510, N)
return np.round(np.clip(np.stack([-t, 510-np.abs(t), t], axis=1), 0, 255)).astype(np.uint8)
It avoids the problem you describe by only relying on the only two points that are guaranteed to be on the grid for any N which are the first and last points.
Examples:
>>> spec(5)
array([[255, 0, 0],
[255, 255, 0],
[ 0, 255, 0],
[ 0, 255, 255],
[ 0, 0, 255]], dtype=uint8)
>>> spec(10)
array([[255, 0, 0],
[255, 113, 0],
[255, 227, 0],
[170, 255, 0],
[ 57, 255, 0],
[ 0, 255, 57],
[ 0, 255, 170],
[ 0, 227, 255],
[ 0, 113, 255],
[ 0, 0, 255]], dtype=uint8)
If you just want RGB at given levels, the diagram that you have posted itself serves as the answer -
R = [255] * 256
R.extend(list(reversed(range(256))))
R.extend([0] * 256)
R.extend([0] * 256)
G = list(range(256))
G.extend([255] * 256)
G.extend([255] * 256)
G.extend(list(reversed(range(256))))
B = [0] * 256
B.extend([0] * 256)
B.extend(list(range(256)))
B.extend([255] * 256)
level = 5
step = 1024 // (level -1)
print(R[::step])
print(G[::step])
print(B[::step])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With