Beispiel #1
0
    def plot_transform_vec(
        self,
        row,
        col,
        flow,
        interval=5,
        arrow_length=1.0,
        linewidth=1.0,
        title=None,
        overlay=False,
    ):
        """
        plots a transformation of the form 2 x H x W at position row, col.
        Parameters:
            row: the row to plot the image
            col: the clolumn to plot the image
            flow: Tensor of shape 2 x H x W
            interval: spacing of grid lines. default 5.
            title: optional title
            overlay: bool, is the grid an overlay over an existing image? Default False
        """
        # get identity
        idty_transform = Identity()
        idty = idty_transform(flow.unsqueeze(0))[0]

        # convert to numpy
        flow = transforms.image_to_numpy(flow)
        idty = transforms.image_to_numpy(idty)

        # extract components
        X = idty[..., 1]  # y, x indexed
        Y = idty[..., 0]

        U = flow[..., 1]
        V = -flow[
            ...,
            0]  # invert Y numerical vlaue, as plt.quiver ignores inverted axis.

        # calculate magnitude
        M = np.hypot(U, V)

        if not overlay:
            # only set up frame if this is not an overlay
            self.axs[row, col].invert_yaxis()
            self.axs[row, col].set_aspect("equal")
            self.axs[row, col].title.set_text(title)

        self.axs[row, col].quiver(
            X[::interval, ::interval],
            Y[::interval, ::interval],
            U[::interval, ::interval],
            V[::interval, ::interval],
            M[::interval, ::interval],
            units="x",
            width=linewidth,
            scale=1 / arrow_length,
            cmap="Blues",
        )
        return self
Beispiel #2
0
 def plot_img(self, row, col, image, title=None, vmin=None, vmax=None):
     """
     plots a tensor of the form C x H x W at position row, col.
     C needs to be either C=1 or C=3
     Parameters:
         row: the row to plot the image
         col: the clolumn to plot the image
         image: Tensor of shape C x H x W
         title: optional title
         vmin: optinal lower bound for color scaling
         vmax: optional higher bound for color scaling
     """
     # convert to numpy
     img = transforms.image_to_numpy(image)
     if len(img.shape) == 2:
         # plot greyscale image
         self.axs[row, col].imshow(img,
                                   cmap="gray",
                                   vmin=vmin,
                                   vmax=vmax,
                                   interpolation="none")
     elif len(img.shape) == 3:
         # last channel is color channel
         self.axs[row, col].imshow(img)
     self.axs[row, col].set_aspect("equal")
     self.axs[row, col].title.set_text(title)
     return self
Beispiel #3
0
 def plot_overlay(self, row, col, mask, alpha=0.4, vmin=None, vmax=None):
     """
     imposes an overlay onto a plot
     Overlay needs to be of the form C x H x W
     C needs to be either C=1 or C=3 or C=4
     Parameters:
         row: the row to plot the image
         col: the clolumn to plot the image
         mask: Tensor of shape C x H x W
         alpha: alpha-visibility of the overlay. Default 0.4
         vmin: optinal lower bound for color scaling
         vmax: optional higher bound for color scaling
     """
     # convert to numpy
     mask = transforms.image_to_numpy(mask)
     if len(mask.shape) == 2:
         # plot greyscale image
         self.axs[row, col].imshow(
             mask,
             cmap="jet",
             vmin=vmin,
             vmax=vmax,
             interpolation="none",
             alpha=alpha,
         )
     elif len(mask.shape) in [3, 4]:
         # last channel is color channel
         self.axs[row, col].imshow(mask, alpha=alpha)
     return self
Beispiel #4
0
    def plot_contour(self,
                     row,
                     col,
                     mask,
                     contour_class,
                     width=3,
                     rgba=(36, 255, 12, 255)):
        """
        imposes a contour-line overlay onto a plot
        Parameters:
            row: the row to plot the image
            col: the clolumn to plot the image
            mask: Tensor of shape C x H x W
            contour_class: the class to make a contour of
            width: thickness of contours.
            rgba: color of the contour lines. RGB or RGBA formats
        """
        # convert to numpy
        mask = transforms.image_to_numpy(mask)

        # get mask
        mask = mask == contour_class

        if len(rgba) == 3:
            # add alpha-channel
            rgba = (*rgba, 255)

        # find countours
        import cv2

        outline = np.zeros((*mask.shape[:2], 4), dtype=np.uint8) * 255
        cnts = cv2.findContours(mask.astype(np.uint8), cv2.RETR_EXTERNAL,
                                cv2.CHAIN_APPROX_SIMPLE)
        cnts = cnts[0] if len(cnts) == 2 else cnts[1]
        for c in cnts:
            cv2.drawContours(outline, [c], -1, rgba, thickness=width)
        self.axs[row, col].imshow(
            outline.astype(np.float) / 255,
            vmin=0,
            vmax=1,
            interpolation="none",
            alpha=1.0,
        )

        return self
Beispiel #5
0
def export_img_2d(path, img, normalize=False):
    """
    exports a tensor as an image. Tensor is comnverted and rescaled from 0..1 to 0..255
    Parameters:
        path: the path to save the image at. eg: './img.png'
        img: a Tensor, CxHxW
        normalize: bool. If true, values will be normalized to 0..255. If falce, values will be converted from 0..1 to 0..255. Default False.
    """
    # convert to numpy
    img = transforms.image_to_numpy(img)

    # normalize
    if normalize:
        img -= img.min()
        img /= img.max()

    # save with PIL
    im = Image.fromarray(np.uint8(img * 255))
    im.save(path)
Beispiel #6
0
    def plot_transform_grid(
        self,
        row,
        col,
        inv_flow,
        interval=5,
        linewidth=0.5,
        title=None,
        color="#000000FF",
        overlay=False,
    ):
        """
        plots a transformation of the form 2 x H x W at position row, col.
        Parameters:
            row: the row to plot the image
            col: the clolumn to plot the image
            flow: Tensor of shape 2 x H x W
            interval: spacing of grid lines. default 5.
            title: optional title
            color: the color of the grid. Default '#000000FF'
            overlay: bool, is the grid an overlay over an existing image? Default False
        """
        # convert to transform
        idty = Identity()
        inv_transform = inv_flow + idty(inv_flow.unsqueeze(0))[0]

        # make sure it's not running out of bounds
        H, W = inv_transform.shape[-2:]
        inv_transform[0, :, :] = torch.clamp(inv_transform[0, :, :], 0, H - 1)
        inv_transform[1, :, :] = torch.clamp(inv_transform[1, :, :], 0, W - 1)

        # convert to numpy
        inv_transform = transforms.image_to_numpy(inv_transform)

        if not overlay:
            # only set up frame if this is not an overlay
            self.axs[row, col].invert_yaxis()
            self.axs[row, col].set_aspect("equal")
            self.axs[row, col].title.set_text(title)

        # record position before plotting, to set it back afterwards
        # under some circumstances, the grid plotting can change the position of the subplot. we want to stop this
        bbox = self.axs[row, col].get_position()

        for r in range(0, inv_transform.shape[0], interval):
            self.axs[row, col].plot(
                inv_transform[r, :, 1],
                inv_transform[r, :, 0],
                color.lower(),
                linewidth=linewidth,
            )
        for c in range(0, inv_transform.shape[1], interval):
            self.axs[row, col].plot(
                inv_transform[:, c, 1],
                inv_transform[:, c, 0],
                color.lower(),
                linewidth=linewidth,
            )

        # set position back
        self.axs[row, col].set_position(bbox, which="both")
        return self