Example #1
0
def similarity_transform(txy=(0, 0), r=0, s=1):
    """Return a 3x3 similarity transformation with translation tuple txy=(x,y), rotation r (radians, scale=s"""
    assert istuple(txy) and len(txy) == 2 and isnumber(r) and isnumber(
        s), "Invalid input"
    R = np.mat([[np.cos(r), -np.sin(r), 0], [np.sin(r),
                                             np.cos(r), 0], [0, 0, 1]])
    S = np.mat([[s, 0, 0], [0, s, 0], [0, 0, 1]])
    T = np.mat([[0, 0, txy[0]], [0, 0, txy[1]], [0, 0, 0]])
    return S * R + T  # composition
Example #2
0
def affine_transform(txy=(0, 0), r=0, sx=1, sy=1, kx=0, ky=0):
    """Compose and return a 3x3 affine transformation for translation txy=(0,0), rotation r (radians), scalex=sx, scaley=sy, shearx=kx, sheary=ky"""
    assert istuple(txy) and len(txy) == 2 and isnumber(r) and isnumber(
        sx) and isnumber(sy) and isnumber(kx) and isnumber(ky), "Invalid input"
    R = np.mat([[np.cos(r), -np.sin(r), 0], [np.sin(r),
                                             np.cos(r), 0], [0, 0, 1]])
    S = np.mat([[sx, 0, 0], [0, sy, 0], [0, 0, 1]])
    K = np.mat([[1, ky, 0], [kx, 1, 0], [0, 0, 1]])
    T = np.mat([[0, 0, txy[0]], [0, 0, txy[1]], [0, 0, 0]])
    return K * S * R + T  # composition
Example #3
0
def similarity_transform_2x3(c=(0, 0), r=0, s=1):
    """Return a 2x3 similarity transform with rotation r (radians), scale s and origin c=(x,y)"""
    assert istuple(c) and len(c) == 2 and isnumber(r) and isnumber(
        s), "Invalid input"
    deg = r * 180. / math.pi
    a = s * np.cos(r)
    b = s * np.sin(r)
    (x, y) = (c[0], c[1])
    return np.array([[a, b, (1 - a) * x - b * y], [-b, a,
                                                   b * x + (1 - a) * y]])
Example #4
0
 def hasoverlap(self, img=None, width=None, height=None):
     """Does the bounding box intersect with the provided image rectangle?"""
     if img is not None:
         assert isnumpy(img), "Invalid image input"
         (width, height) = (img.shape[1], img.shape[0])
     else:
         assert width is not None and height is not None, "Invalid width and height - both must be provided"
         assert isnumber(width) and isnumber(
             height), "Invalid width and height - both must be numbers"
     return self.area_of_intersection(
         BoundingBox(xmin=0, ymin=0, width=width, height=height)) > 0
Example #5
0
 def imclip(self, img=None, width=None, height=None):
     """Clip bounding box to image rectangle [0,0,width,height] or img.shape=(width, height) and, throw an exception on an invalid box"""
     if img is not None:
         assert isnumpy(img), "Invalid numpy image input"
         (height, width) = (img.shape[0], img.shape[1])
     else:
         assert width is not None and height is not None, "Invalid width and height - both must be provided"
         assert isnumber(width) and isnumber(
             height), "Invalid width and height - both must be numbers"
     return self.intersection(BoundingBox(xmin=0,
                                          ymin=0,
                                          width=width,
                                          height=height),
                              strict=True)
Example #6
0
 def rescale(self, scale):
     """Scale ellipse by scale factor"""
     assert isnumber(scale), "Invalid input"
     self._major *= scale
     self._minor *= scale
     self._xcenter *= scale
     self._ycenter *= scale
     return self
Example #7
0
 def flipud(self, img=None, height=None):
     """Flip the box up/down consistent with flipud of the provided img (or consistent with the image height)"""
     if img is not None:
         assert isnumpy(img), "Invalid numpy image input"
         height = img.shape[0]
     else:
         assert isnumber(height), "Invalid height"
     (x, y, w, h) = self.xywh()
     self._ymin = height - self._ymax
     self._ymax = self._ymin + h
     return self
