<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def deblend_sources(data, segment_img, npixels, filter_kernel=None, labels=None, nlevels=32, contrast=0.001, mode='exponential', connectivity=8, relabel=True):
 """ Deblend overlapping sources labeled in a segmentation image. Sources are deblended using a combination of multi-thresholding and `watershed segmentation <https://en.wikipedia.org/wiki/Watershed_(image_processing)>`_. In order to deblend sources, they must be separated enough such that there is a saddle between them. Parameters data : array_like The 2D array of the image. segment_img : `~photutils.segmentation.SegmentationImage` or array_like (int) A 2D segmentation image, either as a `~photutils.segmentation.SegmentationImage` object or an `~numpy.ndarray`, with the same shape as ``data`` where sources are labeled by different positive integer values. A value of zero is reserved for the background. npixels : int The number of connected pixels, each greater than ``threshold``, that an object must have to be detected. ``npixels`` must be a positive integer. filter_kernel : array-like (2D) or `~astropy.convolution.Kernel2D`, optional The 2D array of the kernel used to filter the image before thresholding. Filtering the image will smooth the noise and maximize detectability of objects with a shape similar to the kernel. labels : int or array-like of int, optional The label numbers to deblend. If `None` (default), then all labels in the segmentation image will be deblended. nlevels : int, optional The number of multi-thresholding levels to use. Each source will be re-thresholded at ``nlevels``, spaced exponentially or linearly (see the ``mode`` keyword), between its minimum and maximum values within the source segment. contrast : float, optional The fraction of the total (blended) source flux that a local peak must have to be considered as a separate object. ``contrast`` must be between 0 and 1, inclusive. If ``contrast = 0`` then every local peak will be made a separate object (maximum deblending). If ``contrast = 1`` then no deblending will occur. The default is 0.001, which will deblend sources with a magnitude difference of about 7.5. mode : {'exponential', 'linear'}, optional The mode used in defining the spacing between the multi-thresholding levels (see the ``nlevels`` keyword). The default is 'exponential'. connectivity : {8, 4}, optional The type of pixel connectivity used in determining how pixels are grouped into a detected source. The options are 8 (default) or 4. 8-connected pixels touch along their edges or corners. 4-connected pixels touch along their edges. For reference, SExtractor uses 8-connected pixels. relabel : bool If `True` (default), then the segmentation image will be relabeled such that the labels are in consecutive order starting from 1. Returns ------- segment_image : `~photutils.segmentation.SegmentationImage` A 2D segmentation image, with the same shape as ``data``, where sources are marked by different positive integer values. A value of zero is reserved for the background. See Also -------- :func:`photutils.detect_sources` """


    if not isinstance(segment_img, SegmentationImage):
        segment_img = SegmentationImage(segment_img)

    if segment_img.shape != data.shape:
        raise ValueError('The data and segmentation image must have '
                         'the same shape')

    if labels is None:
        labels = segment_img.labels
    labels = np.atleast_1d(labels)
    segment_img.check_labels(labels)

    data = filter_data(data, filter_kernel, mode='constant', fill_value=0.0)

    last_label = segment_img.max_label
    segm_deblended = deepcopy(segment_img)
    for label in labels:
        source_slice = segment_img.slices[segment_img.get_index(label)]
        source_data = data[source_slice]
        source_segm = SegmentationImage(np.copy(
            segment_img.data[source_slice]))
        source_segm.keep_labels(label)    # include only one label
        source_deblended = _deblend_source(
            source_data, source_segm, npixels, nlevels=nlevels,
            contrast=contrast, mode=mode, connectivity=connectivity)

        if not np.array_equal(source_deblended.data.astype(bool),
                              source_segm.data.astype(bool)):
            raise ValueError('Deblending failed for source "{0}".  Please '
                             'ensure you used the same pixel connectivity '
                             'in detect_sources and deblend_sources.  If '
                             'this issue persists, then please inform the '
                             'developers.'.format(label))

        if source_deblended.nlabels > 1:
            # replace the original source with the deblended source
            source_mask = (source_deblended.data > 0)
            segm_tmp = segm_deblended.data
            segm_tmp[source_slice][source_mask] = (
                source_deblended.data[source_mask] + last_label)
            segm_deblended.data = segm_tmp    # needed to call data setter
            last_label += source_deblended.nlabels

    if relabel:
        segm_deblended.relabel_consecutive()

    return segm_deblended