Home > Net >  Write my own image function that takes a greyscale (0-255) to a r,g,b, alpha heat map
Write my own image function that takes a greyscale (0-255) to a r,g,b, alpha heat map

Time:06-07

I have a 300*500 image. It's is in grayscale and ranges from 0-255. I want to iterate value by value and apply a heat map (say viridis but it doesn't matter) to each value.

My final heatmap image is in Red, Blue, Green and Alpha. I imagine the specific heat map function would take the grayscale values and output three values for each Red, Blue, Green and their appropriate weights.

f(0-255) = weightr(Red), weightb(Blue), weightg(Green).

My ending image would have dimensions (300,500,4) The four channels are r,b,g and an alpha channel.

What is the function that would achieve this? Almost certain it's going to be highly dependent on the specific heat map. Viridis is what I'm after, but I want to understand the concept as well.

The code below reads in a random image (the fact it's from unsplash does not matter) and turns it into a (300,500), 0-255 image called imgarray. I know matplotlib defaults to viridis, but I included the extra step to show what I would like to achieve with my own function.

import matplotlib.pyplot as plt
import requests
from PIL import Image
from io import BytesIO

img_src = 'https://unsplash.it/500/300'
response = requests.get(img_src)
imgarray = Image.open(BytesIO(response.content))
imgarray = np.asarray(imgarray.convert('L'))
from matplotlib import cm
print(cm.viridis(imgarray))
plt.imshow(cm.viridis(imgarray))

CodePudding user response:

Matplotlib defines the viridis colormap as 256 RGB colors (one for each 8 bit gray scale value), where each color channel is a floating point value from [0, 1]. The definition can be found on Viridis colormap applied

The actual magic happens in the np.take(a, indices) method, which takes values from array a (the viridis LUT) at the given indices (gray scale values from 0..255 from the image). To get the same result as from the cm.viridis function, we just need to add an alpha channel (full of 1. = full opacity).

For reference, the same conversion happens around here in the matplotlib source code.

  • Related