import torch


def rgb_decompose_median(rgb_tensors: torch.Tensor) -> tuple:
    """
    Separate median color from given RGB images.
    :param rgb_tensors: RGB images [batch_size, 3, height, width].
    :return: tuple(Delta RGB image [batch_size, 3, height, width], median R [batch_size], median G [batch_size], median B [batch_size])
    """
    assert len(rgb_tensors.shape) == 4 and rgb_tensors.shape[1] == 3

    _median_r = rgb_tensors[:, 0, :, :].view(rgb_tensors.shape[0], -1).median(dim=1)[0].detach()
    median_r = _median_r.unsqueeze(1).unsqueeze(2).expand(
        [rgb_tensors.shape[0], rgb_tensors.shape[2], rgb_tensors.shape[3]])

    _median_g = rgb_tensors[:, 1, :, :].view(rgb_tensors.shape[0], -1).median(dim=1)[0].detach()
    median_g = _median_g.unsqueeze(1).unsqueeze(2).expand(
        [rgb_tensors.shape[0], rgb_tensors.shape[2], rgb_tensors.shape[3]])

    _median_b = rgb_tensors[:, 2, :, :].view(rgb_tensors.shape[0], -1).median(dim=1)[0].detach()
    median_b = _median_b.unsqueeze(1).unsqueeze(2).expand(
        [rgb_tensors.shape[0], rgb_tensors.shape[2], rgb_tensors.shape[3]])

    updated_rgb_tensors = rgb_tensors.clone()
    updated_rgb_tensors[:, 0, :, :] -= median_r
    updated_rgb_tensors[:, 1, :, :] -= median_g
    updated_rgb_tensors[:, 2, :, :] -= median_b

    return updated_rgb_tensors, _median_r, _median_g, _median_b