Example #1
0
 def test_01_3D(self):
     x = numpy.zeros((5,5,5))
     output = rank_order(x)[0]
     self.assertTrue(numpy.all(output==0))
     self.assertEqual(x.ndim, 3)
     self.assertEqual(x.shape[0],5)
     self.assertEqual(x.shape[1],5)
     self.assertEqual(x.shape[2],5)
Example #2
0
 def test_01_3D(self):
     x = numpy.zeros((5, 5, 5))
     output = rank_order(x)[0]
     self.assertTrue(numpy.all(output == 0))
     self.assertEqual(x.ndim, 3)
     self.assertEqual(x.shape[0], 5)
     self.assertEqual(x.shape[1], 5)
     self.assertEqual(x.shape[2], 5)
Example #3
0
 def test_00_zeros(self):
     """Test rank_order on a matrix of all zeros"""
     x = numpy.zeros((5,5))
     output = rank_order(x)[0]
     self.assertTrue(numpy.all(output==0))
     self.assertTrue(output.dtype.type == numpy.uint32)
     self.assertEqual(x.ndim, 2)
     self.assertEqual(x.shape[0],5)
     self.assertEqual(x.shape[1],5)
Example #4
0
 def test_00_zeros(self):
     """Test rank_order on a matrix of all zeros"""
     x = numpy.zeros((5, 5))
     output = rank_order(x)[0]
     self.assertTrue(numpy.all(output == 0))
     self.assertTrue(output.dtype.type == numpy.uint32)
     self.assertEqual(x.ndim, 2)
     self.assertEqual(x.shape[0], 5)
     self.assertEqual(x.shape[1], 5)
Example #5
0
 def test_02_two_values(self):
     x = numpy.zeros((5,10))
     x[3,5] = 2
     x[4,7] = 2
     output,orig = rank_order(x)
     self.assertEqual(output[3,5],1)
     self.assertEqual(output[4,7],1)
     self.assertEqual(len(orig),2)
     self.assertEqual(orig[0],0)
     self.assertEqual(orig[1],2)
     self.assertEqual(numpy.sum(output==0),48)
Example #6
0
 def test_02_two_values(self):
     x = numpy.zeros((5, 10))
     x[3, 5] = 2
     x[4, 7] = 2
     output, orig = rank_order(x)
     self.assertEqual(output[3, 5], 1)
     self.assertEqual(output[4, 7], 1)
     self.assertEqual(len(orig), 2)
     self.assertEqual(orig[0], 0)
     self.assertEqual(orig[1], 2)
     self.assertEqual(numpy.sum(output == 0), 48)
Example #7
0
 def test_03_three_values(self):
     x = numpy.zeros((5,10))
     x[3,5] = 4
     x[4,7] = 4
     x[0,9] = 3
     output,orig = rank_order(x)
     self.assertEqual(output[0,9],1)
     self.assertEqual(output[3,5],2)
     self.assertEqual(output[4,7],2)
     self.assertEqual(len(orig),3)
     self.assertEqual(orig[0],0)
     self.assertEqual(orig[1],3)
     self.assertEqual(orig[2],4)
     self.assertEqual(numpy.sum(output==0),47)
Example #8
0
 def test_03_three_values(self):
     x = numpy.zeros((5, 10))
     x[3, 5] = 4
     x[4, 7] = 4
     x[0, 9] = 3
     output, orig = rank_order(x)
     self.assertEqual(output[0, 9], 1)
     self.assertEqual(output[3, 5], 2)
     self.assertEqual(output[4, 7], 2)
     self.assertEqual(len(orig), 3)
     self.assertEqual(orig[0], 0)
     self.assertEqual(orig[1], 3)
     self.assertEqual(orig[2], 4)
     self.assertEqual(numpy.sum(output == 0), 47)
