def get_bounding_boxes(img, kernel_size, stride):
    """Gives all bounding boxes covering an image with a sliding window
    Args:
        img (np.array or torch.tensor)
        kernel_size (int): size of the kernel, kernel is a square
        stride (int): stride of the sliding window motion
    Returns:
        bounding boxes list (list of (x, xp,y, yp)), convention of bounding box
        (top, bottom, left, right)
    Notice: If not all image covered by sliding window, additional
    bounding boxes are created ending at the end of each dimension
    """
    h, w = img.shape
    h_p, w_p = kernel_size, kernel_size
    s = stride

    # All x locations
    x = [i*s for i in range(0, int((h-h_p)/s)+1)]
    # Add one more point if didn't cover all range
    if x[-1]+h_p!=h:
        x.append(h-h_p)
    # All y locations
    y = [j*s for j in range(0, int((w-w_p)/s)+1)]
    # Add one more point if didn't cover all range
    if y[-1]+w_p!=w:
        y.append(w-w_p)

    # All bounding boxes in the form (x,xp,y,yp)
    # x,y: the top left corner/ xp,yp: the bottom right corner
    bbList = [(xi,xi+h_p, yi, yi+w_p) for xi in x for yi in y]

    return bbList