plugin  0.1.0
classification_grid_mat.hpp
1 // Copyright (C) 2018-2024 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 //
4 
5 #pragma once
6 
7 #include <algorithm>
8 #include <queue>
9 #include <set>
10 #include <string>
11 #include <vector>
12 
13 #include <opencv2/core.hpp>
14 #include <opencv2/imgproc.hpp>
15 
16 #include <monitors/presenter.h>
17 #include <utils/ocv_common.hpp>
18 
20 
21 enum class PredictionResult { Correct, Incorrect, Unknown };
22 
24 public:
25  cv::Mat outImg;
26 
27  explicit ClassificationGridMat(Presenter& presenter,
28  const cv::Size maxDisp = cv::Size{1920, 1080},
29  const cv::Size aspectRatio = cv::Size{16, 9},
30  double targetFPS = 60)
31  : currSourceId{0} {
32  cv::Size size(static_cast<int>(std::round(sqrt(1. * targetFPS * aspectRatio.width / aspectRatio.height))),
33  static_cast<int>(std::round(sqrt(1. * targetFPS * aspectRatio.height / aspectRatio.width))));
34  if (size.width == 0 || size.height == 0) {
35  size = {1, 1}; // set minimum possible grid size
36  }
37  int minCellSize = std::min(maxDisp.width / size.width, maxDisp.height / size.height);
38  cellSize = cv::Size(minCellSize, minCellSize);
39 
40  for (int i = 0; i < size.height; i++) {
41  for (int j = 0; j < size.width; j++) {
42  points.emplace_back(cellSize.width * j, presenter.graphSize.height + cellSize.height * i);
43  }
44  }
45 
46  outImg.create((cellSize.height * size.height) + presenter.graphSize.height,
47  cellSize.width * size.width,
48  CV_8UC3);
49  outImg.setTo(0);
50 
51  textSize = cv::getTextSize("", fontType, fontScale, thickness, &baseline);
52  accuracyMessageSize = cv::getTextSize("Accuracy (top 0): 0.000", fontType, fontScale, thickness, &baseline);
53  testMessageSize = cv::getTextSize(ClassificationGridMat::testMessage, fontType, fontScale, thickness, &baseline);
54  }
55 
56  void textUpdate(PerformanceMetrics& metrics,
57  PerformanceMetrics::TimePoint lastRequestStartTime,
58  double accuracy,
59  unsigned int nTop,
60  bool isFpsTest,
61  bool showAccuracy,
62  Presenter& presenter) {
63  rectangle(outImg, {0, 0}, {outImg.cols, presenter.graphSize.height}, cv::Scalar(0, 0, 0), cv::FILLED);
64 
65  presenter.drawGraphs(outImg);
66 
67  metrics.update(lastRequestStartTime,
68  outImg,
69  cv::Point(textPadding, textSize.height + textPadding),
70  fontType,
71  fontScale,
72  cv::Scalar(255, 100, 100),
73  thickness);
74 
75  if (showAccuracy) {
76  cv::putText(outImg,
77  cv::format("Accuracy (top %d): %.3f", nTop, accuracy),
78  cv::Point(outImg.cols - accuracyMessageSize.width - textPadding, textSize.height + textPadding),
79  fontType,
80  fontScale,
81  cv::Scalar(255, 255, 255),
82  thickness);
83  }
84 
85  if (isFpsTest) {
86  cv::putText(
87  outImg,
88  ClassificationGridMat::testMessage,
89  cv::Point(outImg.cols - testMessageSize.width - textPadding, (textSize.height + textPadding) * 2),
90  fontType,
91  fontScale,
92  cv::Scalar(50, 50, 255),
93  thickness);
94  }
95  }
96 
97  void updateMat(const cv::Mat& mat, const std::string& label, PredictionResult predictionResul) {
98  if (!prevImg.empty()) {
99  size_t prevSourceId = currSourceId - 1;
100  prevSourceId = std::min(prevSourceId, points.size() - 1);
101  prevImg.copyTo(outImg(cv::Rect(points[prevSourceId], cellSize)));
102  }
103  cv::Scalar textColor;
104  switch (predictionResul) {
105  case PredictionResult::Correct:
106  textColor = cv::Scalar(75, 255, 75); // green
107  break;
108  case PredictionResult::Incorrect:
109  textColor = cv::Scalar(50, 50, 255); // red
110  break;
111  case PredictionResult::Unknown:
112  textColor = cv::Scalar(200, 10, 10); // blue
113  break;
114  default:
115  throw std::runtime_error("Undefined type of prediction result");
116  }
117  int labelThickness = cellSize.width / 20;
118  cv::Size labelTextSize = cv::getTextSize(label, fontType, 1, 2, &baseline);
119  double labelFontScale = static_cast<double>(cellSize.width - 2 * labelThickness) / labelTextSize.width;
120  cv::resize(mat, prevImg, cellSize);
121  putHighlightedText(prevImg,
122  label,
123  cv::Point(labelThickness, cellSize.height - labelThickness - labelTextSize.height),
124  fontType,
125  labelFontScale,
126  textColor,
127  2);
128  cv::Mat cell = outImg(cv::Rect(points[currSourceId], cellSize));
129  prevImg.copyTo(cell);
130  cv::rectangle(cell, {0, 0}, {cell.cols, cell.rows}, {255, 50, 50}, labelThickness); // draw a border
131 
132  if (currSourceId == points.size() - 1) {
133  currSourceId = 0;
134  } else {
135  currSourceId++;
136  }
137  }
138 
139 private:
140  cv::Mat prevImg;
141  cv::Size cellSize;
142  size_t currSourceId;
143  std::vector<cv::Point> points;
144  static const int fontType = cv::FONT_HERSHEY_PLAIN;
145  static constexpr double fontScale = 1.5;
146  static const int thickness = 2;
147  static const int textPadding = 10;
148  static constexpr const char testMessage[] = "Testing, please wait...";
149  int baseline;
150  cv::Size textSize;
151  cv::Size accuracyMessageSize;
152  cv::Size testMessageSize;
153 };
154 
155 constexpr const char ClassificationGridMat::testMessage[];
Definition: classification_grid_mat.hpp:23
Definition: performance_metrics.hpp:19
Definition: presenter.h:19
a header file with common samples functionality using OpenCV
void putHighlightedText(const cv::Mat &frame, const std::string &message, cv::Point position, int fontFace, double fontScale, cv::Scalar color, int thickness)
Puts text message on the frame, highlights the text with a white border to make it distinguishable fr...
Definition: ocv_common.hpp:200
a header file for performance metrics calculation class