Creating fake thermal images using Python

I'm have recently finished my master thesis about FPGA implementations of various image fusion algorithms for fusing thermographic images and normal visual light images. Unfortunately thermographic cameras are quite expensive and complicated to handle so I thought of a way to create fake thermal images from a normal webcam feed.

At the chair we are using Python and OpenCV to test the image processing algorithms. Using a webcam is also really easy in Python so lets begin from this basic example:

import sys
import numpy as np
import cv2
import matplotlib as mpl
import as mtpltcm

def main(argv):
    cap = cv2.VideoCapture(0)

    while (True):
        # Capture frame-by-frame
        ret, frame =

        # Our operations on the frame come here
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

        # Display the resulting frame
        cv2.imshow('frame', colors)
        if cv2.waitKey(1) & 0xFF == ord('q'):

    # When everything done, release the capture

if __name__ == '__main__':

Your webcam (index 0) will be opened and the resulting frames will be desaturated so you will get a grayscale image. For me this image looks like the following.

Now lets simply add one of the matplotlib colormaps to the grayscale image to generate the IR effect:

    #initialize the colormap (jet)
    colormap =
    #add a normalization
    cNorm = mpl.colors.Normalize(vmin=0, vmax=255)
    #init the mapping
    scalarMap = mtpltcm.ScalarMappable(norm=cNorm, cmap=colormap)
        #in the main display loop:
        colors = scalarMap.to_rgba(gray)
        cv2.imshow('frame', colors)

This is the result of this first approach.

Now there is still too much structure in the resulting image so I added some gaussian blur to make it more realistic:
blur = cv2.GaussianBlur(gray,(15,15),0)

I think the result is OK for testing purposes now but the colormap jet should not be used anymore since it is not sequential. So using the cool/viridis_r colormap we get the following results which are also quite nice.

This all depends heavily on the lightning conditions in the room. My face, hair, t-shirt and the door mostly consists of darker colors (so less intensity in the grayscale image). Since my body is usually warmer than the room I want the darker colors to be mapped to the higher temperatures. Fortunately the matplotlip colormaps also come with a inverted mode (just append _r to the end of the colormaps name). Also try changing the parameters vmin and vmax to get a more dynamic colormap.

Please find the full code for this article here.

Leave Comment: