DepthAI Tutorials
DepthAI API References

ON THIS PAGE

  • Thermal Camera
  • Demo
  • Setup
  • Source code
  • Pipeline

Thermal Camera

This example demonstrates using a thermal camera to display raw temperature data with a color map and real-time RGB thermal video. It includes mouse interaction to show the temperature at the cursor, combining data processing, visualization, and user interaction for thermal imaging applications.

Demo

Setup

Please run the install script to download all required dependencies. Please note that this script must be ran from git context, so you have to download the depthai-python repository first and then run the script
Command Line
1git clone https://github.com/luxonis/depthai-python.git
2cd depthai-python/examples
3python3 install_requirements.py
For additional information, please follow the installation guide.

Source code

Python
C++

Python

Python
GitHub
1#!/usr/bin/env python3
2
3import depthai as dai
4import cv2
5import numpy as np
6
7mouseX, mouseY = 0, 0
8
9
10def onMouse(event, x, y, *args):
11    global mouseX, mouseY
12    mouseX = x
13    mouseY = y
14
15
16device = dai.Device()
17pipeline = dai.Pipeline()
18
19# Thermal camera
20thermalCam = pipeline.create(dai.node.Camera)
21thermalCam.setFps(25) # Limit to 25 to match what the sensor can do, capped even if left at default, but warns.
22width, height = -1, -1
23thermalFound = False
24for features in device.getConnectedCameraFeatures():
25    if dai.CameraSensorType.THERMAL in features.supportedTypes:
26        thermalFound = True
27        thermalCam.setBoardSocket(features.socket)
28        width, height = features.width, features.height
29        break
30if not thermalFound:
31    raise RuntimeError("No thermal camera found!")
32thermalCam.setPreviewSize(width, height)
33
34# Output raw: FP16 temperature data (degrees Celsius)
35xoutRaw = pipeline.create(dai.node.XLinkOut)
36xoutRaw.setStreamName("thermal_raw")
37thermalCam.raw.link(xoutRaw.input)
38
39# Output preview,video, isp: RGB or NV12 or YUV420 thermal image.
40xoutImage = pipeline.create(dai.node.XLinkOut)
41xoutImage.setStreamName("image")
42thermalCam.preview.link(xoutImage.input)
43device.startPipeline(pipeline)
44
45qRaw = device.getOutputQueue("thermal_raw", 2, False)
46qImage = device.getOutputQueue("image", 2, False)
47
48
49RAW_WINDOW_NAME = "temperature"
50IMAGE_WINDOW_NAME = "image"
51# Scale 4x and position one next to another
52cv2.namedWindow(RAW_WINDOW_NAME, cv2.WINDOW_NORMAL)
53cv2.namedWindow(IMAGE_WINDOW_NAME, cv2.WINDOW_NORMAL)
54cv2.moveWindow(RAW_WINDOW_NAME, 0, 0)
55cv2.resizeWindow(RAW_WINDOW_NAME, width * 4, height * 4)
56cv2.moveWindow(IMAGE_WINDOW_NAME, width * 4, 0)
57cv2.resizeWindow(IMAGE_WINDOW_NAME, width * 4, height * 4)
58cv2.setMouseCallback(RAW_WINDOW_NAME, onMouse)
59cv2.setMouseCallback(IMAGE_WINDOW_NAME, onMouse)
60
61while True:
62    inRaw = qRaw.get()
63    inImg = qImage.get()
64
65    # Retrieve one point of fp16 data
66    frame = inRaw.getCvFrame().astype(np.float32)
67    colormappedFrame = cv2.normalize(frame, None, 0, 255, cv2.NORM_MINMAX, cv2.CV_8U)
68    colormappedFrame = cv2.applyColorMap(colormappedFrame, cv2.COLORMAP_MAGMA)
69    if (
70        mouseX < 0
71        or mouseY < 0
72        or mouseX >= frame.shape[1]
73        or mouseY >= frame.shape[0]
74    ):
75        mouseX = max(0, min(mouseX, frame.shape[1] - 1))
76        mouseY = max(0, min(mouseY, frame.shape[0] - 1))
77    textColor = (255, 255, 255)
78    # Draw crosshair
79    cv2.line(
80        colormappedFrame,
81        (mouseX - 10, mouseY),
82        (mouseX + 10, mouseY),
83        textColor,
84        1,
85    )
86    cv2.line(
87        colormappedFrame,
88        (mouseX, mouseY - 10),
89        (mouseX, mouseY + 10),
90        textColor,
91        1,
92    )
93    # Draw deg C
94    text = f"{frame[mouseY, mouseX]:.2f} deg C"
95    putTextLeft = mouseX > colormappedFrame.shape[1] / 2
96    cv2.putText(
97        colormappedFrame,
98        text,
99        (mouseX - 100 if putTextLeft else mouseX + 10, mouseY - 10),
100        cv2.FONT_HERSHEY_SIMPLEX,
101        0.5,
102        textColor,
103        1,
104    )
105    cv2.imshow(RAW_WINDOW_NAME, colormappedFrame)
106
107    cv2.imshow(IMAGE_WINDOW_NAME, inImg.getCvFrame())
108
109    if cv2.waitKey(1) == ord("q"):
110        break

Pipeline

Need assistance?

Head over to Discussion Forum for technical support or any other questions you might have.