Hotspot.cpp 2.17 KB
#include "Hotspot.hpp"

#include <opencv2/imgproc.hpp>

Cpu::Hotspot::Hotspot(const cv::Mat &temperature, unsigned long timestamp,
                      int component, const Contour &contour,
                      const Surface &surface)
    : Hotspot(temperature, timestamp, component, contour, surface,
              createMask(temperature.size(), contour)) {}

Cpu::Hotspot::Hotspot(const cv::Mat &temperature, unsigned long timestamp,
                      int component, const Contour &contour,
                      const Surface &surface, const cv::Mat &mask)
    : timestamp(timestamp), component(component), contour(contour), mask(mask),
	  /* Compute hotspot attributes */
      meanTemperature(calculateMean(temperature)),
      maxTemperature(calculateMax(temperature)), size(calculateSize()),
      surface(surface) {}

double Cpu::Hotspot::perimeter() const {
	double perimeter = 0;

	for (std::size_t i = 0, size = surface.size(); i < size; ++i) {
		perimeter += cv::norm(surface[i] - surface[(i + 1) % size]);
	}

	return perimeter;
}

int Cpu::Hotspot::calculateSize() const { return cv::countNonZero(mask); }

double Cpu::Hotspot::calculateMean(const cv::Mat &temperature) const {
	return cv::mean(temperature, mask)[0];
}

double Cpu::Hotspot::calculateMax(const cv::Mat &temperature) const {
	double maxValue{-1};
	cv::minMaxIdx(temperature, nullptr, &maxValue, nullptr, nullptr, mask);
	return maxValue;
}

cv::Mat Cpu::Hotspot::createMask(const cv::Size &size, const Contour &contour) {
	cv::Mat result(cv::Mat::zeros(size, CV_8UC1));
	cv::drawContours(result, std::vector<Contour>{contour}, -1, 255,
	                 cv::FILLED);

	return result;
}

Cpu::PersistentHotspot::PersistentHotspot(const Hotspot &initial)
    : mask(initial.mask), component(initial.component) {
	append(initial);
}

void Cpu::PersistentHotspot::merge(const Hotspot &other) {
	cv::bitwise_or(mask, other.mask, mask);
	append(other);
}

int Cpu::PersistentHotspot::area() const { return cv::countNonZero(mask); }

void Cpu::PersistentHotspot::append(const Hotspot &other) {
	timestamps.push_back(other.timestamp);
	meanTemperatures.push_back(other.meanTemperature);
	maxTemperatures.push_back(other.maxTemperature);
}