def crop(self, height, width, center_i=None, center_j=None):
        """Crop the image centered around center_i, center_j.

        Parameters
        ----------
        height : int
            The height of the desired image.

        width : int
            The width of the desired image.

        center_i : int
            The center height point at which to crop. If not specified, the center
            of the image is used.

        center_j : int
            The center width point at which to crop. If not specified, the center
            of the image is used.

        Returns
        -------
        :obj:`Image`
            A cropped Image of the same type.
        """
        # compute crop center px
        height = int(np.round(height))
        width = int(np.round(width))
        if center_i is None:
            center_i = float(self.height) / 2
        if center_j is None:
            center_j = float(self.width) / 2

        # crop using PIL
        desired_start_row = int(np.floor(center_i - float(height) / 2))
        desired_end_row = int(np.floor(center_i + float(height) / 2))
        desired_start_col = int(np.floor(center_j - float(width) / 2))
        desired_end_col = int(np.floor(center_j + float(width) / 2))

        pil_im = PImage.fromarray(self.data)
        cropped_pil_im = pil_im.crop((desired_start_col,
                                      desired_start_row,
                                      desired_end_col,
                                      desired_end_row))
        crop_data = np.array(cropped_pil_im)

        if crop_data.shape[0] != height or crop_data.shape[1] != width:
            raise ValueError('Crop dims are incorrect')

        return type(self)(crop_data.astype(self.data.dtype), self._frame)