# How does the math behind heat map filters work?

I am working on an app that generates heat/ thermal map given a picture. i have been able to get what i expected using python opencv builtin function cv2.applyColorMap(img, cv2.COLORMAP_JET). Everything works exactly as expected. But i want to understand how applyColorMap works at the back end. I am aware how several image filters (like image, edge filters) work by convolution / cross correlation with appropriate kernals, but i can't seem to pull the same concept for color maps. For this question lets consider a color map where we want :

Brightest ones: (RED COLORED)

MEDIUM INTENSITY ONES: (YELLOW COLORED)

LOW INTENSITY ONES: (BLUE COLORED)

What i have done:

I tried dividing the pixels into 3 categories and replaced each pixel with the either of the colors (RED, YELLOW, BLUE ) depending upon it's value from gray scale image( 0-255). This approach had a problem that there were solid 3 colors in the image with no variation in intensity of the individual color while in a good heat map there is blend of colors ( it decreases or increases ) based upon the intensity . I want to achieve that effect. I would appreciate any help or any lead to understand how heat maps work .

About your question concerning ColorMaps: A cv2 ColorMap is basically just a lookup table which directly maps the intensity values of the input image to a predefined RGB color. In its essences it is exactly what you did by categorizing and associating with a specific color value.

Most of the cv2 ColorMaps just have a little more detail, most of them have either 64( "Rainbow", "Hot", ...) or 256 ("Jet", "Magma", ...) steps, some like "Winter" have 11. They come from the GNU Octave or Matlab color palettes.

If you really want to build this lookup table yourself the easiest way to achieve a high level of granularity for the individual steps is to use the HSV color space

import numpy as np
import cv2

N_STEPS = 20
h = np.linspace(0, 180, N_STEPS, endpoint=False) # cv2 Hue range is [0, 179]
s = np.ones_like(h)*255   # cv2 saturation range is from [0, 255]; adjust it to your liking
v = np.ones_like(h)*255   # cv2 value range is from [0, 255]; adjust it to your liking
hsv_colormap = np.dstack([h,s,v])

rgb_colormap = cv2.cvtColor(np.uint8(hsv_colormap), cv2.COLOR_HSV2RGB)

IMG_SIZE = 100
#intensities = np.random.random((IMG_SIZE,IMG_SIZE)) # from 0 to 1
intensities = np.array([np.linspace(0,1, IMG_SIZE, endpoint=False), ]*IMG_SIZE) # from 0 to 1
intensity_indices = np.uint8(N_STEPS*intensities) # map insity ranges to discretized intervals

color_mapped_intensities = rgb_colormap[0,intensity_indices,:]
cv2.imshow('colormap', color_mapped_intensities)

cv2.waitKey(0)


you can play around with the Hue values ranges to feed into the color map

Happy color mapping to you !