Example #9
0
def fast_watershed(image, markers, connectivity=None, offset=None, mask=None):
    """Return a matrix labeled using the watershed algorithm
    
    image - an array where the lowest value points are
            labeled first.
    markers - an array marking the basins with the values
              to be assigned in the label matrix. Zero means not a marker.
              This array should be of an integer type.
    connectivity - an array whose non-zero elements indicate neighbors
                   for connection.
                   Following the scipy convention, default is a one-connected
                   array of the dimension of the image.
    offset  - offset of the connectivity (one offset per dimension)
    mask    - don't label points in the mask
    
    Returns a labeled matrix of the same type and shape as markers
    
    This implementation converts all arguments to specific, lowest common
    denominator types, then passes these to a C algorithm that operates
    as above.
    """

    if connectivity == None:
        c_connectivity = scipy.ndimage.generate_binary_structure(image.ndim, 1)
    else:
        c_connectivity = numpy.array(connectivity, bool)
        if c_connectivity.ndim != image.ndim:
            raise ValueError, "Connectivity dimension must be same as image"
    if offset == None:
        if any([x % 2 == 0 for x in c_connectivity.shape]):
            raise ValueError, "Connectivity array must have an unambiguous center"
        #
        # offset to center of connectivity array
        #
        offset = numpy.array(c_connectivity.shape) / 2

    # pad the image, markers, and mask so that we can use the mask to keep from running off the edges
    pads = offset

    def pad(im):
        new_im = numpy.zeros([i + 2 * p for i, p in zip(im.shape, pads)], im.dtype)
        new_im[[slice(p, -p, None) for p in pads]] = im
        return new_im

    if mask is not None:
        mask = pad(mask)
    else:
        mask = pad(numpy.ones(image.shape, bool))
    image = pad(image)
    markers = pad(markers)

    c_image = rank_order(image)[0].astype(numpy.int32)
    c_markers = numpy.ascontiguousarray(markers, dtype=numpy.int32)
    if c_markers.ndim != c_image.ndim:
        raise ValueError, "markers (ndim=%d) must have same # of dimensions " "as image (ndim=%d)" % (
            c_markers.ndim,
            c_image.ndim,
        )
    if not all([x == y for x, y in zip(c_markers.shape, c_image.shape)]):
        raise ValueError("image and markers must have the same shape")
    if mask != None:
        c_mask = numpy.ascontiguousarray(mask, dtype=bool)
        if c_mask.ndim != c_markers.ndim:
            raise ValueError, "mask must have same # of dimensions as image"
        if not all([x == y for x, y in zip(c_markers.shape, c_mask.shape)]):
            raise ValueError, "mask must have same shape as image"
        c_markers[numpy.logical_not(mask)] = 0
    else:
        c_mask = None
    c_output = c_markers.copy()

    #
    # We pass a connectivity array that pre-calculates the stride for each
    # neighbor.
    #
    # The result of this bit of code is an array with one row per
    # point to be considered. The first column is the pre-computed stride
    # and the second through last are the x,y...whatever offsets
    # (to do bounds checking).
    c = []
    image_stride = __get_strides_for_shape(image.shape)
    for i in range(numpy.product(c_connectivity.shape)):
        multiplier = 1
        offs = []
        indexes = []
        ignore = True
        for j in range(len(c_connectivity.shape)):
            elems = c_image.shape[j]
            idx = (i / multiplier) % c_connectivity.shape[j]
            off = idx - offset[j]
            if off:
                ignore = False
            offs.append(off)
            indexes.append(idx)
            multiplier *= c_connectivity.shape[j]
        if (not ignore) and c_connectivity.__getitem__(tuple(indexes)):
            stride = numpy.dot(image_stride, numpy.array(offs))
            offs.insert(0, stride)
            c.append(offs)
    c = numpy.array(c, numpy.int32)

    pq, age = __heapify_markers(c_markers, c_image)
    pq = numpy.ascontiguousarray(pq, dtype=numpy.int32)
    if numpy.product(pq.shape) > 0:
        # If nothing is labeled, the output is empty and we don't have to
        # do anything
        c_output = c_output.flatten()
        if c_mask == None:
            c_mask = numpy.ones(c_image.shape, numpy.int8).flatten()
        else:
            c_mask = c_mask.astype(numpy.int8).flatten()
        _watershed.watershed(
            c_image.flatten(), pq, age, c, c_image.ndim, c_mask, numpy.array(c_image.shape, numpy.int32), c_output
        )
    c_output = c_output.reshape(c_image.shape)[[slice(1, -1, None)] * image.ndim]
    try:
        return c_output.astype(markers.dtype)
    except:
        return c_output
