import torch


def rgb_recombine_median(d_rgb_tensors: torch.Tensor, median_r: torch.Tensor, median_g: torch.Tensor, median_b: torch.Tensor) -> torch.Tensor:
    """
    Recombine separated median RGB to the delta RGB tensor.
    :param d_rgb_tensors: Delta RGB tensor [batch_size, 3, height, width].
    :param median_r: Median R [batch_size]
    :param median_g: Median G [batch_size]
    :param median_b: Median B [batch_size]
    :return: Recombined RGB texture [batch_size, 3, height, width]. Outputs in the range 0..1
    """
    assert len(d_rgb_tensors.shape) == 4 and d_rgb_tensors.shape[1] == 3
    assert len(median_r.shape) == 1
    assert len(median_g.shape) == 1
    assert len(median_b.shape) == 1

    updated_rgb_tensors = d_rgb_tensors.clone()
    median_r = median_r.unsqueeze(1).unsqueeze(2).expand(
        [updated_rgb_tensors.shape[0], updated_rgb_tensors.shape[2], updated_rgb_tensors.shape[3]])
    median_g = median_g.unsqueeze(1).unsqueeze(2).expand(
        [updated_rgb_tensors.shape[0], updated_rgb_tensors.shape[2], updated_rgb_tensors.shape[3]])
    median_b = median_b.unsqueeze(1).unsqueeze(2).expand(
        [updated_rgb_tensors.shape[0], updated_rgb_tensors.shape[2], updated_rgb_tensors.shape[3]])

    updated_rgb_tensors[:, 0, :, :] += median_r
    updated_rgb_tensors[:, 1, :, :] += median_g
    updated_rgb_tensors[:, 2, :, :] += median_b

    updated_rgb_tensors = updated_rgb_tensors.clamp(0, 1)

    return updated_rgb_tensors