此页面由 AI 自动翻译。查看英文原版
DepthAI
  • DepthAI 组件
    • AprilTags
    • 基准测试
    • Camera
    • 校准
    • DetectionNetwork
    • Events
    • FeatureTracker
    • Gate
    • HostNodes
    • ImageAlign
    • ImageManip
    • IMU
    • 杂项
    • 模型动物园
    • NeuralDepth
    • NeuralNetwork
    • ObjectTracker
    • 点云
    • RecordReplay
    • RGBD
    • Script
    • SpatialDetectionNetwork
    • SpatialLocationCalculator
    • StereoDepth
    • Sync
    • VideoEncoder
    • Visualizer
    • Warp
    • RVC2-specific
  • 高级教程
  • API 参考
  • 工具
软件栈

本页目录

  • 演示
  • 管道
  • 源代码

热成像十字准星

Supported on:RVC2
该示例使用 DepthAI 处理和显示热成像相机数据,并排显示彩色温度图和原始热成像图像,鼠标控制的十字准星显示摄氏度的实时温度读数。此示例需要 DepthAI v3 API,请参阅 安装说明

演示

热成像相机演示

管道

源代码

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

C++

1#include <iostream>
2#include <opencv2/opencv.hpp>
3
4#include "depthai/depthai.hpp"
5
6volatile int mouseX = 0, mouseY = 0;
7
8void onMouse(int event, int x, int y, int flags, void* userdata) {
9    mouseX = x;
10    mouseY = y;
11}
12
13int main() {
14    // Create pipeline
15    dai::Pipeline pipeline(true);
16
17    // Create nodes
18    auto thermal = pipeline.create<dai::node::Thermal>();
19    // Output raw: FP16 temperature data (degrees Celsius)
20    auto qTemperature = thermal->temperature.createOutputQueue();
21    // Output color: YUV422i image data
22    auto qColor = thermal->color.createOutputQueue();
23
24    // Start pipeline
25    pipeline.start();
26
27    const char* MAGMA_WINDOW_NAME = "Colorized Temperature";
28    const char* IMAGE_WINDOW_NAME = "Thermal image";
29
30    // Scale 4x and position one next to another
31    cv::namedWindow(MAGMA_WINDOW_NAME, cv::WINDOW_NORMAL);
32    cv::namedWindow(IMAGE_WINDOW_NAME, cv::WINDOW_NORMAL);
33    bool initialRescaleAndPositionDone = false;
34
35    while(true) {
36        auto inTemperature = qTemperature->get<dai::ImgFrame>();
37        auto inColor = qColor->get<dai::ImgFrame>();
38
39        // temperature data is float16: convert it to float32
40        cv::Mat thermalData(inTemperature->getHeight(), inTemperature->getWidth(), CV_32F);
41        inTemperature->getCvFrame().convertTo(thermalData, CV_32F);
42
43        // Normalize thermal data
44        cv::Mat normalizedThermalData;
45        cv::normalize(thermalData, normalizedThermalData, 0, 1, cv::NORM_MINMAX);
46        normalizedThermalData.convertTo(normalizedThermalData, CV_8U, 255.0);
47
48        // Apply color map
49        cv::Mat colormappedFrame;
50        cv::applyColorMap(normalizedThermalData, colormappedFrame, cv::COLORMAP_MAGMA);
51
52        if(!initialRescaleAndPositionDone) {
53            cv::moveWindow(MAGMA_WINDOW_NAME, 0, 0);
54            int width = colormappedFrame.cols;
55            int height = colormappedFrame.rows;
56            cv::resizeWindow(MAGMA_WINDOW_NAME, width * 4, height * 4);
57            cv::moveWindow(IMAGE_WINDOW_NAME, width * 4, 0);
58            cv::resizeWindow(IMAGE_WINDOW_NAME, width * 4, height * 4);
59            cv::setMouseCallback(MAGMA_WINDOW_NAME, onMouse);
60            cv::setMouseCallback(IMAGE_WINDOW_NAME, onMouse);
61            initialRescaleAndPositionDone = true;
62        }
63
64        // Clamp mouse coordinates
65        mouseX = std::max(0, std::min(static_cast<int>(mouseX), thermalData.cols - 1));
66        mouseY = std::max(0, std::min(static_cast<int>(mouseY), thermalData.rows - 1));
67
68        // Draw crosshair
69        cv::Scalar textColor(255, 255, 255);
70        cv::line(colormappedFrame, cv::Point(mouseX - 10, mouseY), cv::Point(mouseX + 10, mouseY), textColor, 1);
71        cv::line(colormappedFrame, cv::Point(mouseX, mouseY - 10), cv::Point(mouseX, mouseY + 10), textColor, 1);
72
73        // Draw temperature text
74        std::string text = std::to_string(thermalData.at<float>(mouseY, mouseX)) + " deg C";
75        bool putTextLeft = mouseX > colormappedFrame.cols / 2;
76        cv::putText(colormappedFrame, text, cv::Point(mouseX - (putTextLeft ? 100 : -10), mouseY - 10), cv::FONT_HERSHEY_SIMPLEX, 0.5, textColor, 1);
77
78        cv::imshow(MAGMA_WINDOW_NAME, colormappedFrame);
79        cv::imshow(IMAGE_WINDOW_NAME, inColor->getCvFrame());
80
81        if(cv::waitKey(1) == 'q') {
82            break;
83        }
84    }
85
86    return 0;
87}

需要帮助?

请前往 Discussion Forum 获取技术支持或提出您可能有的任何其他问题。