Example #10
0
def fast_watershed(image, markers, connectivity=None, offset=None, mask=None):
    """Return a matrix labeled using the watershed algorithm
    
    image - an array where the lowest value points are
            labeled first.
    markers - an array marking the basins with the values
              to be assigned in the label matrix. Zero means not a marker.
              This array should be of an integer type.
    connectivity - an array whose non-zero elements indicate neighbors
                   for connection.
                   Following the scipy convention, default is a one-connected
                   array of the dimension of the image.
    offset  - offset of the connectivity (one offset per dimension)
    mask    - don't label points in the mask
    
    Returns a labeled matrix of the same type and shape as markers
    
    This implementation converts all arguments to specific, lowest common
    denominator types, then passes these to a C algorithm that operates
    as above.
    """

    if connectivity == None:
        c_connectivity = scipy.ndimage.generate_binary_structure(image.ndim, 1)
    else:
        c_connectivity = numpy.array(connectivity, bool)
        if c_connectivity.ndim != image.ndim:
            raise ValueError, "Connectivity dimension must be same as image"
    if offset == None:
        if any([x % 2 == 0 for x in c_connectivity.shape]):
            raise ValueError, "Connectivity array must have an unambiguous center"
        #
        # offset to center of connectivity array
        #
        offset = numpy.array(c_connectivity.shape) / 2

    # pad the image, markers, and mask so that we can use the mask to keep from running off the edges
    pads = offset

    def pad(im):
        new_im = numpy.zeros([i + 2 * p for i, p in zip(im.shape, pads)],
                             im.dtype)
        new_im[[slice(p, -p, None) for p in pads]] = im
        return new_im

    if mask is not None:
        mask = pad(mask)
    else:
        mask = pad(numpy.ones(image.shape, bool))
    image = pad(image)
    markers = pad(markers)

    c_image = rank_order(image)[0].astype(numpy.int32)
    c_markers = numpy.ascontiguousarray(markers, dtype=numpy.int32)
    if c_markers.ndim != c_image.ndim:
        raise ValueError,\
            "markers (ndim=%d) must have same # of dimensions "\
            "as image (ndim=%d)"%(c_markers.ndim, c_image.ndim)
    if not all([x == y for x, y in zip(c_markers.shape, c_image.shape)]):
        raise ValueError("image and markers must have the same shape")
    if mask != None:
        c_mask = numpy.ascontiguousarray(mask, dtype=bool)
        if c_mask.ndim != c_markers.ndim:
            raise ValueError, "mask must have same # of dimensions as image"
        if not all([x == y for x, y in zip(c_markers.shape, c_mask.shape)]):
            raise ValueError, "mask must have same shape as image"
        c_markers[numpy.logical_not(mask)] = 0
    else:
        c_mask = None
    c_output = c_markers.copy()

    #
    # We pass a connectivity array that pre-calculates the stride for each
    # neighbor.
    #
    # The result of this bit of code is an array with one row per
    # point to be considered. The first column is the pre-computed stride
    # and the second through last are the x,y...whatever offsets
    # (to do bounds checking).
    c = []
    image_stride = __get_strides_for_shape(image.shape)
    for i in range(numpy.product(c_connectivity.shape)):
        multiplier = 1
        offs = []
        indexes = []
        ignore = True
        for j in range(len(c_connectivity.shape)):
            elems = c_image.shape[j]
            idx = (i / multiplier) % c_connectivity.shape[j]
            off = idx - offset[j]
            if off:
                ignore = False
            offs.append(off)
            indexes.append(idx)
            multiplier *= c_connectivity.shape[j]
        if (not ignore) and c_connectivity.__getitem__(tuple(indexes)):
            stride = numpy.dot(image_stride, numpy.array(offs))
            offs.insert(0, stride)
            c.append(offs)
    c = numpy.array(c, numpy.int32)

    pq, age = __heapify_markers(c_markers, c_image)
    pq = numpy.ascontiguousarray(pq, dtype=numpy.int32)
    if numpy.product(pq.shape) > 0:
        # If nothing is labeled, the output is empty and we don't have to
        # do anything
        c_output = c_output.flatten()
        if c_mask == None:
            c_mask = numpy.ones(c_image.shape, numpy.int8).flatten()
        else:
            c_mask = c_mask.astype(numpy.int8).flatten()
        _watershed.watershed(c_image.flatten(), pq, age, c,
                             c_image.ndim, c_mask,
                             numpy.array(c_image.shape, numpy.int32), c_output)
    c_output = c_output.reshape(c_image.shape)[[slice(1, -1, None)] *
                                               image.ndim]
    try:
        return c_output.astype(markers.dtype)
    except:
        return c_output