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 matplotlib.cm as mtpltcm def main(argv): cap = cv2.VideoCapture(0) while (True): # Capture frame-by-frame ret, frame = cap.read() # 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'): break # When everything done, release the capture cap.release() cv2.destroyAllWindows() if __name__ == '__main__': sys.exit(main(sys.argv))
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 = mpl.cm.jet #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.
blur = cv2.GaussianBlur(gray,(15,15),0)
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.