コード例 #1
0
def test_morphsnakes_black():

    img = np.zeros((11, 11))
    ls = circle_level_set(img.shape, (5, 5), 3)

    ref_zeros = np.zeros(img.shape, dtype=np.int8)
    ref_ones = np.ones(img.shape, dtype=np.int8)

    acwe_ls = morphological_chan_vese(img, iterations=6, init_level_set=ls)
    assert_array_equal(acwe_ls, ref_zeros)

    gac_ls = morphological_geodesic_active_contour(img,
                                                   iterations=6,
                                                   init_level_set=ls)
    assert_array_equal(gac_ls, ref_zeros)

    gac_ls2 = morphological_geodesic_active_contour(img,
                                                    iterations=6,
                                                    init_level_set=ls,
                                                    balloon=1,
                                                    threshold=-1,
                                                    smoothing=0)
    assert_array_equal(gac_ls2, ref_ones)

    assert acwe_ls.dtype == gac_ls.dtype == gac_ls2.dtype == np.int8
コード例 #2
0
def test_morphsnakes_incorrect_ndim():
    img = np.zeros((4, 4, 4, 4))
    ls = np.zeros((4, 4, 4, 4))

    with testing.raises(ValueError):
        morphological_chan_vese(img, iterations=1, init_level_set=ls)
    with testing.raises(ValueError):
        morphological_geodesic_active_contour(img, iterations=1,
                                              init_level_set=ls)
コード例 #3
0
def test_morphsnakes_incorrect_ndim():
    img = np.zeros((4, 4, 4, 4))
    ls = np.zeros((4, 4, 4, 4))

    with pytest.raises(ValueError):
        morphological_chan_vese(img, num_iter=1, init_level_set=ls)
    with pytest.raises(ValueError):
        morphological_geodesic_active_contour(img, num_iter=1,
                                              init_level_set=ls)
コード例 #4
0
def test_morphsnakes_incorrect_image_shape():
    img = np.zeros((10, 10, 3))
    ls = np.zeros((10, 9))

    with testing.raises(ValueError):
        morphological_chan_vese(img, iterations=1, init_level_set=ls)
    with testing.raises(ValueError):
        morphological_geodesic_active_contour(img,
                                              iterations=1,
                                              init_level_set=ls)
コード例 #5
0
def test_MorphGeodesicActiveContour():
    """Unit test for MorphGeodesicActiveContour method. Checks if evaluate function output\
     is the same as manually running the skimage function."""
    ac1 = Segmentors.MorphGeodesicActiveContour()
    assert ac1.evaluate(TEST_IM_COLOR).all() == segmentation.morphological_geodesic_active_contour(\
                segmentation.inverse_gaussian_gradient(color.rgb2gray(TEST_IM_COLOR), 0.2, 0.3),\
                iterations=10, init_level_set='checkerboard', smoothing=5, threshold='auto',\
                balloon=10).all()
    assert ac1.evaluate(TEST_IM_GRAY).all() == segmentation.morphological_geodesic_active_contour(\
                segmentation.inverse_gaussian_gradient(TEST_IM_GRAY, 0.2, 0.3), iterations=10,\
                init_level_set='checkerboard', smoothing=5, threshold='auto', balloon=10).all()
コード例 #6
0
def createMask(x0, y0, x1, y1, fileName, patientID, rawDataPath):
    filePath = (rawDataPath + '/' + fileName)
    maskDataPath = '/home/faqih/ITB/TA/Web/server/static/maskData'
    segmentedImPath = '/home/faqih/ITB/TA/Web/server/static/segmentedImage'
    binaryCircle = _init(x0, y0, x1, y1)
    image = pydicom.filereader.dcmread(filePath).pixel_array
    gimage = inverse_gaussian_gradient(image, 200, 8)
    mask = morphological_geodesic_active_contour(gimage,
                                                 100,
                                                 binaryCircle,
                                                 smoothing=3,
                                                 balloon=-1,
                                                 threshold=0.6)

    fig, ax = plt.subplots(figsize=(7, 7))
    plt.subplots_adjust(left=0, bottom=0, right=1, top=1, wspace=0, hspace=0)
    ax.imshow(image, cmap=plt.cm.gray)
    ax.contour(mask, [0.5], colors='r', linestyles='dashed', linewidths=2)
    ax.set_xticks([]), ax.set_yticks([])
    ax.axis([0, image.shape[1], image.shape[0], 0])
    #plt.show()
    ax.figure.savefig(os.path.join(segmentedImPath, fileName.split('.', 1)[0]))
    np.savez_compressed(os.path.join(maskDataPath,
                                     fileName.split('.', 1)[0] + '.npz'),
                        mask=mask)
    return (fileName, patientID)
コード例 #7
0
ファイル: active_plgs.py プロジェクト: pengguanjun/imagepy
 def preview(self, ips, para):
     snap, img = ips.snap, ips.img
     gimage = inverse_gaussian_gradient(img_as_float(snap))
     init = np.ones(img.shape, dtype=np.bool)
     msk = morphological_geodesic_active_contour(gimage, para['iter'], 
         init_level_set=init, smoothing=para['smooth'], 
         threshold='auto' if para['auto'] else para['thr'], balloon=para['balloon']) > 0
     (c1, c2), img[:] = ips.range, snap
     if para['out'] == 'mask': img[~msk], img[msk] = c1, c2
     else: img[binary_dilation(msk) ^ msk] = c2
     ips.update()
コード例 #8
0
def test_morphsnakes_black():
    img = np.zeros((11, 11))
    ls = circle_level_set(img.shape, (5, 5), 3)

    ref_zeros = np.zeros(img.shape, dtype=np.int8)
    ref_ones = np.ones(img.shape, dtype=np.int8)

    acwe_ls = morphological_chan_vese(img, iterations=6, init_level_set=ls)
    assert_array_equal(acwe_ls, ref_zeros)

    gac_ls = morphological_geodesic_active_contour(img, iterations=6,
                                                   init_level_set=ls)
    assert_array_equal(gac_ls, ref_zeros)

    gac_ls2 = morphological_geodesic_active_contour(img, iterations=6,
                                                    init_level_set=ls,
                                                    balloon=1, threshold=-1,
                                                    smoothing=0)
    assert_array_equal(gac_ls2, ref_ones)

    assert acwe_ls.dtype == gac_ls.dtype == gac_ls2.dtype == np.int8
