summaryrefslogtreecommitdiff
path: root/megapixels/app/models/bbox.py
diff options
context:
space:
mode:
authorAdam Harvey <adam@ahprojects.com>2018-12-23 01:37:03 +0100
committerAdam Harvey <adam@ahprojects.com>2018-12-23 01:37:03 +0100
commit4452e02e8b04f3476273574a875bb60cfbb4568b (patch)
tree3ffa44f9621b736250a8b94da14a187dc785c2fe /megapixels/app/models/bbox.py
parent2a65f7a157bd4bace970cef73529867b0e0a374d (diff)
parent5340bee951c18910fd764241945f1f136b5a22b4 (diff)
.
Diffstat (limited to 'megapixels/app/models/bbox.py')
-rw-r--r--megapixels/app/models/bbox.py82
1 files changed, 60 insertions, 22 deletions
diff --git a/megapixels/app/models/bbox.py b/megapixels/app/models/bbox.py
index 41b67416..55a92512 100644
--- a/megapixels/app/models/bbox.py
+++ b/megapixels/app/models/bbox.py
@@ -1,6 +1,9 @@
+import math
+
from dlib import rectangle as dlib_rectangle
import numpy as np
+
class BBoxPoint:
def __init__(self, x, y):
@@ -42,8 +45,12 @@ class BBox:
self._tl = (x1, y1)
self._br = (x2, y2)
self._rect = (self._x1, self._y1, self._x2, self._y2)
+ self._area = self._width * self._height # as percentage
-
+ @property
+ def area(self):
+ return self._area
+
@property
def pt_tl(self):
return self._tl
@@ -105,7 +112,12 @@ class BBox:
# # Utils
# def constrain(self, dim):
-
+ def distance(self, b):
+ a = self
+ dcx = self._cx - b.cx
+ dcy = self._cy - b.cy
+ d = int(math.sqrt(math.pow(dcx, 2) + math.pow(dcy, 2)))
+ return d
# -----------------------------------------------------------------
# Modify
@@ -117,26 +129,40 @@ class BBox:
:returns (BBox) in pixel dimensions
"""
# expand
- rect_exp = list( (np.array(self._rect) + np.array([-amt, -amt, amt, amt])).astype('int'))
+ r = list( (np.array(self._rect) + np.array([-amt, -amt, amt, amt])).astype('int'))
# outliers
oob = list(range(4))
- oob[0] = min(rect_exp[0], 0)
- oob[1] = min(rect_exp[1], 0)
- oob[2] = dim[0] - max(rect_exp[2], 2)
- oob[3] = dim[1] - max(rect_exp[3], 3)
+ oob[0] = min(r[0], 0)
+ oob[1] = min(r[1], 0)
+ oob[2] = dim[0] - r[2]
+ oob[3] = dim[1] - r[3]
oob = np.array(oob)
oob[oob > 0] = 0
- # amount
+ # absolute amount
oob = np.absolute(oob)
- # threshold
- rect_exp[0] = max(rect_exp[0], 0)
- rect_exp[1] = max(rect_exp[1], 0)
- rect_exp[2] = min(rect_exp[2], dim[0])
- rect_exp[3] = min(rect_exp[3], dim[1])
+ # threshold expanded rectangle
+ r[0] = max(r[0], 0)
+ r[1] = max(r[1], 0)
+ r[2] = min(r[2], dim[0])
+ r[3] = min(r[3], dim[1])
# redistribute oob amounts
oob = np.array([-oob[2], -oob[3], oob[0], oob[1]])
- rect_exp = np.add(np.array(rect_exp), oob)
- return BBox(*rect_exp)
+ r = np.add(np.array(r), oob)
+ # find overage
+ oob[0] = min(r[0], 0)
+ oob[1] = min(r[1], 0)
+ oob[2] = dim[0] - r[2]
+ oob[3] = dim[1] - r[3]
+ oob = np.array(oob)
+ oob[oob > 0] = 0
+ oob = np.absolute(oob)
+ if np.array(oob).any():
+ m = np.max(oob)
+ adj = np.array([m, m, -m, -m])
+ # print(adj)
+ r = np.add(np.array(r), adj)
+
+ return BBox(*r)
# -----------------------------------------------------------------
@@ -156,23 +182,23 @@ class BBox:
# -----------------------------------------------------------------
# Format as
- def as_xyxy(self):
+ def to_xyxy(self):
"""Converts BBox back to x1, y1, x2, y2 rect"""
return (self._x1, self._y1, self._x2, self._y2)
- def as_xywh(self):
+ def to_xywh(self):
"""Converts BBox back to haar type"""
return (self._x1, self._y1, self._width, self._height)
- def as_trbl(self):
+ def to_trbl(self):
"""Converts BBox to CSS (top, right, bottom, left)"""
return (self._y1, self._x2, self._y2, self._x1)
- def as_dlib(self):
+ def to_dlib(self):
"""Converts BBox to dlib rect type"""
- return dlib.rectangle(self._x1, self._y1, self._x2, self._y2)
+ return dlib_rectangle(self._x1, self._y1, self._x2, self._y2)
- def as_yolo(self):
+ def to_yolo(self):
"""Converts BBox to normalized center x, center y, w, h"""
return (self._cx, self._cy, self._width, self._height)
@@ -199,6 +225,13 @@ class BBox:
return cls(*rect)
@classmethod
+ def from_xyxy(cls, x1, y1, x2, y2):
+ """Converts x1, y1, x2, y2 to BBox
+ same as constructure but zprovided for conveniene
+ """
+ return cls(x1, y1, x2, y2)
+
+ @classmethod
def from_xywh(cls, x, y, w, h):
"""Converts x1, y1, w, h to BBox
:param rect: (list) x1, y1, w, h
@@ -227,8 +260,13 @@ class BBox:
"""
rect = (rect.left(), rect.top(), rect.right(), rect.bottom())
rect = cls.normalize(cls, rect, dim)
- return cls(*rect)
+ return cls(*rect)
+
+ def __str__(self):
+ return f'BBox: ({self._x1},{self._y1}), ({self._x2}, {self._y2}), width:{self._width}, height:{self._height}'
+ def __repr__(self):
+ return f'BBox: ({self._x1},{self._y1}), ({self._x2}, {self._y2}), width:{self._width}, height:{self._height}'
def str(self):
"""Return BBox as a string "x1, y1, x2, y2" """