xref: /aosp_15_r20/external/armnn/samples/ObjectDetection/src/ImageUtils.cpp (revision 89c4ff92f2867872bb9e2354d150bf0c8c502810)
1 //
2 // Copyright © 2020 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 #include "ImageUtils.hpp"
7 #include "BoundingBox.hpp"
8 #include "Types.hpp"
9 
10 #include <armnn/Logging.hpp>
11 
GetScalarColorCode(std::tuple<int,int,int> color)12 static cv::Scalar GetScalarColorCode(std::tuple<int, int, int> color)
13 {
14     return cv::Scalar(std::get<0>(color), std::get<1>(color), std::get<2>(color));
15 }
16 
AddInferenceOutputToFrame(od::DetectedObjects & decodedResults,cv::Mat & inputFrame,std::vector<std::tuple<std::string,common::BBoxColor>> & labels)17 void AddInferenceOutputToFrame(od::DetectedObjects& decodedResults, cv::Mat& inputFrame,
18                                std::vector<std::tuple<std::string, common::BBoxColor>>& labels)
19 {
20     for(const od::DetectedObject& object : decodedResults)
21     {
22         int confidence = static_cast<int>(object.GetScore() * 100);
23         int baseline = 0;
24         std::string textStr;
25         std::tuple<int, int, int> colorCode(255, 0, 0); //red
26 
27         if (labels.size() > object.GetId())
28         {
29             auto label = labels[object.GetId()];
30             textStr = std::get<0>(label) + " - " + std::to_string(confidence) + "%";
31             colorCode = std::get<1>(label).colorCode;
32         }
33         else
34         {
35             textStr = std::to_string(object.GetId()) + " - " + std::to_string(confidence) + "%";
36         }
37 
38         cv::Size textSize = getTextSize(textStr, cv::FONT_HERSHEY_DUPLEX, 1.0, 1, &baseline);
39 
40         const od::BoundingBox& bbox = object.GetBoundingBox();
41 
42         if (bbox.GetX() + bbox.GetWidth() > inputFrame.cols)
43         {
44             cv::Rect r(bbox.GetX(), bbox.GetY(), inputFrame.cols - bbox.GetX(), bbox.GetHeight());
45 
46             cv::rectangle(inputFrame, r, GetScalarColorCode(colorCode), 2, 8, 0);
47         }
48         else if (bbox.GetY() + bbox.GetHeight() > inputFrame.rows)
49         {
50             cv::Rect r(bbox.GetX(), bbox.GetY(), bbox.GetWidth(), inputFrame.rows - bbox.GetY());
51 
52             cv::rectangle(inputFrame, r, GetScalarColorCode(colorCode), 2, 8, 0);
53         }
54         else
55         {
56             cv::Rect r(bbox.GetX(), bbox.GetY(), bbox.GetWidth(), bbox.GetHeight());
57 
58             cv::rectangle(inputFrame, r, GetScalarColorCode(colorCode), 2, 8, 0);
59         }
60 
61         int textBoxY = std::max(0 ,bbox.GetY() - textSize.height);
62 
63         cv::Rect text(bbox.GetX(), textBoxY, textSize.width, textSize.height);
64 
65         cv::rectangle(inputFrame, text, GetScalarColorCode(colorCode), -1);
66 
67         cv::Scalar color;
68 
69         if(std::get<0>(colorCode) + std::get<1>(colorCode) + std::get<2>(colorCode) > 127)
70         {
71             color = cv::Scalar::all(0);
72         }
73         else
74         {
75             color = cv::Scalar::all(255);
76         }
77 
78         cv::putText(inputFrame,
79                     textStr ,
80                     cv::Point(bbox.GetX(), textBoxY + textSize.height -(textSize.height)/3),
81                     cv::FONT_HERSHEY_DUPLEX,
82                     0.5,
83                     color,
84                     1);
85     }
86 }
87 
88 
ResizeFrame(const cv::Mat & frame,cv::Mat & dest,const common::Size & aspectRatio)89 void ResizeFrame(const cv::Mat& frame, cv::Mat& dest, const common::Size& aspectRatio)
90 {
91     if(&dest != &frame)
92     {
93         double longEdgeInput = std::max(frame.rows, frame.cols);
94         double longEdgeOutput = std::max(aspectRatio.m_Width, aspectRatio.m_Height);
95         const double resizeFactor = longEdgeOutput/longEdgeInput;
96         cv::resize(frame, dest, cv::Size(0, 0), resizeFactor, resizeFactor, DefaultResizeFlag);
97     }
98     else
99     {
100         const std::string warningMessage{"Resize was not performed because resized frame references the source frame."};
101         ARMNN_LOG(warning) << warningMessage;
102     }
103 }
104 
105 /** Pad a frame with zeros (add rows and columns to the end) */
PadFrame(const cv::Mat & src,cv::Mat & dest,const int bottom,const int right)106 void PadFrame(const cv::Mat& src, cv::Mat& dest, const int bottom, const int right)
107 {
108     if(&dest != &src)
109     {
110         cv::copyMakeBorder(src, dest, 0, bottom, 0, right, cv::BORDER_CONSTANT);
111     }
112     else
113     {
114         const std::string warningMessage
115         {
116             "Pad was not performed because destination frame references the source frame."
117         };
118         ARMNN_LOG(warning) << warningMessage;
119     }
120 }
121 
ResizeWithPad(const cv::Mat & frame,cv::Mat & dest,cv::Mat & cache,const common::Size & destSize)122 void ResizeWithPad(const cv::Mat& frame, cv::Mat& dest, cv::Mat& cache, const common::Size& destSize)
123 {
124     ResizeFrame(frame, cache, destSize);
125     PadFrame(cache, dest,destSize.m_Height - cache.rows,destSize.m_Width - cache.cols);
126 }
127