Thermal Crosshair
The example uses DepthAI to process and display thermal camera data, showing a colorized temperature map and raw thermal image side-by-side, with a mouse-controlled crosshair displaying real-time temperature readings in degrees Celsius.Setup
This example requires the DepthAI v3 API, see installation instructions.Demo

Pipeline
Source code
Python
C++
Python
PythonGitHub
1import depthai as dai
2import cv2
3import numpy as np
4
5mouseX, mouseY = 0, 0
6
7
8def onMouse(event, x, y, *args):
9 global mouseX, mouseY
10 mouseX = x
11 mouseY = y
12
13
14# Thermal camera
15
16with dai.Pipeline(True) as pipeline:
17 thermal = pipeline.create(dai.node.Thermal)
18 # Output raw: FP16 temperature data (degrees Celsius)
19 qTemperature = thermal.temperature.createOutputQueue()
20 # Output color: YUV422i image data
21 qColor = thermal.color.createOutputQueue()
22 pipeline.start()
23 MAGMA_WINDOW_NAME = "Colorized Temperature"
24 IMAGE_WINDOW_NAME = "Thermal image"
25 # Scale 4x and position one next to another
26 cv2.namedWindow(MAGMA_WINDOW_NAME, cv2.WINDOW_NORMAL)
27 cv2.namedWindow(IMAGE_WINDOW_NAME, cv2.WINDOW_NORMAL)
28 initialRescaleAndPositionDone = False
29
30 while True:
31 inTemperature = qTemperature.get()
32 inColor = qColor.get()
33
34 thermalData = (
35 inTemperature.getData()
36 .view(dtype=np.float16)
37 .reshape((inTemperature.getHeight(), inTemperature.getWidth()))
38 .astype(np.float32)
39 )
40 normalizedThermalData = cv2.normalize(thermalData, None, 0, 1, cv2.NORM_MINMAX)
41 normalizedThermalData = (normalizedThermalData * 255).astype(np.uint8)
42 colormappedFrame = cv2.applyColorMap(normalizedThermalData, cv2.COLORMAP_MAGMA)
43 if not initialRescaleAndPositionDone:
44 cv2.moveWindow(MAGMA_WINDOW_NAME, 0, 0)
45 width, height = colormappedFrame.shape[1], colormappedFrame.shape[0]
46 cv2.resizeWindow(MAGMA_WINDOW_NAME, width * 4, height * 4)
47 cv2.moveWindow(IMAGE_WINDOW_NAME, width * 4, 0)
48 cv2.resizeWindow(IMAGE_WINDOW_NAME, width * 4, height * 4)
49 cv2.setMouseCallback(MAGMA_WINDOW_NAME, onMouse)
50 cv2.setMouseCallback(IMAGE_WINDOW_NAME, onMouse)
51 initialRescaleAndPositionDone = True
52 colormappedFrame = cv2.applyColorMap(colormappedFrame, cv2.COLORMAP_MAGMA)
53 if (
54 mouseX < 0
55 or mouseY < 0
56 or mouseX >= thermalData.shape[1]
57 or mouseY >= thermalData.shape[0]
58 ):
59 mouseX = max(0, min(mouseX, thermalData.shape[1] - 1))
60 mouseY = max(0, min(mouseY, thermalData.shape[0] - 1))
61 textColor = (255, 255, 255)
62 # Draw crosshair
63 cv2.line(
64 colormappedFrame,
65 (mouseX - 10, mouseY),
66 (mouseX + 10, mouseY),
67 textColor,
68 1,
69 )
70 cv2.line(
71 colormappedFrame,
72 (mouseX, mouseY - 10),
73 (mouseX, mouseY + 10),
74 textColor,
75 1,
76 )
77 # Draw deg C
78 text = f"{thermalData[mouseY, mouseX]:.2f} deg C"
79 putTextLeft = mouseX > colormappedFrame.shape[1] / 2
80 cv2.putText(
81 colormappedFrame,
82 text,
83 (mouseX - 100 if putTextLeft else mouseX + 10, mouseY - 10),
84 cv2.FONT_HERSHEY_SIMPLEX,
85 0.5,
86 textColor,
87 1,
88 )
89
90 cv2.imshow(MAGMA_WINDOW_NAME, colormappedFrame)
91 cv2.imshow(IMAGE_WINDOW_NAME, inColor.getCvFrame())
92
93 if cv2.waitKey(1) == ord("q"):
94 break
Need assistance?
Head over to Discussion Forum for technical support or any other questions you might have.