コード例 #9
0
ファイル: active_plgs.py プロジェクト: super973/imagepy
 def run(self, ips, snap, img, para=None):
     gimage = inverse_gaussian_gradient(img_as_float(snap))
     init = ips.get_msk('out')
     msk = morphological_geodesic_active_contour(
         gimage,
         para['iter'],
         init_level_set=init,
         smoothing=para['smooth'],
         threshold='auto' if para['auto'] else para['thr'],
         balloon=para['balloon']) > 0
     (c1, c2), img[:] = ips.range, snap
     if para['out'] == 'mask': img[~msk], img[msk] = c1, c2
     else: img[binary_dilation(msk) ^ msk] = c2
コード例 #10
0
ファイル: active_plgs.py プロジェクト: pengguanjun/imagepy
 def run(self, ips, snap, img, para = None):
     stackimg = []
     callback = lambda x: stackimg.append((x*255).astype(np.uint8)) if para['sub'] else 0
     gimage = inverse_gaussian_gradient(img_as_float(snap))
     init = np.ones(img.shape, dtype=np.bool)
     msk = morphological_geodesic_active_contour(gimage, para['iter'], 
         init_level_set=init, smoothing=para['smooth'], 
         threshold='auto' if para['auto'] else para['thr'], 
         balloon=para['balloon'], iter_callback=callback) > 0
     (c1, c2), img[:] = ips.range, snap
     if para['out'] == 'mask': img[~msk], img[msk] = c1, c2
     else: img[binary_dilation(msk) ^ msk] = c2
     if para['sub']: self.app.show_img(stackimg, ips.title+'-sub')
コード例 #11
0
def snake_GAC(filename):
    image = io.imread(filename)
    gimage = inverse_gaussian_gradient(image)

    # Initial level set
    init_ls = np.zeros(image.shape, dtype=np.int8)
    init_ls[10:-10, 10:-10] = 1
    # List with intermediate results for plotting the evolution
    evolution2 = []
    callback = store_evolution_in(evolution2)
    ls = morphological_geodesic_active_contour(gimage, iterations,
                                               iter_callback=callback)
    return evolution2[-1]
コード例 #12
0
 def _segment_gac(img, init_level_set, iterations=20):
     """
     refines initial segmentation contours using geodesic active contours
     :param imgs: list of 2 images [2D] imgs[0] = slice to segment: imgs[1] = initial level set
     :param iterations: number of refinement iterations
     :return:
     """
     return segmentation.morphological_geodesic_active_contour(
         img,
         iterations,
         init_level_set=init_level_set,
         smoothing=2,
         balloon=1.2)
コード例 #13
0
 def supercluster(self,clustered_data):
     gimage = inverse_gaussian_gradient(clustered_data)
     # Initial level set
     # this makes alternate squares active at the first iteration of 10 macro-pixels
     #init_ls = checkerboard_level_set(clustered_data.shape, 10)
     init_ls = np.zeros(clustered_data.shape, dtype=np.int8)
     init_ls[10:-10, 10:-10] = 1
     # List with intermediate results for plotting the evolution
     evolution = []
     callback = self.store_evolution_in(evolution)
     ls = morphological_geodesic_active_contour(gimage, 300, init_ls,
                                                smoothing=1, balloon=-1,
                                                threshold=0.69,
                                                iter_callback=callback)
     return ls
コード例 #14
0
def test_morphsnakes_iterations_kwarg_deprecation():
    img = np.zeros((11, 11))
    ls = disk_level_set(img.shape, center=(5, 5), radius=3)

    ref_zeros = np.zeros(img.shape, dtype=np.int8)
    ref_ones = np.ones(img.shape, dtype=np.int8)

    with expected_warnings(["`iterations` is a deprecated argument"]):
        acwe_ls = morphological_chan_vese(img, iterations=6, init_level_set=ls)
    assert_array_equal(acwe_ls, ref_zeros)

    with expected_warnings(["`iterations` is a deprecated argument"]):
        gac_ls = morphological_geodesic_active_contour(img, iterations=6,
                                                       init_level_set=ls)
    assert_array_equal(gac_ls, ref_zeros)
コード例 #15
0
def test_init_level_sets():
    image = np.zeros((6, 6))
    checkerboard_ls = morphological_chan_vese(image, 0, 'checkerboard')
    checkerboard_ref = np.array(
        [[0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 0, 1],
         [0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 0, 1], [1, 1, 1, 1, 1, 0]],
        dtype=np.int8)

    circle_ls = morphological_geodesic_active_contour(image, 0, 'circle')
    circle_ref = np.array(
        [[0, 0, 0, 0, 0, 0], [0, 0, 1, 1, 1, 0], [0, 1, 1, 1, 1, 1],
         [0, 1, 1, 1, 1, 1], [0, 1, 1, 1, 1, 1], [0, 0, 1, 1, 1, 0]],
        dtype=np.int8)

    assert_array_equal(checkerboard_ls, checkerboard_ref)
    assert_array_equal(circle_ls, circle_ref)
