Files
ANSCORE/engines/OpenVINOEngine/include/utils/classification_grid_mat.hpp

156 lines
5.9 KiB
C++

// Copyright (C) 2018-2024 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#pragma once
#include <algorithm>
#include <queue>
#include <set>
#include <string>
#include <vector>
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <monitors/presenter.h>
#include <utils/ocv_common.hpp>
#include "utils/performance_metrics.hpp"
enum class PredictionResult { Correct, Incorrect, Unknown };
class ClassificationGridMat {
public:
cv::Mat outImg;
explicit ClassificationGridMat(Presenter& presenter,
const cv::Size maxDisp = cv::Size{1920, 1080},
const cv::Size aspectRatio = cv::Size{16, 9},
double targetFPS = 60)
: currSourceId{0} {
cv::Size size(static_cast<int>(std::round(sqrt(1. * targetFPS * aspectRatio.width / aspectRatio.height))),
static_cast<int>(std::round(sqrt(1. * targetFPS * aspectRatio.height / aspectRatio.width))));
if (size.width == 0 || size.height == 0) {
size = {1, 1}; // set minimum possible grid size
}
int minCellSize = std::min(maxDisp.width / size.width, maxDisp.height / size.height);
cellSize = cv::Size(minCellSize, minCellSize);
for (int i = 0; i < size.height; i++) {
for (int j = 0; j < size.width; j++) {
points.emplace_back(cellSize.width * j, presenter.graphSize.height + cellSize.height * i);
}
}
outImg.create((cellSize.height * size.height) + presenter.graphSize.height,
cellSize.width * size.width,
CV_8UC3);
outImg.setTo(0);
textSize = cv::getTextSize("", fontType, fontScale, thickness, &baseline);
accuracyMessageSize = cv::getTextSize("Accuracy (top 0): 0.000", fontType, fontScale, thickness, &baseline);
testMessageSize = cv::getTextSize(ClassificationGridMat::testMessage, fontType, fontScale, thickness, &baseline);
}
void textUpdate(PerformanceMetrics& metrics,
PerformanceMetrics::TimePoint lastRequestStartTime,
double accuracy,
unsigned int nTop,
bool isFpsTest,
bool showAccuracy,
Presenter& presenter) {
rectangle(outImg, {0, 0}, {outImg.cols, presenter.graphSize.height}, cv::Scalar(0, 0, 0), cv::FILLED);
presenter.drawGraphs(outImg);
metrics.update(lastRequestStartTime,
outImg,
cv::Point(textPadding, textSize.height + textPadding),
fontType,
fontScale,
cv::Scalar(255, 100, 100),
thickness);
if (showAccuracy) {
cv::putText(outImg,
cv::format("Accuracy (top %d): %.3f", nTop, accuracy),
cv::Point(outImg.cols - accuracyMessageSize.width - textPadding, textSize.height + textPadding),
fontType,
fontScale,
cv::Scalar(255, 255, 255),
thickness);
}
if (isFpsTest) {
cv::putText(
outImg,
ClassificationGridMat::testMessage,
cv::Point(outImg.cols - testMessageSize.width - textPadding, (textSize.height + textPadding) * 2),
fontType,
fontScale,
cv::Scalar(50, 50, 255),
thickness);
}
}
void updateMat(const cv::Mat& mat, const std::string& label, PredictionResult predictionResul) {
if (!prevImg.empty()) {
size_t prevSourceId = currSourceId - 1;
prevSourceId = std::min(prevSourceId, points.size() - 1);
prevImg.copyTo(outImg(cv::Rect(points[prevSourceId], cellSize)));
}
cv::Scalar textColor;
switch (predictionResul) {
case PredictionResult::Correct:
textColor = cv::Scalar(75, 255, 75); // green
break;
case PredictionResult::Incorrect:
textColor = cv::Scalar(50, 50, 255); // red
break;
case PredictionResult::Unknown:
textColor = cv::Scalar(200, 10, 10); // blue
break;
default:
throw std::runtime_error("Undefined type of prediction result");
}
int labelThickness = cellSize.width / 20;
cv::Size labelTextSize = cv::getTextSize(label, fontType, 1, 2, &baseline);
double labelFontScale = static_cast<double>(cellSize.width - 2 * labelThickness) / labelTextSize.width;
cv::resize(mat, prevImg, cellSize);
putHighlightedText(prevImg,
label,
cv::Point(labelThickness, cellSize.height - labelThickness - labelTextSize.height),
fontType,
labelFontScale,
textColor,
2);
cv::Mat cell = outImg(cv::Rect(points[currSourceId], cellSize));
prevImg.copyTo(cell);
cv::rectangle(cell, {0, 0}, {cell.cols, cell.rows}, {255, 50, 50}, labelThickness); // draw a border
if (currSourceId == points.size() - 1) {
currSourceId = 0;
} else {
currSourceId++;
}
}
private:
cv::Mat prevImg;
cv::Size cellSize;
size_t currSourceId;
std::vector<cv::Point> points;
static const int fontType = cv::FONT_HERSHEY_PLAIN;
static constexpr double fontScale = 1.5;
static const int thickness = 2;
static const int textPadding = 10;
static constexpr const char testMessage[] = "Testing, please wait...";
int baseline;
cv::Size textSize;
cv::Size accuracyMessageSize;
cv::Size testMessageSize;
};
constexpr const char ClassificationGridMat::testMessage[];