Example #8
0
 def fliplr(self, img=None, width=None):
     """Flip the box left/right consistent with fliplr of the provided img (or consistent with the image width)"""
     if img is not None:
         assert isnumpy(img), "Invalid numpy image input"
         width = img.shape[1]
     else:
         assert isnumber(width), "Invalid width"
     (x, y, w, h) = self.xywh()
     self._xmin = width - self._xmax
     self._xmax = self._xmin + w
     return self
Example #9
0
 def dilate(self, scale=1):
     """Change scale of bounding box keeping centroid constant"""
     assert isnumber(scale), "Invalid input"
     w = self.width()
     h = self.height()
     c = self.centroid()
     old_x = self._xmin
     old_y = self._ymin
     new_x = (float(w) / 2.0) * scale
     new_y = (float(h) / 2.0) * scale
     self._xmin = c[0] - new_x
     self._ymin = c[1] - new_y
     self._xmax = c[0] + new_x
     self._ymax = c[1] + new_y
     return self
Example #10
0
    def __init__(self,
                 xmin=None,
                 ymin=None,
                 xmax=None,
                 ymax=None,
                 centroid=None,
                 xcentroid=None,
                 ycentroid=None,
                 width=None,
                 height=None,
                 mask=None,
                 xywh=None,
                 ulbr=None):

        if xmin is not None and ymin is not None and xmax is not None and ymax is not None:
            if not (isnumber(xmin) and isnumber(ymin) and isnumber(xmax)
                    and isnumber(ymax)):
                raise ValueError('Box coordinates must be integers or floats')
            self._xmin = float(xmin)
            self._ymin = float(ymin)
            self._xmax = float(xmax)
            self._ymax = float(ymax)
        elif xmin is not None and ymin is not None and width is not None and height is not None:
            if not (isnumber(xmin) and isnumber(ymin) and isnumber(width)
                    and isnumber(height)):
                raise ValueError('Box coordinates must be integers or floats')
            self._xmin = float(xmin)
            self._ymin = float(ymin)
            self._xmax = self._xmin + float(width)
            self._ymax = self._ymin + float(height)
        elif centroid is not None and width is not None and height is not None:
            if not (len(centroid) == 2 and isnumber(centroid[0]) and isnumber(
                    centroid[1]) and isnumber(width) and isnumber(height)):
                raise ValueError('Invalid box coordinates')
            self._xmin = float(centroid[0]) - float(width) / 2.0
            self._ymin = float(centroid[1]) - float(height) / 2.0
            self._xmax = float(centroid[0]) + float(width) / 2.0
            self._ymax = float(centroid[1]) + float(height) / 2.0
        elif xcentroid is not None and ycentroid is not None and width is not None and height is not None:
            if not (isnumber(xcentroid) and isnumber(ycentroid)
                    and isnumber(width) and isnumber(height)):
                raise ValueError('Box coordinates must be integers or floats')
            self._xmin = float(xcentroid) - (float(width) / 2.0)
            self._ymin = float(ycentroid) - (float(height) / 2.0)
            self._xmax = float(xcentroid) + (float(width) / 2.0)
            self._ymax = float(ycentroid) + (float(height) / 2.0)
        elif xywh is not None:
            self.xywh(xywh)
        elif ulbr is not None:
            self.ulbr(ulbr)
        elif mask is not None:
            # Bounding rectangle of non-zero pixels in a binary mask image
            if not isnumpy(mask) or np.sum(mask) == 0:
                raise ValueError(
                    'Mask input must be numpy array with at least one non-zero entry'
                )
            imx = np.sum(mask, axis=0)
            imy = np.sum(mask, axis=1)
            self._xmin = np.argwhere(imx > 0)[0]
            self._ymin = np.argwhere(imy > 0)[0]
            self._xmax = np.argwhere(imx > 0)[-1]
            self._ymax = np.argwhere(imy > 0)[-1]
        else:
            raise ValueError('invalid constructor input')
Example #11
0
def random_positive_semidefinite_matrix(N):
    """Return a randomly generated float64 positive semidefinite matrix of size NxN"""
    assert isnumber(N), "Invalid input" ""
    A = np.random.rand(N, N)
    return np.dot(A, A.transpose())