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 scriptCommand Line
1git clone https://github.com/luxonis/depthai-python.git
2cd depthai-python/examples
3python3 install_requirements.py
Source code
Python
C++
Python
PythonGitHub
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.