xref: /aosp_15_r20/external/armnn/samples/ObjectDetection/src/BoundingBox.cpp (revision 89c4ff92f2867872bb9e2354d150bf0c8c502810)
1 //
2 // Copyright © 2020 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 #include "BoundingBox.hpp"
7 #include <algorithm>
8 namespace od
9 {
10 
BoundingBox()11 BoundingBox::BoundingBox() :
12         BoundingBox(0, 0, 0u, 0u) {}
13 
BoundingBox(int x,int y,unsigned int width,unsigned int height)14 BoundingBox::BoundingBox(
15         int x,
16         int y,
17         unsigned int width,
18         unsigned int height) :
19         m_X(x),
20         m_Y(y),
21         m_Width(width),
22         m_Height(height) {}
23 
BoundingBox(const BoundingBox & other)24 BoundingBox::BoundingBox(const BoundingBox& other) :
25         m_X(other.m_X),
26         m_Y(other.m_Y),
27         m_Width(other.m_Width),
28         m_Height(other.m_Height) {}
29 
GetX() const30 int BoundingBox::GetX() const {
31     return m_X;
32 }
33 
GetY() const34 int BoundingBox::GetY() const {
35     return m_Y;
36 }
37 
GetWidth() const38 unsigned int BoundingBox::GetWidth() const {
39     return m_Width;
40 }
41 
GetHeight() const42 unsigned int BoundingBox::GetHeight() const {
43     return m_Height;
44 }
45 
SetX(int x)46 void BoundingBox::SetX(int x) {
47     m_X = x;
48 }
49 
SetY(int y)50 void BoundingBox::SetY(int y) {
51     m_Y = y;
52 }
53 
SetWidth(unsigned int width)54 void BoundingBox::SetWidth(unsigned int width) {
55     m_Width = width;
56 }
57 
SetHeight(unsigned int height)58 void BoundingBox::SetHeight(unsigned int height) {
59     m_Height = height;
60 }
61 
operator =(const BoundingBox & other)62 BoundingBox& BoundingBox::operator=(const BoundingBox& other) {
63     m_X = other.m_X;
64     m_Y = other.m_Y;
65 
66     m_Width = other.m_Width;
67     m_Height = other.m_Height;
68 
69     return *this;
70 }
71 
72 /* Helper function to get a "valid" bounding box */
GetValidBoundingBox(const BoundingBox & boxIn,BoundingBox & boxOut,const BoundingBox & boxLimits)73 void GetValidBoundingBox(const BoundingBox& boxIn, BoundingBox& boxOut,
74                          const BoundingBox& boxLimits) {
75     boxOut.SetX(std::max(boxIn.GetX(), boxLimits.GetX()));
76     boxOut.SetY(std::max(boxIn.GetY(), boxLimits.GetY()));
77 
78     /* If we have changed x and/or y, we compensate by reducing the height and/or width */
79     int boxOutWidth = static_cast<int>(boxIn.GetWidth()) -
80                       std::max(0, (boxOut.GetX() - boxIn.GetX()));
81     int boxOutHeight = static_cast<int>(boxIn.GetHeight()) -
82                        std::max(0, (boxOut.GetY() - boxIn.GetY()));
83 
84     /* This suggests that there was no overlap on x or/and y axis */
85     if (boxOutHeight <= 0 || boxOutWidth <= 0)
86     {
87         boxOut = BoundingBox{0, 0, 0, 0};
88         return;
89     }
90 
91     const int limitBoxRightX = boxLimits.GetX() + static_cast<int>(boxLimits.GetWidth());
92     const int limitBoxRightY = boxLimits.GetY() + static_cast<int>(boxLimits.GetHeight());
93     const int boxRightX = boxOut.GetX() + boxOutWidth;
94     const int boxRightY = boxOut.GetY() + boxOutHeight;
95 
96     if (boxRightX > limitBoxRightX)
97     {
98         boxOutWidth -= (boxRightX - limitBoxRightX);
99     }
100 
101     if (boxRightY > limitBoxRightY)
102     {
103         boxOutHeight -= (boxRightY - limitBoxRightY);
104     }
105 
106     /* This suggests value has rolled over because of very high numbers, not handled for now */
107     if (boxOutHeight <= 0 || boxOutWidth <= 0)
108     {
109         boxOut = BoundingBox{0, 0, 0, 0};
110         return;
111     }
112 
113     boxOut.SetHeight(static_cast<unsigned int>(boxOutHeight));
114     boxOut.SetWidth(static_cast<unsigned int>(boxOutWidth));
115 }
116 }// namespace od