diff --git a/cmake/Depthai/DepthaiDeviceSideConfig.cmake b/cmake/Depthai/DepthaiDeviceSideConfig.cmake index e55c24d3a..45508a27e 100644 --- a/cmake/Depthai/DepthaiDeviceSideConfig.cmake +++ b/cmake/Depthai/DepthaiDeviceSideConfig.cmake @@ -2,7 +2,7 @@ set(DEPTHAI_DEVICE_SIDE_MATURITY "snapshot") # "full commit hash of device side binary" -set(DEPTHAI_DEVICE_SIDE_COMMIT "9a26c8a19c1dbd741f10c7dce498561f4843db48") +set(DEPTHAI_DEVICE_SIDE_COMMIT "d86f2efa04753e0e47c153db678753afa9a630a0") # "version if applicable" set(DEPTHAI_DEVICE_SIDE_VERSION "") diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 606ab29ff..a1f7e61ee 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -230,6 +230,9 @@ dai_add_example(rgb_preview ColorCamera/rgb_preview.cpp ON) dai_add_example(rgb_video ColorCamera/rgb_video.cpp ON) dai_add_example(rgb_isp_scale ColorCamera/rgb_isp_scale.cpp ON) +# Camera +dai_add_example(thermal_cam Camera/thermal_cam.cpp OFF) + # EdgeDetector dai_add_example(edge_detector EdgeDetector/edge_detector.cpp ON) diff --git a/examples/Camera/thermal_cam.cpp b/examples/Camera/thermal_cam.cpp new file mode 100644 index 000000000..8178655e8 --- /dev/null +++ b/examples/Camera/thermal_cam.cpp @@ -0,0 +1,102 @@ +/* + Thermal camera example. + Streams temperature and thermal image from thermal sensor and displays them. +*/ +#include +#include + +#include "depthai/depthai.hpp" + +volatile int mouseX, mouseY = 0; +void mouseCallback(int event, int x, int y, int flags, void* userdata) { + mouseX = x; + mouseY = y; +} + +const cv::Scalar WHITE(255, 255, 255); + +int main() { + dai::Device d; + dai::Pipeline pipeline; + auto thermal = pipeline.create(); + // Find the sensor width, height. + int width, height; + bool thermal_found = false; + for (auto &features : d.getConnectedCameraFeatures()) { + if (std::find_if(features.supportedTypes.begin(), features.supportedTypes.end(), [](const dai::CameraSensorType &type) { + return type == dai::CameraSensorType::THERMAL; + }) != features.supportedTypes.end()) { + thermal->setBoardSocket(features.socket); // Thermal will always be on CAM_E + width = features.width; + height = features.height; + thermal_found = true; + } + } + if (!thermal_found) { + throw std::runtime_error("Thermal camera not found!"); + } + thermal->setPreviewSize(width, height); + auto xlink = pipeline.create(); + auto xlinkRaw = pipeline.create(); + // Output preview,video, isp: RGB or NV12 or YUV420 thermal image. + thermal->preview.link(xlink->input); + // Output raw: FP16 temperature data (degrees Celsius) + thermal->raw.link(xlinkRaw->input); + + xlinkRaw->setStreamName("thermal_raw"); + xlink->setStreamName("thermal"); + d.startPipeline(pipeline); + auto q = d.getOutputQueue("thermal", 2, false); + auto qRaw = d.getOutputQueue("thermal_raw", 2, false); + + const char* tempWindow = "temperature"; + const char* imageWindow = "image"; + cv::namedWindow(tempWindow, cv::WINDOW_NORMAL); + cv::setMouseCallback(tempWindow, mouseCallback); + cv::namedWindow(imageWindow, cv::WINDOW_NORMAL); + cv::setMouseCallback(imageWindow, mouseCallback); + // Scale 4x and position one next to another + cv::moveWindow(tempWindow, 0, 0); + cv::resizeWindow(tempWindow, width * 4, height * 4); + cv::moveWindow(imageWindow, width * 4, 0); + cv::resizeWindow(imageWindow, width * 4, height * 4); + while(true) { + auto temp = qRaw->tryGet(); + if(temp) { + auto frame = temp->getCvFrame(); + // Retrieve one point of fp16 data + cv::Mat frameFp32(temp->getHeight(), temp->getWidth(), CV_32F); + frame.convertTo(frameFp32, CV_32F); + cv::Mat normalized; + cv::normalize(frameFp32, normalized, 0, 255, cv::NORM_MINMAX, CV_8UC1); + cv::Mat colormapped(temp->getHeight(), temp->getWidth(), CV_8UC3); + cv::applyColorMap(normalized, colormapped, cv::COLORMAP_MAGMA); + if(mouseX < 0 || mouseY < 0 || mouseX >= colormapped.cols || mouseY >= colormapped.rows) { + mouseX = std::max(0, std::min(static_cast(mouseX), colormapped.cols - 1)); + mouseY = std::max(0, std::min(static_cast(mouseY), colormapped.rows - 1)); + } + double min, max; + cv::minMaxLoc(frameFp32, &min, &max); + auto textColor = WHITE; + // Draw crosshair + cv::line(colormapped, cv::Point(mouseX - 10, mouseY), cv::Point(mouseX + 10, mouseY), textColor, 1); + cv::line(colormapped, cv::Point(mouseX, mouseY - 10), cv::Point(mouseX, mouseY + 10), textColor, 1); + // Draw deg C + char text[32]; + snprintf(text, sizeof(text), "%.1f deg C", frameFp32.at(mouseY, mouseX)); + bool putTextLeft = mouseX > colormapped.cols / 2; + cv::putText(colormapped, text, cv::Point(putTextLeft ? mouseX - 100 : mouseX + 10, mouseY - 10), cv::FONT_HERSHEY_SIMPLEX, 0.5, textColor, 1); + cv::imshow(tempWindow, colormapped); + } + auto image = q->tryGet(); + if(image) { + cv::imshow(imageWindow, image->getCvFrame()); + } + int key = cv::waitKey(1); + if(key == 'q') { + break; + } + } + + return 0; +} diff --git a/shared/depthai-shared b/shared/depthai-shared index 084fd0f4c..147468b12 160000 --- a/shared/depthai-shared +++ b/shared/depthai-shared @@ -1 +1 @@ -Subproject commit 084fd0f4cab84830a26b36e07d5a6b31e6c1adf6 +Subproject commit 147468b124b3c30e40f69239e3560afca782ba6b