diff options
| author | Adam Harvey <adam@ahprojects.com> | 2018-12-23 01:37:03 +0100 |
|---|---|---|
| committer | Adam Harvey <adam@ahprojects.com> | 2018-12-23 01:37:03 +0100 |
| commit | 4452e02e8b04f3476273574a875bb60cfbb4568b (patch) | |
| tree | 3ffa44f9621b736250a8b94da14a187dc785c2fe /megapixels/app/models/bbox.py | |
| parent | 2a65f7a157bd4bace970cef73529867b0e0a374d (diff) | |
| parent | 5340bee951c18910fd764241945f1f136b5a22b4 (diff) | |
.
Diffstat (limited to 'megapixels/app/models/bbox.py')
| -rw-r--r-- | megapixels/app/models/bbox.py | 82 |
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" """ |
