Face Engine SDK
5.25.0
A face detection, recognition and tracking engine.
|
00001 #pragma once 00002 00003 #include <fsdk/Types/Vector2.h> 00004 00005 namespace fsdk { 00008 template <typename Type> 00009 struct BaseRect { 00010 typedef Type ElementType; 00011 00012 Type x; 00013 Type y; 00014 Type width; 00015 Type height; 00016 00019 BaseRect() noexcept 00020 : x(0) 00021 , y(0) 00022 , width(0) 00023 , height(0) { 00024 } 00025 00032 BaseRect(Type x_, Type y_, Type w_, Type h_) noexcept 00033 : x(x_) 00034 , y(y_) 00035 , width(w_) 00036 , height(h_) { 00037 } 00038 00043 BaseRect(const Vector2<Type>& topLeft, const Vector2<Type>& bottomRight) noexcept { 00044 set(topLeft, bottomRight); 00045 } 00046 00050 BaseRect(const BaseRect& other) noexcept { 00051 *this = other; 00052 } 00053 00054 template <typename OtherType> 00055 BaseRect(const BaseRect<OtherType>& other) noexcept { 00056 *this = other; 00057 } 00058 00061 void setLeft(Type l) noexcept { 00062 const auto r = right(); 00063 x = l; 00064 setRight(r); 00065 } 00066 00069 void setTop(Type t) noexcept { 00070 const auto b = bottom(); 00071 y = t; 00072 setBottom(b); 00073 } 00074 00077 void setRight(Type r) noexcept { 00078 width = r - x; 00079 } 00080 00083 void setBottom(Type b) noexcept { 00084 height = b - y; 00085 } 00086 00093 static BaseRect coords(Type x0, Type y0, Type x1, Type y1) noexcept { 00094 return BaseRect(x0, y0, x1 - x0, y1 - y0); 00095 } 00096 00102 static float intersectionOverFirstRect(const BaseRect& rect1, const BaseRect& rect2) { 00103 const float inter = (rect1 & rect2).getArea(); 00104 return inter / rect1.getArea(); 00105 } 00106 00112 static float intersectionOverUnion(const BaseRect& rect1, const BaseRect& rect2) { 00113 const float inter = (rect1 & rect2).getArea(); 00114 return inter / (rect1.getArea() + rect2.getArea() - inter); 00115 } 00116 00122 static float intersectionOverForeground(const BaseRect& rect1, const BaseRect& rect2) { 00123 if(rect1.getArea() < rect2.getArea()) { 00124 return intersectionOverFirstRect(rect1, rect2); 00125 } 00126 return intersectionOverFirstRect(rect2, rect1); 00127 } 00128 00133 template <typename OtherType> 00134 BaseRect& operator=(const BaseRect<OtherType>& other) noexcept { 00135 if(reinterpret_cast<const void*>(this) != reinterpret_cast<const void*>(&other)) { 00136 x = static_cast<Type>(other.x); 00137 y = static_cast<Type>(other.y); 00138 width = static_cast<Type>(other.width); 00139 height = static_cast<Type>(other.height); 00140 } 00141 return *this; 00142 } 00143 00148 template <typename OtherType> 00149 bool operator==(const BaseRect<OtherType>& other) const noexcept { 00150 return x == other.x && y == other.y && width == other.width && height == other.height; 00151 } 00152 00157 template <typename OtherType> 00158 bool operator!=(const BaseRect<OtherType>& other) const noexcept { 00159 return !(*this == other); 00160 } 00161 00166 BaseRect operator&(const BaseRect& other) const noexcept { 00167 BaseRect newRect; 00168 newRect.x = x > other.x ? x : other.x; 00169 newRect.y = y > other.y ? y : other.y; 00170 newRect.width = (x + width < other.x + other.width ? x + width : other.x + other.width) - newRect.x; 00171 newRect.height = 00172 (y + height < other.y + other.height ? y + height : other.y + other.height) - newRect.y; 00173 if(newRect.width <= 0 || newRect.height <= 0) 00174 newRect = BaseRect(); 00175 return newRect; 00176 } 00177 00182 BaseRect operator&=(const BaseRect& other) noexcept { 00183 if(this != &other) 00184 *this = *this & other; 00185 00186 return *this; 00187 } 00188 00193 BaseRect operator|(const BaseRect& other) const noexcept { 00194 BaseRect newRect; 00195 newRect.x = x < other.x ? x : other.x; 00196 newRect.y = y < other.y ? y : other.y; 00197 newRect.width = (x + width > other.x + other.width ? x + width : other.x + other.width) - newRect.x; 00198 newRect.height = 00199 (y + height > other.y + other.height ? y + height : other.y + other.height) - newRect.y; 00200 00201 return newRect; 00202 } 00203 00208 BaseRect operator|=(const BaseRect& other) noexcept { 00209 if(this != &other) 00210 *this = *this & other; 00211 00212 return *this; 00213 } 00214 00219 BaseRect operator*(float scaleFactor) const noexcept { 00220 BaseRect newRect; 00221 newRect.x = static_cast<Type>(x * scaleFactor); 00222 newRect.y = static_cast<Type>(y * scaleFactor); 00223 newRect.width = static_cast<Type>(width * scaleFactor); 00224 newRect.height = static_cast<Type>(height * scaleFactor); 00225 00226 return newRect; 00227 } 00228 00233 BaseRect operator/(float scaleFactor) const noexcept { 00234 BaseRect newRect; 00235 newRect.x = static_cast<Type>(x / scaleFactor); 00236 newRect.y = static_cast<Type>(y / scaleFactor); 00237 newRect.width = static_cast<Type>(width / scaleFactor); 00238 newRect.height = static_cast<Type>(height / scaleFactor); 00239 00240 return newRect; 00241 } 00242 00243 BaseRect operator+(Vector2<typename BaseRect::ElementType> vec) { 00244 BaseRect newRect = *this; 00245 newRect.x += vec.x; 00246 newRect.y += vec.y; 00247 00248 return newRect; 00249 } 00250 00251 BaseRect operator-(Vector2<typename BaseRect::ElementType> vec) { 00252 BaseRect newRect = *this; 00253 newRect.x -= vec.x; 00254 newRect.y -= vec.y; 00255 00256 return newRect; 00257 } 00258 00262 Vector2<Type> size() const noexcept { 00263 return Vector2<Type>(width, height); 00264 } 00265 00269 Vector2<Type> topLeft() const noexcept { 00270 return Vector2<Type>(x, y); 00271 } 00272 00276 Vector2<Type> center() const noexcept { 00277 return Vector2<Type>(x + width / 2, y + height / 2); 00278 } 00279 00283 Vector2<Type> bottomRight() const noexcept { 00284 return Vector2<Type>(x + width, y + height); 00285 } 00286 00290 Type top() const noexcept { 00291 return y; 00292 } 00293 00297 Type bottom() const noexcept { 00298 return y + height; 00299 } 00300 00304 Type left() const noexcept { 00305 return x; 00306 } 00307 00311 Type right() const noexcept { 00312 return x + width; 00313 } 00314 00319 void set(const Vector2<Type>& topLeft, const Vector2<Type>& bottomRight) noexcept { 00320 x = topLeft.x; 00321 y = topLeft.y; 00322 width = bottomRight.x - x; 00323 height = bottomRight.y - y; 00324 } 00325 00332 void adjust(Type dx, Type dy, Type dw, Type dh) noexcept { 00333 x += dx; 00334 y += dy; 00335 width += dw; 00336 height += dh; 00337 } 00338 00346 BaseRect adjusted(Type dx, Type dy, Type dw, Type dh) const noexcept { 00347 BaseRect rect(*this); 00348 rect.adjust(dx, dy, dw, dh); 00349 return rect; 00350 } 00351 00355 Type getArea() const noexcept { 00356 return width * height; 00357 } 00358 00363 bool inside(const BaseRect& other) const noexcept { 00364 return topLeft() >= other.topLeft() && bottomRight() <= other.bottomRight(); 00365 } 00366 00372 bool isValid() const noexcept { 00373 return width > 0 && height > 0; 00374 } 00375 }; 00376 00382 template <typename Type> 00383 BaseRect<Type> centerScale(const BaseRect<Type>& in, float scaleFactor) noexcept { 00384 BaseRect<Type> out; 00385 out.x = in.x - 0.5 * (scaleFactor - 1) * in.width; 00386 out.y = in.y - 0.5 * (scaleFactor - 1) * in.height; 00387 out.width = in.width * scaleFactor; 00388 out.height = in.height * scaleFactor; 00389 return out; 00390 } 00391 00392 using Rect = BaseRect<int>; 00393 using FloatRect = BaseRect<float>; 00394 } // namespace fsdk