コード例 #16
0
ファイル: snake.py プロジェクト: templeblock/PlaqueDetection
def probmap2bound_slicewise(i, prob_map_b, thres=0.7, ks=9):
    """ obtain boundary from probability map for each slice
    :param prob_map_b: ndarray of size [B, H, W], probability map
    :param thres: float, thres for filtering out pixels with prob lower than given thres
    :param outer_ks: int, kernel size for bound detection
    :return: lses: list of obtained bounds
    """

    n_channel, height, width = prob_map_b.shape
    iter_max = 30
    lses = []

    for bound_inx in range(1, n_channel):  # inner and outer bound
        prob_map_bb = prob_map_b[bound_inx]
        pred_filter = (prob_map_bb >= thres).astype(np.uint8)
        kernel_close = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (ks, ks))

        for inx in range(iter_max):
            image_close = cv2.morphologyEx(pred_filter, cv2.MORPH_CLOSE, kernel_close, iterations=inx+1)
            _, contours, _ = cv2.findContours(image_close, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
            contours = [contour for contour in contours
                        if len(contour) > 4 and cv2.contourArea(contour) / len(contour) >= 4.0]

            if len(contours) > 0: # find the optimal number of iterations
                break

        if len(contours) > 0:
            mask = np.zeros(image_close.shape[:2], np.uint8)
            ls = cv2.drawContours(mask, contours, -1, 1, -1)

        else: # use Snake to find contours if cv2.findContours doesn't work well
            if bound_inx == 1:
                gimage = inverse_gaussian_gradient(img_as_float(image_close), alpha=100, sigma=5.0)
            else:
                gimage = inverse_gaussian_gradient(img_as_float(image_close), alpha=100, sigma=3.0)
            init = np.zeros(gimage.shape, dtype=np.int8)
            init[5:-5, 5:-5] = 1
            ls = morphological_geodesic_active_contour(gimage, 100, init, smoothing=1,
                                                       balloon=-1, threshold='auto')
        lses.append(ls)

    reg = lslist2bound(lses)

    return reg
コード例 #17
0
def _morph_snakes(img: np.ndarray,
                  labels: np.ndarray,
                  sigma: int = SNAKES_SIGMA,
                  iterations: int = SNAKES_ITERATIONS,
                  balloon: int = SNAKES_BALLOON,
                  threshold: float = SNAKES_THRESHOLD,
                  smoothing: float = SNAKES_SMOOTHING) -> List[np.ndarray]:
    """ Applies morphological active contour method to given image starting from given labels. """
    gradient = ndimage.gaussian_gradient_magnitude(img.astype(np.float32),
                                                   sigma=sigma)
    return [
        segment.morphological_geodesic_active_contour(gradient,
                                                      iterations,
                                                      labels == region_id,
                                                      smoothing=smoothing,
                                                      balloon=balloon,
                                                      threshold=threshold)
        for region_id in range(1, np.amax(labels))
    ]
コード例 #18
0
def test_init_level_sets():
    image = np.zeros((6, 6))
    checkerboard_ls = morphological_chan_vese(image, 0, 'checkerboard')
    checkerboard_ref = np.array([[0, 0, 0, 0, 0, 1],
                                 [0, 0, 0, 0, 0, 1],
                                 [0, 0, 0, 0, 0, 1],
                                 [0, 0, 0, 0, 0, 1],
                                 [0, 0, 0, 0, 0, 1],
                                 [1, 1, 1, 1, 1, 0]], dtype=np.int8)

    circle_ls = morphological_geodesic_active_contour(image, 0, 'circle')
    circle_ref = np.array([[0, 0, 0, 0, 0, 0],
                           [0, 0, 1, 1, 1, 0],
                           [0, 1, 1, 1, 1, 1],
                           [0, 1, 1, 1, 1, 1],
                           [0, 1, 1, 1, 1, 1],
                           [0, 0, 1, 1, 1, 0]], dtype=np.int8)

    assert_array_equal(checkerboard_ls, checkerboard_ref)
    assert_array_equal(circle_ls, circle_ref)
コード例 #19
0
def test_morphsnakes_simple_shape_geodesic_active_contour():
    img = np.float_(circle_level_set((11, 11), (5, 5), 3.5))
    gimg = inverse_gaussian_gradient(img, alpha=10.0, sigma=1.0)
    ls = circle_level_set(img.shape, (5, 5), 6)

    ref = np.array(
        [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
         [0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0], [0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0],
         [0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0], [0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
         [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]],
        dtype=np.int8)

    gac_ls = morphological_geodesic_active_contour(gimg,
                                                   iterations=10,
                                                   init_level_set=ls,
                                                   balloon=-1)
    assert_array_equal(gac_ls, ref)
    assert gac_ls.dtype == np.int8
コード例 #20
0
def test_morphsnakes_simple_shape_geodesic_active_contour():
    img = (disk_level_set((11, 11), center=(5, 5), radius=3.5)).astype(float)
    gimg = inverse_gaussian_gradient(img, alpha=10.0, sigma=1.0)
    ls = disk_level_set(img.shape, center=(5, 5), radius=6)

    ref = np.array(
        [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
         [0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0], [0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0],
         [0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0], [0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
         [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]],
        dtype=np.int8)

    gac_ls = morphological_geodesic_active_contour(gimg,
                                                   num_iter=10,
                                                   init_level_set=ls,
                                                   balloon=-1)
    assert_array_equal(gac_ls, ref)
    assert gac_ls.dtype == np.int8
コード例 #21
0
def test_morphsnakes_simple_shape_geodesic_active_contour():
    img = np.float_(circle_level_set((11, 11), (5, 5), 3.5))
    gimg = inverse_gaussian_gradient(img, alpha=10.0, sigma=1.0)
    ls = circle_level_set(img.shape, (5, 5), 6)

    ref = np.array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                    [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
                    [0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
                    [0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
                    [0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0],
                    [0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
                    [0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
                    [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
                    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]],
                   dtype=np.int8)

    gac_ls = morphological_geodesic_active_contour(gimg, iterations=10,
                                                   init_level_set=ls,
                                                   balloon=-1)
    assert_array_equal(gac_ls, ref)
    assert gac_ls.dtype == np.int8
コード例 #22
0
title = "Morphological ACWE evolution"
ax[1].set_title(title, fontsize=12)


# Morphological GAC
image = img_as_float(data.coins())
gimage = inverse_gaussian_gradient(image)

# Initial level set
init_ls = np.zeros(image.shape, dtype=np.int8)
init_ls[10:-10, 10:-10] = 1
# List with intermediate results for plotting the evolution
evolution = []
callback = store_evolution_in(evolution)
ls = morphological_geodesic_active_contour(gimage, 230, init_ls,
                                           smoothing=1, balloon=-1,
                                           threshold=0.69,
                                           iter_callback=callback)

ax[2].imshow(image, cmap="gray")
ax[2].set_axis_off()
ax[2].contour(ls, [0.5], colors='r')
ax[2].set_title("Morphological GAC segmentation", fontsize=12)

ax[3].imshow(ls, cmap="gray")
ax[3].set_axis_off()
contour = ax[3].contour(evolution[0], [0.5], colors='g')
contour.collections[0].set_label("Iteration 0")
contour = ax[3].contour(evolution[100], [0.5], colors='y')
contour.collections[0].set_label("Iteration 100")
contour = ax[3].contour(evolution[-1], [0.5], colors='r')
contour.collections[0].set_label("Iteration 230")
コード例 #23
0
        c = c[1:]
        count = count[1:]
        RealGlacier = 1 * (G2label == np.argmax(count) + 1)
        # RealGlacier=binary_closing(RealGlacier, selem=np.ones((3,3)))
        # RealOcean=binary_closing(RealOcean, selem=np.ones((3,3)))
        # GO2=BlankFrame(scipy.ndimage.binary_fill_holes(RealGlacier))
        RO2 = 1 * scipy.ndimage.binary_fill_holes(RealOcean)
        #deploy the geodetic active contours
        RealGlacier = scipy.ndimage.binary_fill_holes(RealGlacier)
        init_ls = 1 * binary_dilation(1 * RealGlacier, selem=np.ones((5, 5)))
        init_ls = 1 * binary_closing(init_ls, selem=np.ones((30, 30)))
        init_ls = 1 * scipy.ndimage.binary_fill_holes(init_ls)
        image = 1 - (np.float32(1 * RealGlacier))
        GO2 = morphological_geodesic_active_contour(image,
                                                    30,
                                                    init_ls,
                                                    smoothing=1,
                                                    balloon=-0.5,
                                                    threshold=0.6)
        GO2 = scipy.ndimage.morphology.binary_erosion(GO2, iterations=2)

        RO2 = np.logical_and(RO2, np.logical_not(GO2))
        GO2 = BlankFrame(GO2)
        C = measure.find_contours(GO2, level=0.5)
        csize = np.zeros(len(C))
        for i in range(len(C)):
            csize = C[i].shape[0]
        MainContour = np.int16(C[np.argmax(csize)])
        GlacierContour = np.zeros((GO2.shape))
        for c in range(len(MainContour)):
            GlacierContour[MainContour[c, 0], MainContour[c, 1]] = 1
                a = dmap_test[i, :, :, :].reshape(dmap_test.shape[1:3])
                b = dmap_test_pred
                c = mask_test[i, :, :, 0]
                plt.imshow(np.abs((b - a)) * c)
                plt.colorbar()
                plt.title('error |est - gt| * mask')

                input("Press Enter to continue...")

            mask = np.zeros(shape=)


            from skimage.segmentation import morphological_geodesic_active_contour
            contours = morphological_geodesic_active_contour(dmap_test_pred[0, :, :, 0],
                                                             iterations=10000,
                                                             init_level_set='checkerboard',
                                                             smoothing=4,
                                                             balloon=0.0)

            contours = cv2.Laplacian(dmap_test_pred[0, :, :, 0], cv2.CV_32F)

            import CGAL
            from CGAL.CGAL_Point_set_processing_3 import jet_estimate_normals

            plt.clf()
            plt.subplot(211)
            plt.imshow(dmap_test_pred.reshape(dmap_test_pred.shape[1:3]))
            plt.subplot(212)
            plt.imshow(contours)

コード例 #25
0
ax[1].set_title(title, fontsize=12)

# Morphological GAC
image = img_as_float(data.coins())
gimage = inverse_gaussian_gradient(image)

# Initial level set
init_ls = np.zeros(image.shape, dtype=np.int8)
init_ls[10:-10, 10:-10] = 1
# List with intermediate results for plotting the evolution
evolution2 = []
callback = store_evolution_in(evolution2)
ls = morphological_geodesic_active_contour(gimage,
                                           230,
                                           init_ls,
                                           smoothing=1,
                                           balloon=-1,
                                           threshold=0.69,
                                           iter_callback=callback)

ax[2].imshow(image, cmap="gray")
ax[2].set_axis_off()
ax[2].contour(ls, [0.5], colors='r')
ax[2].set_title("Morphological GAC segmentation", fontsize=12)

ax[3].imshow(ls, cmap="gray")
ax[3].set_axis_off()
contour = ax[3].contour(evolution2[0], [0.5], colors='g')
contour.collections[0].set_label("Iteration 0")
contour = ax[3].contour(evolution2[100], [0.5], colors='y')
contour.collections[0].set_label("Iteration 100")
コード例 #26
0
    def run(self):
        self.beginTaskRun()

        # Get input 0 :
        input = self.getInput(0)

        # Get output :
        output = self.getOutput(0)

        # Get parameters :
        param = self.getParam()

        # Get image from input/output (numpy array):
        srcImage = input.getImage()

        # Convert to grey Image if RGB
        if len(srcImage.shape) == 3:
            image = cv2.cvtColor(srcImage, cv2.COLOR_RGB2GRAY)
        else:
            image = srcImage

        # Convert to float
        imagef = img_as_float(image)

        # enhances borders
        if param.mgac_amplification_contour == "Inverse gaussian gradient":
            gimage = inverse_gaussian_gradient(imagef)
        else:
            gimage = imagef

        # initial level set
        initlevelSetInput = self.getInput(2)
        if initlevelSetInput.isDataAvailable():
            initlevelSetBinary = initlevelSetInput.getImage()
            if param.method == "mgac":
                proc_img = morphological_geodesic_active_contour(
                    gimage,
                    param.mgac_iterations,
                    init_level_set=initlevelSetBinary,
                    smoothing=param.mgac_smoothing,
                    threshold=param.mgac_threshold,
                    balloon=param.mgac_balloon,
                    iter_callback=(lambda callback: self.emitStepProgress()
                                   )).astype(np.uint8) * 255
            else:
                proc_img = morphological_chan_vese(
                    gimage,
                    param.mcv_iterations,
                    init_level_set=initlevelSetBinary,
                    smoothing=param.mcv_smoothing,
                    lambda1=param.mcv_lambda1,
                    lambda2=param.mcv_lambda2,
                    iter_callback=(lambda callback: self.emitStepProgress()
                                   )).astype(np.uint8) * 255
        else:
            # input graph -> by user / by previous aoperation in worflow
            graphInput = self.getInput(1)
            if graphInput.isDataAvailable():
                self.createGraphicsMask(imagef.shape[1], imagef.shape[0],
                                        graphInput)
                binImg = self.getGraphicsMask(0)
                if param.method == "mgac":
                    proc_img = morphological_geodesic_active_contour(
                        gimage,
                        param.mgac_iterations,
                        init_level_set=binImg,
                        smoothing=param.mgac_smoothing,
                        threshold=param.mgac_threshold,
                        balloon=param.mgac_balloon,
                        iter_callback=(
                            lambda callback: self.emitStepProgress())).astype(
                                np.uint8) * 255
                else:
                    proc_img = morphological_chan_vese(
                        gimage,
                        param.mcv_iterations,
                        init_level_set=binImg,
                        smoothing=param.mcv_smoothing,
                        lambda1=param.mcv_lambda1,
                        lambda2=param.mcv_lambda2,
                        iter_callback=(
                            lambda callback: self.emitStepProgress())).astype(
                                np.uint8) * 255
            else:
                raise Exception(
                    "No initial level-set given: it must be graphics input or binary image."
                )

        # set output mask binary image
        output.setImage(proc_img)

        # add foward input image
        self.forwardInputImage(0, 1)

        # Call endTaskRun to finalize process
        self.endTaskRun()
コード例 #27
0
def active_contour(image):
    def store_evolution_in(lst):
        
        def _store(x):
            lst.append(np.copy(x))
    
        return _store
    
    image = img_as_float(data.camera())
    
    init_ls = checkerboard_level_set(image.shape, 6)
    
    evolution = []
    callback = store_evolution_in(evolution)
    ls = morphological_chan_vese(image, 35, init_level_set=init_ls, smoothing=3,
                                 iter_callback=callback)
    
    fig, axes = plt.subplots(2, 2, figsize=(8, 8))
    ax = axes.flatten()
    
    ax[0].imshow(image, cmap="gray")
    ax[0].set_axis_off()
    ax[0].contour(ls, [0.5], colors='r')
    ax[0].set_title("Morphological ACWE segmentation", fontsize=12)
    
    ax[1].imshow(ls, cmap="gray")
    ax[1].set_axis_off()
    contour = ax[1].contour(evolution[2], [0.5], colors='g')
    contour.collections[0].set_label("Iteration 2")
    contour = ax[1].contour(evolution[7], [0.5], colors='y')
    contour.collections[0].set_label("Iteration 7")
    contour = ax[1].contour(evolution[-1], [0.5], colors='r')
    contour.collections[0].set_label("Iteration 35")
    ax[1].legend(loc="upper right")
    title = "Morphological ACWE evolution"
    ax[1].set_title(title, fontsize=12)
    
    
    
    image = img_as_float(data.coins())
    gimage = inverse_gaussian_gradient(image)
    
    
    init_ls = np.zeros(image.shape, dtype=np.int8)
    init_ls[10:-10, 10:-10] = 1
    
    evolution = []
    callback = store_evolution_in(evolution)
    ls = morphological_geodesic_active_contour(gimage, 230, init_ls,
                                               smoothing=1, balloon=-1,
                                               threshold=0.69,
                                               iter_callback=callback)
    
    ax[2].imshow(image, cmap="gray")
    ax[2].set_axis_off()
    ax[2].contour(ls, [0.5], colors='r')
    ax[2].set_title("Morphological GAC segmentation", fontsize=12)
    
    ax[3].imshow(ls, cmap="gray")
    ax[3].set_axis_off()
    contour = ax[3].contour(evolution[0], [0.5], colors='g')
    contour.collections[0].set_label("Iteration 0")
    contour = ax[3].contour(evolution[100], [0.5], colors='y')
    contour.collections[0].set_label("Iteration 100")
    contour = ax[3].contour(evolution[-1], [0.5], colors='r')
    contour.collections[0].set_label("Iteration 230")
    ax[3].legend(loc="upper right")
    title = "Morphological GAC evolution"
    ax[3].set_title(title, fontsize=12)
    
    fig.tight_layout()
    plt.show()
コード例 #28
0
###############################################################################
# Finally, we use morphological geodesic active contours,
# :func:`skimage.segmentation.morphological_geodesic_active_contour`, a method
# that generally produces good results, but requires a long time to converge on
# a good answer. We purposefully cut short the procedure at 100 iterations, so
# that the final result is *undersegmented*, meaning that many regions are
# merged into one segment. We will see the corresponding effect on the
# segmentation metrics.

image = img_as_float(image)
gradient = inverse_gaussian_gradient(image)
init_ls = np.zeros(image.shape, dtype=np.int8)
init_ls[10:-10, 10:-10] = 1
im_test3 = morphological_geodesic_active_contour(gradient,
                                                 iterations=100,
                                                 init_level_set=init_ls,
                                                 smoothing=1,
                                                 balloon=-1,
                                                 threshold=0.69)
im_test3 = label(im_test3)

method_names = [
    'Compact watershed', 'Canny filter',
    'Morphological Geodesic Active Contours'
]
short_method_names = ['Compact WS', 'Canny', 'GAC']

precision_list = []
recall_list = []
split_list = []
merge_list = []
for name, im_test in zip(method_names, [im_test1, im_test2, im_test3]):
コード例 #29
0
def morphSnakes(fp, frame, alph, sig, thresh):
    """{ 
    ******************************************************************
    *  Fnc:     read_arf() 
    *  Desc:    reads an arf file and returns dictionary of parsed info
    *  Inputs:  fp - full path to arf file
    *  Outputs: 
    ******************************************************************
    }"""
    ############################ Read Public Release Data ##################################################
    #    print('Reading data...')
    _, fn = os.path.split(fp)
    basename, _ext = os.path.splitext(fn)
    df = pd.read_csv(f"{DATA_DIR}/Metric/{basename}.bbox_met",
                     header=None,
                     names=[
                         "site", "unknown1", "unknown2", "sensor", "scenario",
                         "frame", "ply_id", "unknown3", "unknown4", "upperx",
                         "uppery", "unknown5", "unknown6", "unknown7",
                         "unknown8", "unknown9", "unknown10", "unknown11"
                     ])
    agt = read_agt(f"{DATA_DIR}/cegr/agt/{basename}.agt")
    f = open(fp, "rb")
    header = f.read(8 * 4)
    header = list(struct.iter_unpack(">I", header))
    fptr = np.memmap(fp,
                     dtype="uint16",
                     mode='r',
                     shape=(header[5][0], header[2][0], header[3][0]),
                     offset=32)
    frames, cols, rows = fptr.shape
    #    print('Data loaded!')
    im = fptr[frame].T.byteswap()
    tgtx, tgty = map(
        int, agt['Agt']['TgtSect'][f'TgtUpd.{frame}'][f'Tgt.{frame}']
        ['PixLoc'].split())
    upper_left_x, upper_left_y = df[df['frame'] == frame +
                                    1][['upperx', 'uppery']].iloc[0]
    tgt_width = 2 * (tgtx - upper_left_x)
    tgt_height = 2 * (tgty - upper_left_y)

    ######################################### Find BB with GAC ################################################
    def store_evolution_in(lst):
        """Returns a callback function to store the evolution of the level sets in
        the given list.
        """
        def _store(x):
            lst.append(np.copy(x))

        return _store

    plt.ioff()
    fig, axes = plt.subplots(2, 2, figsize=(8, 8))
    ax = axes.flatten()
    # Morphological GAC
    image = img_as_float(im.T)
    gimage = inverse_gaussian_gradient(image, alpha=alph, sigma=sig)
    ax[0].imshow(image, cmap="gray")
    ax[0].set_axis_off()
    ax[0].set_title("MWIR", fontsize=12)
    ax[1].imshow(gimage, cmap="gray")
    ax[1].set_axis_off()
    ax[1].set_title("Inverse Gaussian Gradient", fontsize=12)
    ######################################## Set Initial Contour ###########################################
    ## Here you will want to set it as the bounding box, then you can set the morph snake to shrink instead
    ## of dialate.
    ########################################################################################################
    # Initial level set
    init_ls = circle_level_set(image.shape, center=(tgty, tgtx), radius=5)
    #    init_ls[10:-10, 10:-10] = 1
    # List with intermediate results for plotting the evolution
    evolution = []
    callback = store_evolution_in(evolution)
    ## Initialize the Morph Snake,  you will want it to shrink (balloon=-1)
    ls = morphological_geodesic_active_contour(gimage,
                                               230,
                                               init_ls,
                                               smoothing=1,
                                               balloon=1,
                                               threshold=thresh,
                                               iter_callback=callback)
    ax[2].imshow(image, cmap="gray")
    ax[2].set_axis_off()
    ax[2].contour(ls, [0.5], colors='r')
    ax[2].set_title("Center Point GAC Segmentation", fontsize=12)
    ax[3].imshow(ls, cmap="gray")
    ax[3].set_axis_off()
    contour = ax[3].contour(evolution[0], [0.5], colors='g')
    contour.collections[0].set_label("Iteration 0")
    contour = ax[3].contour(evolution[100], [0.5], colors='y')
    contour.collections[0].set_label("Iteration 100")
    contour = ax[3].contour(evolution[-1], [0.5], colors='r')
    contour.collections[0].set_label("Iteration 230")
    ax[3].legend(loc="upper right")
    title = "Center Point GAC Evolution"
    ax[3].set_title(title, fontsize=12)

    fig.tight_layout()
    fig.tight_layout(rect=[0, 0.03, 1, 0.95])
    plt.suptitle(
        f'Morph Snakes, alpha={alph}, sigma={sig}, threshold={thresh}')
    #    plt.savefig(f"{DATA_DIR}\\morphSnakes\\{basename}_{alph}_{sig}_{thresh}.png")
    #    plt.close(fig)
    plt.show()
コード例 #30
0
def main():
    filePath = '../Img/'
    fileList = os.listdir(filePath)
    # name = '13.png'

    for i in range(len(fileList)):  # len(fileList)
        Image = cv2.imread(os.path.join(filePath, fileList[i]), 1)  # 读入原图
        image = cv2.cvtColor(Image, cv2.COLOR_BGR2GRAY)
        image = img_as_float(image)
        # image = np.array(image, dtype=np.float64)  # 读入到np的array中,并转化浮点类型

        # Initial level set
        init_ls = checkerboard_level_set(image.shape, 6)
        # List with intermediate results for plotting the evolution
        ls = morphological_chan_vese(image,
                                     35,
                                     init_level_set=init_ls,
                                     smoothing=0)

        fig, axes = plt.subplots(2, 2, figsize=(8, 8))
        ax = axes.flatten()
        ax[0].imshow(image, cmap="gray")
        ax[0].set_axis_off()
        ax[0].contour(ls, [0.5], colors='r')
        ax[0].set_title(fileList[i] + 'MAC', fontsize=12)

        # Morphological GAC
        gimage = inverse_gaussian_gradient(image)
        # Initial level set
        init_ls = np.zeros(image.shape, dtype=np.int8)
        init_ls[10:-10, 10:-10] = 1
        # List with intermediate results for plotting the evolution
        ls = morphological_geodesic_active_contour(gimage,
                                                   230,
                                                   init_ls,
                                                   smoothing=1,
                                                   balloon=-1,
                                                   threshold=0.69)
        ax[1].imshow(image, cmap="gray")
        ax[1].set_axis_off()
        ax[1].contour(ls, [0.5], colors='r')
        ax[1].set_title('MGAC', fontsize=12)

        #CV
        cv = chan_vese(image,
                       mu=0.25,
                       lambda1=1,
                       lambda2=1,
                       tol=1e-3,
                       max_iter=200,
                       dt=0.5,
                       init_level_set="checkerboard",
                       extended_output=True)
        ax[2].imshow(image, cmap="gray")
        ax[2].set_axis_off()
        ax[2].contour(cv[0], [0.5], colors='r')
        ax[2].set_title('AC', fontsize=12)

        #My CV
        from MyCV import my_chan_vese
        # CV
        cv = my_chan_vese(image,
                          mu=0.25,
                          lambda1=1,
                          lambda2=1,
                          tol=1e-3,
                          max_iter=200,
                          dt=0.5,
                          init_level_set="checkerboard",
                          extended_output=True)
        ax[3].imshow(image, cmap="gray")
        ax[3].set_axis_off()
        ax[3].contour(cv[0], [0.5], colors='r')
        ax[3].set_title('MyAC', fontsize=12)

        fig.tight_layout()
        plt.savefig('./MCVSeg2/' + fileList[i] + '.png')
        plt.show(block=False)
コード例 #31
0
def morphological(image):

    # Morphological ACWE
    img = img_as_float(skimage.color.rgb2gray(image))
    # Initial level set
    init_ls = checkerboard_level_set(img.shape, 6)
    # List with intermediate results for plotting the evolution
    evolution = []
    callback = store_evolution_in(evolution)
    ls = morphological_chan_vese(img,
                                 200,
                                 init_level_set=init_ls,
                                 smoothing=4,
                                 iter_callback=callback)

    fig, axes = plt.subplots(2, 2, figsize=(8, 8))
    ax = axes.flatten()

    ax[0].imshow(img, cmap="gray")
    ax[0].set_axis_off()
    ax[0].contour(ls, [0.5], colors='r')
    ax[0].set_title("Morphological ACWE segmentation", fontsize=12)

    ax[1].imshow(ls, cmap="gray")
    ax[1].set_axis_off()
    contour = ax[1].contour(evolution[2], [0.5], colors='g')
    contour.collections[0].set_label("Iteration 2")
    contour = ax[1].contour(evolution[7], [0.5], colors='y')
    contour.collections[0].set_label("Iteration 7")
    contour = ax[1].contour(evolution[-1], [0.5], colors='r')
    contour.collections[0].set_label("Iteration 35")
    ax[1].legend(loc="upper right")
    title = "Morphological ACWE evolution"
    ax[1].set_title(title, fontsize=12)

    # Morphological GAC
    img = img_as_float(skimage.color.rgb2gray(image))
    gimage = inverse_gaussian_gradient(img)

    # Initial level set
    init_ls = np.zeros(img.shape, dtype=np.int8)
    init_ls[10:-10, 10:-10] = 1
    # List with intermediate results for plotting the evolution
    evolution = []
    callback = store_evolution_in(evolution)
    ls = morphological_geodesic_active_contour(gimage,
                                               230,
                                               init_ls,
                                               smoothing=5,
                                               balloon=-1,
                                               threshold=0.5,
                                               iter_callback=callback)

    ax[2].imshow(img, cmap="gray")
    ax[2].set_axis_off()
    ax[2].contour(ls, [0.5], colors='r')
    ax[2].set_title("Morphological GAC segmentation", fontsize=12)

    ax[3].imshow(ls, cmap="gray")
    ax[3].set_axis_off()
    contour = ax[3].contour(evolution[0], [0.5], colors='g')
    contour.collections[0].set_label("Iteration 0")
    contour = ax[3].contour(evolution[100], [0.5], colors='y')
    contour.collections[0].set_label("Iteration 100")
    contour = ax[3].contour(evolution[-1], [0.5], colors='r')
    contour.collections[0].set_label("Iteration 230")
    ax[3].legend(loc="upper right")
    title = "Morphological GAC evolution"
    ax[3].set_title(img, fontsize=12)

    fig.tight_layout()
    plt.show()
コード例 #32
0
def main():

    current_path = os.path.abspath(os.path.dirname(__file__))
    dice_results = []
    hausdorff_results = []

    # Final report text file initialization

    summary_file = open('contour_report.txt', 'w+')
    summary_file.write('Script run: {a}\n'.format(
        a=datetime.now().strftime('%Y-%m-%d %H:%M:%S')))

    for image_number in range(1, 110):

        image_path = os.path.join(current_path, 'input_images',
                                  '{}_no_contour.jpg'.format(image_number))
        image = io.imread(image_path)
        image = color.rgb2gray(image)

        # Displaying the image to get the clicks coordinates

        fig = plt.figure()
        plt.imshow(image, cmap='gray')
        plt.axis('Off')

        cid = fig.canvas.mpl_connect('button_press_event', onclick)
        plt.show()

        # Calculating the radius, used to initialize the level set algorithm

        radius = np.sqrt(
            np.square(coords[1][0] - coords[0][0]) +
            np.square(coords[1][1] - coords[0][1]))

        # Main part of the script - image processing and creating the contour:
        # 1. Histogram equalization
        # 2. Gaussian filtration
        # 3. Anisotropic diffusion filtration
        # 4. Inverse Gaussian Gradient
        # 5. Unsharp Masking
        # 6. Morphological snakes
        # Hyperparameter optimization were performed using grid search for every method.

        equalized_image = equalize_hist(image)
        filtered_image = nd.gaussian_filter(equalized_image, sigma=5)
        diff_image = anisodiff(filtered_image, niter=50)
        gimage = inverse_gaussian_gradient(diff_image, alpha=50)
        sharpened_image = unsharp_mask(gimage, radius=100, amount=1.0)
        init_level_set = circle_level_set(gimage.shape, coords[0], radius)
        level_set = morphological_geodesic_active_contour(sharpened_image,
                                                          250,
                                                          init_level_set,
                                                          smoothing=4,
                                                          balloon=1)
        level_set = nd.morphology.binary_fill_holes(level_set).astype(int)

        contour_access = os.path.join('input_images',
                                      '{}_contour.jpg'.format(image_number))
        given_contour = contour_to_binary_mask(contour_access, level_set.shape)
        dice_result = dice(given_contour, level_set)
        hausdorff_result = hausdorff(given_contour, level_set)

        print('Dice =', dice_result)
        print('Hausdorff =', hausdorff_result)

        # Updating the report with new coefficients.

        summary_file.write('\n{a}:\nDice: {b}\nHausdorff: {c}\n'.format(
            a=image_number,
            b=format(dice_result, '.2f'),
            c=format(hausdorff_result, '.2f')))

        dice_results.append(dice_result)
        hausdorff_results.append(hausdorff_result)

        # Displaying the result

        plt.figure()
        plt.imshow(image, cmap="gray")
        plt.axis('Off')
        plt.contour(level_set, [0.5], colors='r')
        plt.show()

    # Calculating and appending mean and standard deviation of the test to the end of the report

    summary_file.write('\n\nDICE:\nMEAN: {d}\nSTD DEV: {e}'.format(
        d=format(mean(dice_results), '.2f'),
        e=format(stddev(dice_results), '.2f')))
    summary_file.write('\n\nHAUSDORFF:\nMEAN: {d}\nSTD DEV: {e}'.format(
        d=format(mean(hausdorff_results), '.2f'),
        e=format(stddev(hausdorff_results), '.2f')))
    summary_file.close()
コード例 #33
0
def level_set3D(data,
                seed3D,
                resol,
                lambda1=1,
                lambda2=4,
                smoothing=0,
                iterations=100,
                rad=3,
                method='ACWE',
                alpha=100,
                sigma=2,
                balloon=1):

    ## init
    res_fac = resol[1] / resol[
        0]  # resolution factor to scale chunk to real dimensions
    N = 60  # approximately the chunk size (in mm) around nodule
    num_slices = int(round(N / res_fac))  # number of slices before
    reg = 30  # window of interest centered around seed point
    s = seed3D[1:]  # 2D seed point for (x,y)-plane
    num = seed3D[0]  # slice number seed point is selected from

    # apply lungmask on each slice of interest around seed point
    tmp_data = np.zeros((num_slices, data.shape[1], data.shape[2]))
    ii = 0
    for i in range(data.shape[0]):
        if (i >= num - int(round(num_slices / 2))
                and i <= num + int(round(num_slices / 2)) - 1):
            mask = lungmask_pro(data[i, :, :].copy())
            tmp = data[i, :, :].copy()
            tmp[mask == 0] = np.amin(
                tmp
            )  # OBS: -1024 maybe not far away enough from lung intensities
            tmp_data[ii, :, :] = tmp.copy()
            ii += 1

    # only apply level set on small volume around seed point -> increases speed and accuracy for fixed number of iterations
    tmp = tmp_data.copy()
    tmp = tmp[:, s[0] - reg:s[0] + reg, s[1] - reg:s[1] + reg]

    # transform chunk to true size (in mm) by stretching the slice-axis relevant to a resolution factor
    tmp = zoom(tmp.copy(), zoom=[res_fac, 1, 1], order=1)

    # apply 3D level set from single seed point from initial 3D blob around current seed point
    inits = circle_level_set(tmp.shape,
                             center=(int(num_slices / 2 * res_fac), reg, reg),
                             radius=rad)

    # choose between two types of level set methods
    if method == 'ACWE':
        tmp = morphological_chan_vese(tmp.copy(),
                                      iterations=iterations,
                                      init_level_set=inits,
                                      smoothing=smoothing,
                                      lambda1=lambda1,
                                      lambda2=lambda2).astype(int)
    elif method == 'GAC':
        tmp = tmp.astype(np.float32)
        tmp = inverse_gaussian_gradient(tmp, alpha=alpha, sigma=alpha)
        tmp = morphological_geodesic_active_contour(tmp,
                                                    iterations=iterations,
                                                    init_level_set=inits,
                                                    smoothing=smoothing,
                                                    threshold='auto',
                                                    balloon=1)
    else:
        print('Please choose a valid method!')
        return None

    # if no nodule was segmented, break
    if (len(np.unique(tmp)) == 1):
        #print('No nodule was segmented. Try changing parameters...')
        return None

    # check if leakage has occured
    #if ((tmp[0,0,0] > 0) or (tmp[0,0,-1] > 0) or (tmp[0,-1,0] > 0) or (tmp[0,-1,-1] > 0) or (tmp[-1,0,0] > 0) or (tmp[-1,-1,0] > 0) or (tmp[-1,0,-1] > 0) or (tmp[-1,-1,-1] > 0)):
    # if ((len(np.unique(tmp[0,:,:])) > 1) or (len(np.unique(tmp[:,0,:])) > 1) or (len(np.unique(tmp[:,:,0])) > 1) or
    #  (len(np.unique(tmp[-1,:,:])) > 1) or (len(np.unique(tmp[:,-1,:])) > 1) or (len(np.unique(tmp[:,:,-1])) > 1)):
    # 	print("Leakage problems? Growing reached boundaries... Discards segmentation")
    # 	return None

    # only keep segments connected to seed point (blood vessels will hopefully not be connected with nodule after level set, if leakage has occured)
    labels_tmp = label(tmp.copy())
    res = np.zeros(tmp.shape)
    if (labels_tmp[int(num_slices / 2 * res_fac), reg, reg] > 0):
        res[labels_tmp == labels_tmp[int(num_slices / 2 * res_fac), reg,
                                     reg]] = 1

    # need to transform chunk back to original size
    res = zoom(res.copy(), zoom=[1 / res_fac, 1, 1], order=1)

    # # just in case some parts are not connected anymore after interpolation -> remove not connected components
    # labels_tmp = label(res.copy())
    # res = np.zeros(res.shape)
    # if (labels_tmp[int(num_slices/2), reg, reg] > 0):
    # 	res[labels_tmp == labels_tmp[int(num_slices/2), reg, reg]] = 1

    # get the final nodule mask to the original image stack shape
    # but handle cases where seed point is selected at ends of image stack, and window is outside of range
    new_res = np.zeros(data.shape)
    if (num + int(num_slices / 2) > new_res.shape[0]):
        new_res[num - int(num_slices / 2):num + int(num_slices / 2),
                s[0] - reg:s[0] + reg, s[1] - reg:s[1] +
                reg] = res[:num + int(num_slices / 2) - new_res.shape[0]]
    elif (num - int(num_slices / 2) < 0):
        new_res[0:num + int(num_slices / 2), s[0] - reg:s[0] + reg,
                s[1] - reg:s[1] + reg] = res[:num + int(num_slices / 2)]
    else:
        new_res[num - int(np.floor(num_slices / 2)):num +
                int(np.ceil(num_slices / 2)), s[0] - reg:s[0] + reg,
                s[1] - reg:s[1] + reg] = res

    return new_res