thermal_cam.cpp
Go to the documentation of this file.
1 /*
2  Thermal camera example.
3  Streams temperature and thermal image from thermal sensor and displays them.
4 */
5 #include <algorithm>
6 #include <cstdio>
7 
8 #include "depthai/depthai.hpp"
9 
10 volatile int mouseX, mouseY = 0;
11 void mouseCallback(int event, int x, int y, int flags, void* userdata) {
12  mouseX = x;
13  mouseY = y;
14 }
15 
16 const cv::Scalar WHITE(255, 255, 255);
17 
18 int main() {
19  dai::Device d;
20  dai::Pipeline pipeline;
21  auto thermal = pipeline.create<dai::node::Camera>();
22  // Find the sensor width, height.
23  int width, height;
24  bool thermal_found = false;
25  for(auto& features : d.getConnectedCameraFeatures()) {
26  if(std::find_if(features.supportedTypes.begin(),
27  features.supportedTypes.end(),
28  [](const dai::CameraSensorType& type) { return type == dai::CameraSensorType::THERMAL; })
29  != features.supportedTypes.end()) {
30  thermal->setBoardSocket(features.socket); // Thermal will always be on CAM_E
31  width = features.width;
32  height = features.height;
33  thermal_found = true;
34  }
35  }
36  if(!thermal_found) {
37  throw std::runtime_error("Thermal camera not found!");
38  }
39  thermal->setPreviewSize(width, height);
40  auto xlink = pipeline.create<dai::node::XLinkOut>();
41  auto xlinkRaw = pipeline.create<dai::node::XLinkOut>();
42  // Output preview,video, isp: RGB or NV12 or YUV420 thermal image.
43  thermal->preview.link(xlink->input);
44  // Output raw: FP16 temperature data (degrees Celsius)
45  thermal->raw.link(xlinkRaw->input);
46 
47  xlinkRaw->setStreamName("thermal_raw");
48  xlink->setStreamName("thermal");
49  d.startPipeline(pipeline);
50  auto q = d.getOutputQueue("thermal", 2, false);
51  auto qRaw = d.getOutputQueue("thermal_raw", 2, false);
52 
53  const char* tempWindow = "temperature";
54  const char* imageWindow = "image";
55  cv::namedWindow(tempWindow, cv::WINDOW_NORMAL);
56  cv::setMouseCallback(tempWindow, mouseCallback);
57  cv::namedWindow(imageWindow, cv::WINDOW_NORMAL);
58  cv::setMouseCallback(imageWindow, mouseCallback);
59  // Scale 4x and position one next to another
60  cv::moveWindow(tempWindow, 0, 0);
61  cv::resizeWindow(tempWindow, width * 4, height * 4);
62  cv::moveWindow(imageWindow, width * 4, 0);
63  cv::resizeWindow(imageWindow, width * 4, height * 4);
64  while(true) {
65  auto temp = qRaw->tryGet<dai::ImgFrame>();
66  if(temp) {
67  auto frame = temp->getCvFrame();
68  // Retrieve one point of fp16 data
69  cv::Mat frameFp32(temp->getHeight(), temp->getWidth(), CV_32F);
70  frame.convertTo(frameFp32, CV_32F);
71  cv::Mat normalized;
72  cv::normalize(frameFp32, normalized, 0, 255, cv::NORM_MINMAX, CV_8UC1);
73  cv::Mat colormapped(temp->getHeight(), temp->getWidth(), CV_8UC3);
74  cv::applyColorMap(normalized, colormapped, cv::COLORMAP_MAGMA);
75  if(mouseX < 0 || mouseY < 0 || mouseX >= colormapped.cols || mouseY >= colormapped.rows) {
76  mouseX = std::max(0, std::min(static_cast<int>(mouseX), colormapped.cols - 1));
77  mouseY = std::max(0, std::min(static_cast<int>(mouseY), colormapped.rows - 1));
78  }
79  double min, max;
80  cv::minMaxLoc(frameFp32, &min, &max);
81  auto textColor = WHITE;
82  // Draw crosshair
83  cv::line(colormapped, cv::Point(mouseX - 10, mouseY), cv::Point(mouseX + 10, mouseY), textColor, 1);
84  cv::line(colormapped, cv::Point(mouseX, mouseY - 10), cv::Point(mouseX, mouseY + 10), textColor, 1);
85  // Draw deg C
86  char text[32];
87  snprintf(text, sizeof(text), "%.1f deg C", frameFp32.at<float>(mouseY, mouseX));
88  bool putTextLeft = mouseX > colormapped.cols / 2;
89  cv::putText(colormapped, text, cv::Point(putTextLeft ? mouseX - 100 : mouseX + 10, mouseY - 10), cv::FONT_HERSHEY_SIMPLEX, 0.5, textColor, 1);
90  cv::imshow(tempWindow, colormapped);
91  }
92  auto image = q->tryGet<dai::ImgFrame>();
93  if(image) {
94  cv::imshow(imageWindow, image->getCvFrame());
95  }
96  int key = cv::waitKey(1);
97  if(key == 'q') {
98  break;
99  }
100  }
101 
102  return 0;
103 }
mouseY
volatile int mouseY
Definition: thermal_cam.cpp:10
dai::DeviceBase::startPipeline
bool startPipeline()
Definition: DeviceBase.cpp:1511
dai::node::XLinkOut
XLinkOut node. Sends messages over XLink.
Definition: XLinkOut.hpp:14
dai::Pipeline
Represents the pipeline, set of nodes and connections between them.
Definition: Pipeline.hpp:100
dai::node::Camera::setBoardSocket
void setBoardSocket(CameraBoardSocket boardSocket)
Definition: Camera.cpp:35
dai::CameraSensorType
CameraSensorType
Camera sensor type.
Definition: shared/depthai-shared/include/depthai-shared/common/CameraSensorType.hpp:8
mouseX
volatile int mouseX
Definition: thermal_cam.cpp:10
WHITE
const cv::Scalar WHITE(255, 255, 255)
dai::DeviceBase::getConnectedCameraFeatures
std::vector< CameraFeatures > getConnectedCameraFeatures()
Definition: DeviceBase.cpp:1109
dai::Device::getOutputQueue
std::shared_ptr< DataOutputQueue > getOutputQueue(const std::string &name)
Definition: Device.cpp:86
dai::node::XLinkOut::input
Input input
Definition: XLinkOut.hpp:27
depthai.hpp
main
int main()
Definition: thermal_cam.cpp:18
dai::Pipeline::create
std::shared_ptr< N > create()
Definition: Pipeline.hpp:145
dai::ImgFrame::getCvFrame
void getCvFrame(T...)
Definition: ImgFrame.hpp:222
dai::ImgFrame
Definition: ImgFrame.hpp:25
nanorpc::core::detail::pack::meta::type
type
Definition: pack_meta.h:26
dai::Device
Definition: Device.hpp:21
dai::node::XLinkOut::setStreamName
void setStreamName(const std::string &name)
Definition: XLinkOut.cpp:13
mouseCallback
void mouseCallback(int event, int x, int y, int flags, void *userdata)
Definition: thermal_cam.cpp:11
dai::node::Camera
Camera node. Experimental node, for both mono and color types of sensors.
Definition: Camera.hpp:18


depthai
Author(s): Martin Peterlin
autogenerated on Sat Mar 22 2025 02:58:19