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

#include <opencv2/imgproc.hpp>

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

Hotspot::Hotspot(const cv::cuda::GpuMat &temperature, unsigned long timestamp,
                 int component, const Contour &contour, const Surface &surface,
                 const cv::cuda::GpuMat &mask)
    : timestamp(timestamp), component(component), contour(contour), mask(mask),
      surface(surface) {
	/* Compute hotspot attributes */
	cv::cuda::countNonZero(mask, nonZeroDevice, nonZeroStream);
	nonZeroDevice.download(nonZeroHost, nonZeroStream);

	cv::cuda::calcSum(temperature, sumDevice, mask, sumStream);
	sumDevice.download(sumHost, sumStream);

	cv::cuda::findMinMax(temperature, minMaxDevice, mask, minMaxStream);
	minMaxDevice.download(minMaxHost, minMaxStream);

	nonZeroStream.waitForCompletion();
	size = nonZeroHost.at<int>(0);
	sumStream.waitForCompletion();
	meanTemperature = sumHost.at<double>(0) / size;
	minMaxStream.waitForCompletion();
	maxTemperature = minMaxHost.at<int>(1);
}

double 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;
}

cv::cuda::GpuMat 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 cv::cuda::GpuMat{result};
}

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

void PersistentHotspot::merge(const Hotspot &other) {
	cv::cuda::bitwise_or(mask, other.mask, mask, cv::noArray(), stream);
	append(other);
	stream.waitForCompletion();
}

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

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