Software Stack
DepthAI
  • DepthAI Components
    • AprilTags
    • Benchmark
    • Camera
    • DetectionNetwork
    • EdgeDetector
    • Events
    • FeatureTracker
    • HostNodes
    • ImageAlign
    • ImageManip
    • IMU
    • Misc
    • Modelzoo
    • NeuralNetwork
    • RecordReplay
    • RGBD
    • Script
    • SpatialDetectionNetwork
    • SpatialLocationCalculator
    • StereoDepth
    • Sync
    • SystemLogger
    • VideoEncoder
    • Visualizer
    • Warp
    • RVC2-specific
  • Advanced Tutorials
  • API Reference
  • Tools

ON THIS PAGE

  • Thermal Crosshair
  • Setup
  • Demo
  • Pipeline
  • Source code

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

Python
GitHub
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.