Пример #1
0
def multiplePoints(imIn, imOut, grid=mamba.DEFAULT_GRID):
    """
    Extracts multiple points in 'imIn', supposed to be a "skeleton" image (connected 
    components without thickness), and puts the result in 'imOut'.
    
    Note that, on a square grid, the resulting skeleton is supposed to be defined 
    on a 4-connectivity grid. if it is not the case, some multiple points are likely
    to be missed.
    """

    imWrk1 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn)
    endPoints(imIn, imWrk2)
    if grid == mamba.HEXAGONAL:
        dse_list = [hexagonalS1, hexagonalS2]
        step = 1
        nb = 6
    else:
        dse_list = [squareS1, squareS2]
        step = 2
        nb = 4
    for dse in dse_list:
        for i in range(nb):
            hitOrMiss(imIn, imWrk1, dse)
            mamba.logic(imWrk1, imWrk2, imWrk2, "sup")
            dse = dse.rotate(step)
    mamba.diff(imIn, imWrk2, imOut)
Пример #2
0
def endPoints(imIn, imOut, grid=mamba.DEFAULT_GRID, edge=mamba.FILLED):
    """
    Extracts end points in 'imIn', supposed to be a "skeleton" image (connected 
    components without thickness), and puts them in 'imOut'.
    
    'edge' is FILLED by default and it can be modified to take into account
    extremities touching the edge.
    """

    imWrk1 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn)
    if grid == mamba.HEXAGONAL:
        dse1 = hexagonalE
        dse2 = hexagonalL
        nb = 6
        step = 1
    else:
        dse1 = squareE
        dse2 = squareL
        nb = 4
        step = 2
    rotatingThin(imIn, imWrk1, dse2, edge=edge)
    # added to avoid blocking of the process in clipping
    mamba.diff(imIn, imWrk1, imOut)
    for i in range(nb):
        hitOrMiss(imWrk1, imWrk2, dse1, edge=edge)
        mamba.logic(imOut, imWrk2, imOut, "sup")
        dse1 = dse1.rotate(step)
Пример #3
0
def partitionLabel(imIn, imOut):
    """
    This procedure labels each cell of image 'imIn' and puts the result in
    'imOut'. The number of cells is returned. 'imIn' can be a 1-bit, 8-bit or a
    32-bit image. 'imOut' is a 32-bit image. When 'imIn' is a binary image, all the
    connected components of the background are also labelled. When 'imIn' is a grey
    image, the 0-valued cells are also labelled (which is not the case with the label
    operator.
    Warning! The label values of adjacent cells are not necessarily consecutive.
    """
    
    imWrk1 = mamba.imageMb(imIn, 1)
    imWrk2 = mamba.imageMb(imIn, 32)
    
    if imIn.getDepth() == 1:
        mamba.negate(imIn, imWrk1)
    else:
        mamba.threshold(imIn, imWrk1, 0, 0)
    nb1 = mamba.label(imWrk1, imWrk2)
    mamba.convertByMask(imWrk1, imOut, mamba.computeMaxRange(imOut)[1], 0)
    mamba.logic(imOut, imWrk2, imOut, "sup")
    nb2 = mamba.label(imIn, imWrk2)
    mamba.addConst(imWrk2, nb1, imWrk2)
    mamba.logic(imOut, imWrk2, imOut, "inf")
    return nb1 + nb2
Пример #4
0
def hierarchicalLevel(imIn, imOut, grid=mamba.DEFAULT_GRID):
    """
    Computes the next hierarchical level of image 'imIn' in the
    waterfalls transformation and puts the result in 'imOut'.
    This operation makes sure that the next hierarchical level is embedded
    in the previous one.
    'imIn' must be a valued watershed image.
    """

    imWrk0 = mamba.imageMb(imIn)
    imWrk1 = mamba.imageMb(imIn, 1)
    imWrk2 = mamba.imageMb(imIn, 1)
    imWrk3 = mamba.imageMb(imIn, 1)
    imWrk4 = mamba.imageMb(imIn, 32)
    mamba.threshold(imIn, imWrk1, 0, 0)
    mamba.negate(imWrk1, imWrk2)
    hierarchy(imIn, imWrk2, imWrk0, grid=grid)
    mamba.minima(imWrk0, imWrk2, grid=grid)
    mamba.label(imWrk2, imWrk4, grid=grid)
    mamba.watershedSegment(imWrk0, imWrk4, grid=grid)
    mamba.copyBytePlane(imWrk4, 3, imWrk0)
    mamba.threshold(imWrk0, imWrk2, 0, 0)
    mamba.diff(imWrk1, imWrk2, imWrk3)
    mamba.build(imWrk1, imWrk3)
    se = mamba.structuringElement(mamba.getDirections(grid), grid)
    mamba.dilate(imWrk3, imWrk1, 1, se)
    mamba.diff(imWrk2, imWrk1, imWrk1)
    mamba.logic(imWrk1, imWrk3, imWrk1, "sup")
    mamba.convertByMask(imWrk1, imWrk0, 255, 0)
    mamba.logic(imIn, imWrk0, imOut, "inf")
Пример #5
0
def cellsHMT(imIn, imOut, dse, edge=mamba.EMPTY):
    """
    A Hit-Or-Miss transform is performed on each cell of the partition 'imIn'.
    'dse' is a double structuring element (see thinthick.py module).
    The result is put in 'imOut'. 'edge' is set to EMPTY by default.
    """

    imWrk1 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn)
    grid = dse.getGrid()
    cse0 = dse.getStructuringElement(0)
    cse1 = dse.getStructuringElement(1)
    mamba.copy(imIn, imOut)
    mamba.copy(imIn, imWrk1)
    equalNeighbors(imWrk1,
                   imWrk2,
                   cse1.getEncodedDirections(withoutZero=True),
                   grid=grid,
                   edge=edge)
    mamba.logic(imOut, imWrk2, imOut, "inf")
    nonEqualNeighbors(imWrk1,
                      imWrk2,
                      cse0.getEncodedDirections(withoutZero=True),
                      grid=grid,
                      edge=edge)
    mamba.logic(imOut, imWrk2, imOut, "inf")
Пример #6
0
def _initialQuasiDist_(imIn, imOut1, imOut2, grid=mamba.DEFAULT_GRID):
    """
    Computes the initial quasi-distance. For internal use only. The resulting
    quasi-distance is not lipchitzian (see MM documentation for details).
    """
    
    maskIm = mamba.imageMb(imIn, 1)
    imWrk1 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn)
    imWrk3 = mamba.imageMb(imIn, 32)
    se = mamba.structuringElement(mamba.getDirections(grid), grid)
    i = 0
    mamba.copy(imIn, imWrk1)
    v2 = mamba.computeVolume(imWrk1)
    v1 = v2 + 1
    imOut1.reset()
    imOut2.reset()
    while v1 > v2:
        i += 1
        v1 = v2
        mamba.erode(imWrk1, imWrk2, se=se)
        mamba.sub(imWrk1, imWrk2, imWrk1)
        _generateMask_(imWrk1, imOut1, maskIm)
        mamba.convertByMask(maskIm, imWrk3, 0, i)
        mamba.logic(imOut1, imWrk1, imOut1, "sup")
        mamba.logic(imOut2, imWrk3, imOut2, "sup")
        mamba.copy(imWrk2, imWrk1)
        v2 = mamba.computeVolume(imWrk1)
Пример #7
0
def nonEqualNeighbors(imIn, imOut, nb, grid=mamba.DEFAULT_GRID, edge=mamba.FILLED):
    """
    This operator compares the value of each pixel of image 'imIn'
    with the value of its neighbors encoded in 'nb'.
    If all the neighbor values are different, the pixel is unchanged.
    Otherwise, it takes value 0.
    This operator works on hexagonal or square 'grid' and
    'edge' is set to FILLED by default.
    This operator works for 8-bit and 32-bit images.
    """
    
    imWrk1 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn)
    imWrk3 = mamba.imageMb(imIn, 1)
    imWrk4 = mamba.imageMb(imIn, 1)
    for d in mamba.getDirections(grid):
        ed = 1<<d
        if (nb & ed):
            mamba.copy(imIn, imWrk1)
            mamba.copy(imIn, imWrk2)
            mamba.supNeighbor(imWrk1, imWrk1, ed, grid=grid, edge=edge)
            mamba.infNeighbor(imWrk2, imWrk2, ed, grid=grid, edge=edge)
            mamba.generateSupMask(imWrk2, imWrk1, imWrk3, False)
            mamba.logic(imWrk4, imWrk3, imWrk4, "or")
    mamba.convertByMask(imWrk4, imWrk1, mamba.computeMaxRange(imIn)[1], 0)
    mamba.logic(imIn, imWrk1, imOut, "inf")
Пример #8
0
def mosaicGradient(imIn, imOut, grid=mamba.DEFAULT_GRID):
    """
    Builds the mosaic-gradient image of 'imIn' and puts the result in 'imOut'.
    The mosaic-gradient image is built by computing the differences of two
    mosaic images generated from 'imIn', the first one having its watershed
    lines valued by the suprema of the adjacent catchment basins values, the
    second one been valued by the infima.
    """

    imWrk1 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn)
    imWrk3 = mamba.imageMb(imIn)
    imWrk4 = mamba.imageMb(imIn)
    imWrk5 = mamba.imageMb(imIn)
    imWrk6 = mamba.imageMb(imIn, 1)
    mosaic(imIn, imWrk2, imWrk3, grid=grid)
    mamba.sub(imWrk2, imWrk3, imWrk1)
    mamba.logic(imWrk2, imWrk3, imWrk2, "sup")
    mamba.negate(imWrk2, imWrk2)
    mamba.threshold(imWrk3, imWrk6, 1, 255)
    mamba.multiplePoints(imWrk6, imWrk6, grid=grid)
    mamba.convertByMask(imWrk6, imWrk3, 0, 255)
    se = mamba.structuringElement(mamba.getDirections(grid), grid)
    mamba.dilate(imWrk1, imWrk4, se=se)
    mamba.dilate(imWrk2, imWrk5, se=se)
    while mamba.computeVolume(imWrk3) != 0:
        mamba.dilate(imWrk1, imWrk1, 2, se=se)
        mamba.dilate(imWrk2, imWrk2, 2, se=se)
        mamba.logic(imWrk1, imWrk3, imWrk1, "inf")
        mamba.logic(imWrk2, imWrk3, imWrk2, "inf")
        mamba.logic(imWrk1, imWrk4, imWrk4, "sup")
        mamba.logic(imWrk2, imWrk5, imWrk5, "sup")
        mamba.erode(imWrk3, imWrk3, 2, se=se)
    mamba.negate(imWrk5, imWrk5)
    mamba.sub(imWrk4, imWrk5, imOut)
Пример #9
0
def binaryUltimateErosion(imIn, imOut1, imOut2, grid=mamba.DEFAULT_GRID, edge=mamba.FILLED):
    """
    Ultimate erosion of binary image 'imIn'. 'imOut1' contains the ultimate 
    eroded set and 'imOut2' contains the associated function (that is the 
    height of each connected component of the ultimate erosion).
    
    An ultimate erosion is composed of the union of the last connected
    components of the successive erosions of the initial set. The associated
    function provides the size of the corresponding erosion.
    
    Depth of 'imOut1' is 1, depth of 'imOut2' is 32. 

    The operation is fast because it is computed using the distance function
    of 'imIn' (the ultimate erosion is identical to the maxima of this
    distance function).

    The edge is set to 'FILLED' by default.
    """

    imWrk1 = mamba.imageMb(imIn, 32)
    imWrk2 = mamba.imageMb(imIn, 32)
    mamba.computeDistance(imIn, imWrk1, grid=grid, edge=edge)
    mamba.maxima(imWrk1, imOut1, grid=grid)
    mamba.convertByMask(imOut1, imWrk2, 0, mamba.computeMaxRange(imWrk2)[1])
    mamba.logic(imWrk1, imWrk2, imOut2, "inf")
Пример #10
0
def hierarchicalLevel(imIn, imOut, grid=mamba.DEFAULT_GRID):
    """
    Computes the next hierarchical level of image 'imIn' in the
    waterfalls transformation and puts the result in 'imOut'.
    This operation makes sure that the next hierarchical level is embedded
    in the previous one.
    'imIn' must be a valued watershed image.
    """
    
    imWrk0 = mamba.imageMb(imIn)
    imWrk1 = mamba.imageMb(imIn, 1)
    imWrk2 = mamba.imageMb(imIn, 1)
    imWrk3 = mamba.imageMb(imIn, 1)
    imWrk4 = mamba.imageMb(imIn, 32)
    mamba.threshold(imIn,imWrk1, 0, 0)
    mamba.negate(imWrk1, imWrk2)
    hierarchy(imIn, imWrk2, imWrk0, grid=grid)
    mamba.minima(imWrk0, imWrk2, grid=grid)
    mamba.label(imWrk2, imWrk4, grid=grid)
    mamba.watershedSegment(imWrk0, imWrk4, grid=grid)
    mamba.copyBytePlane(imWrk4, 3, imWrk0)
    mamba.threshold(imWrk0, imWrk2, 0, 0)
    mamba.diff(imWrk1, imWrk2, imWrk3)
    mamba.build(imWrk1, imWrk3)
    se = mamba.structuringElement(mamba.getDirections(grid), grid)
    mamba.dilate(imWrk3, imWrk1, 1, se)
    mamba.diff(imWrk2, imWrk1, imWrk1)
    mamba.logic(imWrk1, imWrk3, imWrk1, "sup")
    mamba.convertByMask(imWrk1, imWrk0, 255, 0)
    mamba.logic(imIn, imWrk0, imOut, "inf")
Пример #11
0
def quasiDistance(imIn, imOut1, imOut2, grid=mamba.DEFAULT_GRID):
    """
    Quasi-distance of image 'imIn'. 'imOut1' contains the residues image
    and 'imOut2' contains the quasi-distance (associated function).
    
    The quasi-distance of a greytone image is made of a patch of distance
    functions of some almost flat regions in the image. When the image is a
    simple indicator function of a set, the quasi-distance and the distance
    function are identical.

    Depth of 'imOut1' is the same as 'imIn', depth of 'imOut2' is 32.
    """

    imWrk1 = mamba.imageMb(imIn, 32)
    imWrk2 = mamba.imageMb(imIn, 32)
    imWrk3 = mamba.imageMb(imIn, 32)
    maskIm = mamba.imageMb(imIn, 1) 
    se = mamba.structuringElement(mamba.getDirections(grid), grid)
    _initialQuasiDist_(imIn, imOut1, imOut2, grid=grid)
    mamba.copy(imOut2, imWrk1)
    v1 = mamba.computeVolume(imOut2)
    v2 = v1 + 1
    while v2 > v1:
        v2 = v1
        mamba.erode(imWrk1, imWrk2, se=se)
        mamba.sub(imWrk1, imWrk2, imWrk2)
        mamba.threshold(imWrk2, maskIm, 2, mamba.computeMaxRange(imWrk2)[1])
        mamba.convertByMask(maskIm, imWrk3, 0, mamba.computeMaxRange(imWrk3)[1])
        mamba.logic(imWrk2, imWrk3, imWrk2, "inf")
        mamba.subConst(imWrk2, 1, imWrk3)
        mamba.logic(imWrk2, imWrk3, imWrk2, "inf") # Patch non saturated subtraction
        mamba.sub(imWrk1, imWrk2, imWrk1)
        v1 = mamba.computeVolume(imWrk1)
    mamba.copy(imWrk1, imOut2)
Пример #12
0
def vectorGradient(imIn, imModul, imAzim, size=1):
    """
    Computes modulus (result in 'imModul') and azimut (in 'imAzim') of image
    'imIn'. The 'size' of each directional gradient is set to 1 by default.
    This operator is defined on the hexagonal grid (12 directions are used).
    Note that this operator belongs to the residual operators class.
    """
    
    imWrk1 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn)
    imWrk3 = mamba.imageMb(imIn)
    imWrk4 = mamba.imageMb(imIn, 1)
    
    mamba.copy(imIn, imWrk1)
    imModul.reset()
    imAzim.reset()
    for i in range(12):
        d = i + 1
        # Directional gradient obtained with linear erosions and dilations.
        directionalDilate(imWrk1, imWrk2, d, size)
        directionalErode(imWrk1, imWrk3, d, size)
        mamba.sub(imWrk2, imWrk3, imWrk2)
        # For each direction, maximal pixels are indexed in a mask image.
        mamba.generateSupMask(imWrk2, imModul, imWrk4, True)
        mamba.convertByMask(imWrk4, imWrk3, 0, d)
        # Modulus and azimut are calculated.
        mamba.logic(imWrk2, imModul, imModul, "sup")
        mamba.logic(imWrk3, imAzim, imAzim, "sup")
Пример #13
0
def mulRealConst(imIn, v, imOut, nearest=False, precision=2):
    """
    Multiplies image 'imIn' by a real positive constant value 'v' and puts the 
    result in image 'imOut'. 'imIn' and 'imOut' can be 8-bit or 32-bit images.
    If 'imOut' is greyscale (8-bit), the result is saturated (results
    of the multiplication greater than 255 are limited to this value).
    'precision' indicates the number of decimal digits taken into account for
    the constant 'v' (default is 2).
    If 'nearest' is true, the result is rounded to the nearest integer value.
    If not (default), the result is simply truncated.
    """
    
    if imIn.getDepth()==1 or imOut.getDepth()==1:
        mamba.raiseExceptionOnError(core.MB_ERR_BAD_DEPTH)
    imWrk1 = mamba.imageMb(imIn, 32)
    imWrk2 = mamba.imageMb(imIn, 1)
    precVal = (10 ** precision)
    v1 = int(v * precVal)
    if imIn.getDepth()==8:
        imWrk1.reset()
        mamba.copyBytePlane(imIn, 0, imWrk1)
    else:
        mamba.copy(imIn, imWrk1)
    mulConst(imWrk1, v1, imWrk1)
    if nearest:
        adjVal = int(5 * (10 ** (precision - 1)))
        addConst(imWrk1, adjVal , imWrk1)
    divConst(imWrk1, precVal, imWrk1)
    if imOut.getDepth()==8:
        mamba.threshold(imWrk1, imWrk2, 255, mamba.computeMaxRange(imWrk1)[1])
        mamba.copyBytePlane(imWrk1, 0, imOut)
        imWrk2.convert(8)
        mamba.logic(imOut, imWrk2, imOut, "sup")
    else:
        mamba.copy(imWrk1, imOut)
Пример #14
0
def vectorGradient(imIn, imModul, imAzim, size=1):
    """
    Computes modulus (result in 'imModul') and azimut (in 'imAzim') of image
    'imIn'. The 'size' of each directional gradient is set to 1 by default.
    This operator is defined on the hexagonal grid (12 directions are used).
    Note that this operator belongs to the residual operators class.
    """

    imWrk1 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn)
    imWrk3 = mamba.imageMb(imIn)
    imWrk4 = mamba.imageMb(imIn, 1)

    mamba.copy(imIn, imWrk1)
    imModul.reset()
    imAzim.reset()
    for i in range(12):
        d = i + 1
        # Directional gradient obtained with linear erosions and dilations.
        directionalDilate(imWrk1, imWrk2, d, size)
        directionalErode(imWrk1, imWrk3, d, size)
        mamba.sub(imWrk2, imWrk3, imWrk2)
        # For each direction, maximal pixels are indexed in a mask image.
        mamba.generateSupMask(imWrk2, imModul, imWrk4, True)
        mamba.convertByMask(imWrk4, imWrk3, 0, d)
        # Modulus and azimut are calculated.
        mamba.logic(imWrk2, imModul, imModul, "sup")
        mamba.logic(imWrk3, imAzim, imAzim, "sup")
Пример #15
0
def cellsBuild(imIn, imInOut, grid=mamba.DEFAULT_GRID):
    """
    Geodesic reconstruction of the cells of the partition image 'imIn' which
    are marked by the image 'imInOut'. The marked cells take the value of
    their corresponding marker. Note that the background cells (labelled by 0)
    are also modified if they are marked.
    The result is stored in 'imInOut'.
    The images can be 8-bit or 32-bit images.
    'grid' can be set to HEXAGONAL or SQUARE.
    """
    
    imWrk1 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn)
    imWrk3 = mamba.imageMb(imIn, 1)
    vol = 0
    prec_vol = -1
    dirs = mamba.getDirections(grid)[1:]
    while (prec_vol!=vol):
        prec_vol = vol
        for d in dirs:
            ed = 1<<d
            mamba.copy(imIn, imWrk1)
            mamba.copy(imIn, imWrk2)
            mamba.supNeighbor(imWrk1, imWrk1, ed, grid=grid)
            mamba.infNeighbor(imWrk2, imWrk2, ed, grid=grid)
            mamba.generateSupMask(imWrk2, imWrk1, imWrk3, False)
            mamba.convertByMask(imWrk3, imWrk1, 0, mamba.computeMaxRange(imIn)[1])
            mamba.linearDilate(imInOut, imWrk2, d, 1, grid=grid)
            mamba.logic(imWrk2, imWrk1, imWrk2, "inf")
            v = mamba.buildNeighbor(imWrk1, imWrk2, d, grid=grid)
            mamba.logic(imWrk2, imInOut, imInOut, "sup")
        vol = mamba.computeVolume(imInOut)
Пример #16
0
def mosaicGradient(imIn, imOut, grid=mamba.DEFAULT_GRID):
    """
    Builds the mosaic-gradient image of 'imIn' and puts the result in 'imOut'.
    The mosaic-gradient image is built by computing the differences of two
    mosaic images generated from 'imIn', the first one having its watershed
    lines valued by the suprema of the adjacent catchment basins values, the
    second one been valued by the infima.
    """

    imWrk1 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn)
    imWrk3 = mamba.imageMb(imIn)
    imWrk4 = mamba.imageMb(imIn)
    imWrk5 = mamba.imageMb(imIn)
    imWrk6 = mamba.imageMb(imIn, 1)
    mosaic(imIn, imWrk2, imWrk3, grid=grid)
    mamba.sub(imWrk2, imWrk3, imWrk1)
    mamba.logic(imWrk2, imWrk3, imWrk2, "sup")
    mamba.negate(imWrk2, imWrk2)
    mamba.threshold(imWrk3, imWrk6, 1, 255)
    mamba.multiplePoints(imWrk6, imWrk6, grid=grid)
    mamba.convertByMask(imWrk6, imWrk3, 0, 255)
    se = mamba.structuringElement(mamba.getDirections(grid), grid)
    mamba.dilate(imWrk1, imWrk4, se=se)
    mamba.dilate(imWrk2, imWrk5, se=se)
    while mamba.computeVolume(imWrk3) != 0:
        mamba.dilate(imWrk1, imWrk1, 2, se=se)
        mamba.dilate(imWrk2, imWrk2, 2, se=se)
        mamba.logic(imWrk1, imWrk3, imWrk1, "inf")
        mamba.logic(imWrk2, imWrk3, imWrk2, "inf")
        mamba.logic(imWrk1, imWrk4, imWrk4, "sup")
        mamba.logic(imWrk2, imWrk5, imWrk5, "sup")
        mamba.erode(imWrk3, imWrk3, 2, se=se)
    mamba.negate(imWrk5, imWrk5)
    mamba.sub(imWrk4, imWrk5, imOut)
Пример #17
0
def cellsBuild(imIn, imInOut, grid=mamba.DEFAULT_GRID):
    """
    Geodesic reconstruction of the cells of the partition image 'imIn' which
    are marked by the image 'imInOut'. The marked cells take the value of
    their corresponding marker. Note that the background cells (labelled by 0)
    are also modified if they are marked.
    The result is stored in 'imInOut'.
    The images can be 8-bit or 32-bit images.
    'grid' can be set to HEXAGONAL or SQUARE.
    """

    imWrk1 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn)
    imWrk3 = mamba.imageMb(imIn, 1)
    vol = 0
    prec_vol = -1
    dirs = mamba.getDirections(grid)[1:]
    while (prec_vol != vol):
        prec_vol = vol
        for d in dirs:
            ed = 1 << d
            mamba.copy(imIn, imWrk1)
            mamba.copy(imIn, imWrk2)
            mamba.supNeighbor(imWrk1, imWrk1, ed, grid=grid)
            mamba.infNeighbor(imWrk2, imWrk2, ed, grid=grid)
            mamba.generateSupMask(imWrk2, imWrk1, imWrk3, False)
            mamba.convertByMask(imWrk3, imWrk1, 0,
                                mamba.computeMaxRange(imIn)[1])
            mamba.linearDilate(imInOut, imWrk2, d, 1, grid=grid)
            mamba.logic(imWrk2, imWrk1, imWrk2, "inf")
            v = mamba.buildNeighbor(imWrk1, imWrk2, d, grid=grid)
            mamba.logic(imWrk2, imInOut, imInOut, "sup")
        vol = mamba.computeVolume(imInOut)
Пример #18
0
def rotatingThin(imIn, imOut, dse, edge=mamba.FILLED):
    """
    Performs a complete rotation of thinnings , the initial 'dse' double
    structuring element being turned one step clockwise after each thinning.
    At each rotation step, the previous result is used as input for the next
    thinning (chained thinnings). Depending on the grid where 'dse' is defined,
    6 or 8 rotations are performed.
    
    'imIn' and 'imOut' are binary images.
    
    'edge' is set to FILLED by default (default value is EMPTY in simple thin).
    """

    imWrk = mamba.imageMb(imIn)
    if edge == mamba.FILLED:
        mamba.negate(imIn, imOut)
        for d in mamba.getDirections(dse.getGrid(), True):
            hitOrMiss(imOut, imWrk, dse.flip(), edge=mamba.EMPTY)
            mamba.logic(imWrk, imOut, imOut, "sup")
            dse = dse.rotate()
        mamba.negate(imOut, imOut)
    else:
        mamba.copy(imIn, imOut)
        for d in mamba.getDirections(dse.getGrid(), True):
            hitOrMiss(imOut, imWrk, dse, edge=mamba.EMPTY)
            mamba.diff(imOut, imWrk, imOut)
            dse = dse.rotate()
Пример #19
0
def partitionLabel(imIn, imOut):
    """
    This procedure labels each cell of image 'imIn' and puts the result in
    'imOut'. The number of cells is returned. 'imIn' can be a 1-bit, 8-bit or a
    32-bit image. 'imOut' is a 32-bit image. When 'imIn' is a binary image, all the
    connected components of the background are also labelled. When 'imIn' is a grey
    image, the 0-valued cells are also labelled (which is not the case with the label
    operator.
    Warning! The label values of adjacent cells are not necessarily consecutive.
    """

    imWrk1 = mamba.imageMb(imIn, 1)
    imWrk2 = mamba.imageMb(imIn, 32)

    if imIn.getDepth() == 1:
        mamba.negate(imIn, imWrk1)
    else:
        mamba.threshold(imIn, imWrk1, 0, 0)
    nb1 = mamba.label(imWrk1, imWrk2)
    mamba.convertByMask(imWrk1, imOut, mamba.computeMaxRange(imOut)[1], 0)
    mamba.logic(imOut, imWrk2, imOut, "sup")
    nb2 = mamba.label(imIn, imWrk2)
    mamba.addConst(imWrk2, nb1, imWrk2)
    mamba.logic(imOut, imWrk2, imOut, "inf")
    return nb1 + nb2
Пример #20
0
def nonEqualNeighbors(imIn,
                      imOut,
                      nb,
                      grid=mamba.DEFAULT_GRID,
                      edge=mamba.FILLED):
    """
    This operator compares the value of each pixel of image 'imIn'
    with the value of its neighbors encoded in 'nb'.
    If all the neighbor values are different, the pixel is unchanged.
    Otherwise, it takes value 0.
    This operator works on hexagonal or square 'grid' and
    'edge' is set to FILLED by default.
    This operator works for 8-bit and 32-bit images.
    """

    imWrk1 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn)
    imWrk3 = mamba.imageMb(imIn, 1)
    imWrk4 = mamba.imageMb(imIn, 1)
    for d in mamba.getDirections(grid):
        ed = 1 << d
        if (nb & ed):
            mamba.copy(imIn, imWrk1)
            mamba.copy(imIn, imWrk2)
            mamba.supNeighbor(imWrk1, imWrk1, ed, grid=grid, edge=edge)
            mamba.infNeighbor(imWrk2, imWrk2, ed, grid=grid, edge=edge)
            mamba.generateSupMask(imWrk2, imWrk1, imWrk3, False)
            mamba.logic(imWrk4, imWrk3, imWrk4, "or")
    mamba.convertByMask(imWrk4, imWrk1, mamba.computeMaxRange(imIn)[1], 0)
    mamba.logic(imIn, imWrk1, imOut, "inf")
Пример #21
0
def multiplePoints(imIn, imOut, grid=mamba.DEFAULT_GRID):
    """
    Extracts multiple points in 'imIn', supposed to be a "skeleton" image (connected 
    components without thickness), and puts the result in 'imOut'.
    
    Note that, on a square grid, the resulting skeleton is supposed to be defined 
    on a 4-connectivity grid. if it is not the case, some multiple points are likely
    to be missed.
    """
    
    imWrk1 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn)
    endPoints(imIn, imWrk2)
    if grid == mamba.HEXAGONAL:
        dse_list = [hexagonalS1, hexagonalS2]
        step = 1
        nb = 6
    else:
        dse_list = [squareS1, squareS2]
        step = 2
        nb = 4
    for dse in dse_list:
        for i in range(nb):
            hitOrMiss(imIn, imWrk1, dse)
            mamba.logic(imWrk1, imWrk2, imWrk2, "sup")
            dse = dse.rotate(step)
    mamba.diff(imIn, imWrk2, imOut)
Пример #22
0
def endPoints(imIn, imOut, grid=mamba.DEFAULT_GRID, edge=mamba.FILLED):
    """
    Extracts end points in 'imIn', supposed to be a "skeleton" image (connected 
    components without thickness), and puts them in 'imOut'.
    
    'edge' is FILLED by default and it can be modified to take into account
    extremities touching the edge.
    """
    
    imWrk1 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn)
    if grid == mamba.HEXAGONAL:
        dse1 = hexagonalE
        dse2 = hexagonalL
        nb = 6
        step = 1
    else:
        dse1 = squareE
        dse2 = squareL
        nb = 4
        step = 2
    rotatingThin(imIn, imWrk1, dse2, edge=edge)
    # added to avoid blocking of the process in clipping
    mamba.diff(imIn, imWrk1, imOut)
    for i in range(nb):
        hitOrMiss(imWrk1, imWrk2, dse1, edge=edge)
        mamba.logic(imOut, imWrk2, imOut, "sup")
        dse1 = dse1.rotate(step)
Пример #23
0
def rotatingThin(imIn, imOut, dse, edge=mamba.FILLED):
    """
    Performs a complete rotation of thinnings , the initial 'dse' double
    structuring element being turned one step clockwise after each thinning.
    At each rotation step, the previous result is used as input for the next
    thinning (chained thinnings). Depending on the grid where 'dse' is defined,
    6 or 8 rotations are performed.
    
    'imIn' and 'imOut' are binary images.
    
    'edge' is set to FILLED by default (default value is EMPTY in simple thin).
    """
    
    imWrk = mamba.imageMb(imIn)
    if edge == mamba.FILLED:
        mamba.negate(imIn, imOut)
        for d in mamba.getDirections(dse.getGrid(), True):
            hitOrMiss(imOut, imWrk, dse.flip(), edge=mamba.EMPTY)
            mamba.logic(imWrk, imOut, imOut, "sup")
            dse = dse.rotate()
        mamba.negate(imOut, imOut)
    else:
        mamba.copy(imIn, imOut)
        for d in mamba.getDirections(dse.getGrid(), True):
            hitOrMiss(imOut, imWrk, dse, edge=mamba.EMPTY)
            mamba.diff(imOut, imWrk, imOut)
            dse = dse.rotate()
Пример #24
0
def geodesicThick(imIn, imMask, imOut, dse):
    """
    Geodesic thickening of image 'imIn' inside 'imMask' by the double
    structuring element 'dse'. The result is stored in 'imOut'.
    
    'imIn', 'imMask' and 'imOut' are binary images.
    """

    thick(imIn, imOut, dse)
    mamba.logic(imOut, imMask, imOut, "inf")
Пример #25
0
def geodesicThick(imIn, imMask, imOut, dse):
    """
    Geodesic thickening of image 'imIn' inside 'imMask' by the double
    structuring element 'dse'. The result is stored in 'imOut'.
    
    'imIn', 'imMask' and 'imOut' are binary images.
    """
    
    thick(imIn, imOut, dse)
    mamba.logic(imOut, imMask, imOut, "inf")
Пример #26
0
def thick(imIn, imOut, dse):
    """
    Elementary thickening operator with 'dse' double structuring element. The
    
    'imIn' and 'imOut' are binary images.
    
    The edge is always EMPTY (as for hitOrMiss).
    """
    
    imWrk = mamba.imageMb(imIn)
    hitOrMiss(imIn, imWrk, dse, edge=mamba.EMPTY)
    mamba.logic(imIn, imWrk, imOut, "or") 
Пример #27
0
def thick(imIn, imOut, dse):
    """
    Elementary thickening operator with 'dse' double structuring element. The
    
    'imIn' and 'imOut' are binary images.
    
    The edge is always EMPTY (as for hitOrMiss).
    """

    imWrk = mamba.imageMb(imIn)
    hitOrMiss(imIn, imWrk, dse, edge=mamba.EMPTY)
    mamba.logic(imIn, imWrk, imOut, "or")
Пример #28
0
def multiSuperpose(imInout, *imIns):
    """
    Superposes multiple binary images ('imIns') to the greyscale image
    'imInout'. The binary images are put above the greyscale. The
    result is meant to be seen with an appropriate color palette.
    """
    imWrk = mamba.imageMb(imInout)
    
    mamba.subConst(imInout, len(imIns), imInout)
    for i,im in enumerate(imIns):
        mamba.convertByMask(im, imWrk, 0, 256-len(imIns)+i)
        mamba.logic(imInout, imWrk, imInout, "sup")
Пример #29
0
def segmentByP(imIn, imOut, gain=2.0, grid=mamba.DEFAULT_GRID):
    """
    General segmentation by P algorithm. This algorithm keeps or reintroduces
    the contours of the initial watershed transform which are above or equal to
    the hierarchical image associated to the next level of hierarchy when the
    altitude of the contour is multiplied by a 'gain' factor (default is 2.0).
    This transform also ends by idempotence. All the hierarchical levels of
    image 'imIn' (which is a valued watershed) are computed. 'imOut' contains all
    these hierarchies which are embedded, so that hierarchy i is simply obtained
    by a threshold [i+1, 255] of image imOut.
    'imIn' and 'imOut' must be greyscale images. 'imIn' and 'imOut' must be
    different.
    This transformation returns the number of hierarchical levels.    
    """
    
    imWrk0 = mamba.imageMb(imIn)
    imWrk1 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn)
    imWrk3 = mamba.imageMb(imIn)
    imWrk4 = mamba.imageMb(imIn, 1)
    imWrk5 = mamba.imageMb(imIn, 32)    
    mamba.copy(imIn, imWrk1)
    mamba.mulRealConst(imIn, gain, imWrk5)
    mamba.floorSubConst(imWrk5, 1, imWrk5)
    mamba.threshold(imWrk5, imWrk4, 255, mamba.computeMaxRange(imWrk5)[1])  
    mamba.copyBytePlane(imWrk5, 0, imWrk0)
    mamba.convert(imWrk4, imWrk2)
    mamba.logic(imWrk0, imWrk2, imWrk0, "sup")
    mamba.logic(imWrk0, imWrk1, imWrk0, "sup")
    imOut.reset()
    nbLevels = 0
    mamba.threshold(imWrk1, imWrk4, 1, 255)
    flag = not(mamba.checkEmptiness(imWrk4))
    while flag:
        hierarchy(imWrk1, imWrk4, imWrk2, grid=grid)
        mamba.add(imOut, imWrk4, imOut)
        mamba.valuedWatershed(imWrk2, imWrk3, grid=grid)
        mamba.threshold(imWrk3, imWrk4, 1, 255)
        flag = not(mamba.checkEmptiness(imWrk4))
        hierarchy(imWrk3, imWrk4, imWrk2, grid=grid)
        mamba.generateSupMask(imWrk0, imWrk2, imWrk4, strict=False)
        mamba.convertByMask(imWrk4, imWrk3, 0, 255)
        mamba.logic(imWrk1, imWrk3, imWrk3, "inf")
        mamba.negate(imWrk4, imWrk4)
        mamba.label(imWrk4, imWrk5, grid=grid)
        mamba.watershedSegment(imWrk3, imWrk5, grid=grid)
        mamba.copyBytePlane(imWrk5, 3, imWrk3)
        mamba.logic(imWrk1, imWrk2, imWrk1, "sup")
        mamba.logic(imWrk1, imWrk3, imWrk1, "inf")
        mamba.threshold(imWrk1, imWrk4, 1, 255)
        nbLevels += 1
    return nbLevels
Пример #30
0
def segmentByP(imIn, imOut, gain=2.0, grid=mamba.DEFAULT_GRID):
    """
    General segmentation by P algorithm. This algorithm keeps or reintroduces
    the contours of the initial watershed transform which are above or equal to
    the hierarchical image associated to the next level of hierarchy when the
    altitude of the contour is multiplied by a 'gain' factor (default is 2.0).
    This transform also ends by idempotence. All the hierarchical levels of
    image 'imIn' (which is a valued watershed) are computed. 'imOut' contains all
    these hierarchies which are embedded, so that hierarchy i is simply obtained
    by a threshold [i+1, 255] of image imOut.
    'imIn' and 'imOut' must be greyscale images. 'imIn' and 'imOut' must be
    different.
    This transformation returns the number of hierarchical levels.    
    """

    imWrk0 = mamba.imageMb(imIn)
    imWrk1 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn)
    imWrk3 = mamba.imageMb(imIn)
    imWrk4 = mamba.imageMb(imIn, 1)
    imWrk5 = mamba.imageMb(imIn, 32)
    mamba.copy(imIn, imWrk1)
    mamba.mulRealConst(imIn, gain, imWrk5)
    mamba.floorSubConst(imWrk5, 1, imWrk5)
    mamba.threshold(imWrk5, imWrk4, 255, mamba.computeMaxRange(imWrk5)[1])
    mamba.copyBytePlane(imWrk5, 0, imWrk0)
    mamba.convert(imWrk4, imWrk2)
    mamba.logic(imWrk0, imWrk2, imWrk0, "sup")
    mamba.logic(imWrk0, imWrk1, imWrk0, "sup")
    imOut.reset()
    nbLevels = 0
    mamba.threshold(imWrk1, imWrk4, 1, 255)
    flag = not (mamba.checkEmptiness(imWrk4))
    while flag:
        hierarchy(imWrk1, imWrk4, imWrk2, grid=grid)
        mamba.add(imOut, imWrk4, imOut)
        mamba.valuedWatershed(imWrk2, imWrk3, grid=grid)
        mamba.threshold(imWrk3, imWrk4, 1, 255)
        flag = not (mamba.checkEmptiness(imWrk4))
        hierarchy(imWrk3, imWrk4, imWrk2, grid=grid)
        mamba.generateSupMask(imWrk0, imWrk2, imWrk4, strict=False)
        mamba.convertByMask(imWrk4, imWrk3, 0, 255)
        mamba.logic(imWrk1, imWrk3, imWrk3, "inf")
        mamba.negate(imWrk4, imWrk4)
        mamba.label(imWrk4, imWrk5, grid=grid)
        mamba.watershedSegment(imWrk3, imWrk5, grid=grid)
        mamba.copyBytePlane(imWrk5, 3, imWrk3)
        mamba.logic(imWrk1, imWrk2, imWrk1, "sup")
        mamba.logic(imWrk1, imWrk3, imWrk1, "inf")
        mamba.threshold(imWrk1, imWrk4, 1, 255)
        nbLevels += 1
    return nbLevels
Пример #31
0
def cellsExtract(imIn, imMarkers, imOut, grid=mamba.DEFAULT_GRID):
    """
    Geodesic reconstruction and extraction of the cells of the partition image
    'imIn' which are marked by the binary marker image 'imMarkers'. The marked
    cells keep their initial value. The result is stored in 'imOut'.
    The images can be 8-bit or 32-bit images.
    'grid' can be set to HEXAGONAL or SQUARE.
    """
    
    imWrk1 = mamba.imageMb(imIn)
    mamba.convertByMask(imMarkers, imWrk1, 0, mamba.computeMaxRange(imIn)[1])
    mamba.logic(imIn, imWrk1, imOut, "inf")
    cellsBuild(imIn, imOut, grid=grid)
Пример #32
0
def markerControlledWatershed(imIn, imMarkers, imOut, grid=mamba.DEFAULT_GRID):
    """
    Marker-controlled watershed transform of greytone image 'imIn'. The binary
    image 'imMarkers' contains the markers which control the flooding process.
    'imOut' contains the valued watershed.
    """

    im_mark = mamba.imageMb(imIn, 32)
    imWrk = mamba.imageMb(imIn)
    label(imMarkers, im_mark, grid=grid)
    watershedSegment(imIn, im_mark, grid=grid)
    mamba.copyBytePlane(im_mark, 3, imWrk)
    mamba.logic(imWrk, imIn, imOut, 'inf')
Пример #33
0
def markerControlledWatershed(imIn, imMarkers, imOut, grid=mamba.DEFAULT_GRID):
    """
    Marker-controlled watershed transform of greytone image 'imIn'. The binary
    image 'imMarkers' contains the markers which control the flooding process.
    'imOut' contains the valued watershed.
    """

    im_mark = mamba.imageMb(imIn, 32)
    imWrk = mamba.imageMb(imIn)
    label(imMarkers, im_mark, grid=grid)
    watershedSegment(imIn, im_mark, grid=grid)
    mamba.copyBytePlane(im_mark, 3, imWrk)
    mamba.logic(imWrk, imIn, imOut, "inf")
Пример #34
0
def cellsExtract(imIn, imMarkers, imOut, grid=mamba.DEFAULT_GRID):
    """
    Geodesic reconstruction and extraction of the cells of the partition image
    'imIn' which are marked by the binary marker image 'imMarkers'. The marked
    cells keep their initial value. The result is stored in 'imOut'.
    The images can be 8-bit or 32-bit images.
    'grid' can be set to HEXAGONAL or SQUARE.
    """

    imWrk1 = mamba.imageMb(imIn)
    mamba.convertByMask(imMarkers, imWrk1, 0, mamba.computeMaxRange(imIn)[1])
    mamba.logic(imIn, imWrk1, imOut, "inf")
    cellsBuild(imIn, imOut, grid=grid)
Пример #35
0
def upperGeodesicErode(imIn, imMask, imOut, n=1, se=mamba.DEFAULT_SE):
    """
    Performs a upper geodesic erosion of image 'imIn' above 'imMask'.
    The result is put inside 'imOut', 'n' controls the size of the erosion.
    'se' specifies the type of structuring element used to perform the 
    computation (DEFAULT_SE by default).
    
    Warning! 'imMask' and 'imOut' must be different.
    """
    
    mamba.logic(imIn, imMask, imOut, "sup")
    for i in range(n):
        mamba.erode(imOut, imOut, se=se)
        mamba.logic(imOut, imMask, imOut, "sup")
Пример #36
0
def upperGeodesicDilate(imIn, imMask, imOut, n=1, se=mamba.DEFAULT_SE):
    """
    Performs an upper geodesic dilation of image 'imIn' above 'imMask'.
    The result is put inside 'imOut', 'n' controls the size of the dilation.
    'se' specifies the type of structuring element used to perform the 
    computation (DEFAULT_SE by default). 
    
    Warning! 'imMask' and 'imOut' must be different.
    """
    
    mamba.logic(imIn, imMask, imOut, "sup")
    if imIn.getDepth() == 1:
        for i in range(n):
            mamba.diff(imOut, imMask, imOut)
            mamba.dilate(imOut, imOut, se=se)
            mamba.logic(imMask, imOut, imOut, "sup")
    else:
        imWrk1 = mamba.imageMb(imIn)
        imWrk2 = mamba.imageMb(imIn, 1)
        for i in range(n):
            mamba.generateSupMask(imOut, imMask, imWrk2, True)
            mamba.convertByMask(imWrk2, imWrk1, 0, mamba.computeMaxRange(imWrk1)[1])
            mamba.logic(imOut, imWrk1, imOut, "inf")
            mamba.dilate(imOut, imOut, se=se)
            mamba.logic(imOut, imMask, imOut, "sup")
Пример #37
0
def linearClose(imIn, imOut, dir, n, grid=mamba.DEFAULT_GRID, edge=mamba.FILLED):
    """
    Performs a closing by a segment of size 'n' in direction 'dir'.
    
    If 'edge' is set to 'EMPTY', the operation must be modified to remain extensive.
    """
    
    imWrk = mamba.imageMb(imIn)
    if edge==mamba.EMPTY:
        mamba.copy(imIn, imWrk)
    mamba.linearDilate(imIn, imOut, dir, n, grid=grid)
    mamba.linearErode(imOut, imOut, mamba.transposeDirection(dir, grid=grid), n, edge=edge, grid=grid)
    if edge==mamba.EMPTY:
        mamba.logic(imOut, imWrk, imOut, "sup")
Пример #38
0
def closeHoles(imIn, imOut, grid=mamba.DEFAULT_GRID):
    """
    Close holes in image 'imIn' and puts the result in 'imOut'. This operator
    works on binary and greytone images. In this case, however, it should be 
    used cautiously.
    """
    
    imWrk = mamba.imageMb(imIn)
    mamba.negate(imIn, imIn)
    mamba.drawEdge(imWrk)
    mamba.logic(imIn, imWrk, imWrk, "inf")
    build(imIn, imWrk, grid=grid)
    mamba.negate(imIn, imIn)
    mamba.negate(imWrk, imOut)
Пример #39
0
def removeEdgeParticles(imIn, imOut, grid=mamba.DEFAULT_GRID):
    """
    Removes particles (connected components) touching the edge in image 'imIn'.
    The resulting image is put in image 'imOut'.
    Although this operator may be used with greytone images, it should be
    considered with caution.
    """
    
    imWrk = mamba.imageMb(imIn)
    se = mamba.structuringElement(mamba.getDirections(grid), grid)
    mamba.dilate(imWrk, imWrk, se=se, edge=mamba.FILLED)
    mamba.logic(imIn, imWrk, imWrk, "inf")
    build(imIn, imWrk, grid=grid)
    mamba.diff(imIn, imWrk, imOut)
Пример #40
0
def minPartialBuild(imIn, imMask, imOut, grid=mamba.DEFAULT_GRID):
    """
    Performs the partial reconstruction of 'imIn' with its minima which are
    contained in the binary mask 'imMask'. The result is put in 'imOut'.
    
    'imIn' and 'imOut' must be different and greyscale images.
    """
    
    imWrk = mamba.imageMb(imIn, 1)
    minima(imIn, imWrk, 1, grid=grid)
    mamba.logic(imMask, imWrk, imWrk, "inf")
    mamba.convertByMask(imWrk, imOut, mamba.computeMaxRange(imIn)[1], 0)
    mamba.logic(imIn, imOut, imOut, "sup")
    mamba.dualBuild(imIn, imOut)
Пример #41
0
def geodesicSKIZ(imIn, imMask, imOut, grid=mamba.DEFAULT_GRID):
    """
    Geodesic skeleton by zones of influence of binary image 'imIn' inside the
    geodesic mask 'imMask'. The result is in binary image 'imOut'.
    """

    imWrk1 = mamba.imageMb(imIn, 8)
    imWrk2 = mamba.imageMb(imIn)
    mamba.copy(imIn, imWrk2)
    mamba.build(imMask, imWrk2, grid=grid)
    mamba.convertByMask(imWrk2, imWrk1, 2, 1)
    mamba.sub(imWrk1, imIn, imWrk1)
    markerControlledWatershed(imWrk1, imIn, imWrk1, grid=grid)
    mamba.threshold(imWrk1, imOut, 0, 0)
    mamba.logic(imOut, imWrk2, imOut, "inf")
Пример #42
0
def floorSubConst(imIn, v, imOut):
    """
    Subtracts a constant value 'v' to image 'imIn' and puts the result in 'imOut'.
    If imIn - v is negative, the result is truncated and limited to 0.
    
    Note that this operator is mainly useful for 32-bit images, as the result
    of the subtraction is always truncated for 8-bit images.
    """
    
    imMask = mamba.imageMb(imIn, 1)
    imWrk = mamba.imageMb(imIn)
    mamba.subConst(imIn, v, imWrk)
    mamba.generateSupMask(imIn, imWrk, imMask, False)
    mamba.convertByMask(imMask, imOut, 0, mamba.computeMaxRange(imOut)[1])
    mamba.logic(imOut, imWrk, imOut, "inf")
Пример #43
0
def geodesicSKIZ(imIn, imMask, imOut, grid=mamba.DEFAULT_GRID):
    """
    Geodesic skeleton by zones of influence of binary image 'imIn' inside the
    geodesic mask 'imMask'. The result is in binary image 'imOut'.
    """

    imWrk1 = mamba.imageMb(imIn, 8)
    imWrk2 = mamba.imageMb(imIn)
    mamba.copy(imIn, imWrk2)
    mamba.build(imMask, imWrk2, grid=grid)
    mamba.convertByMask(imWrk2, imWrk1, 2, 1)
    mamba.sub(imWrk1, imIn, imWrk1)
    markerControlledWatershed(imWrk1, imIn, imWrk1, grid=grid)
    mamba.threshold(imWrk1, imOut, 0, 0)
    mamba.logic(imOut, imWrk2, imOut, "inf")
Пример #44
0
def cellsErode(imIn, imOut, n=1, se=mamba.DEFAULT_SE, edge=mamba.FILLED):
    """
    Simultaneous erosion of size 'n' (default 1) of all the cells of the
    partition image 'imIn' with 'se' structuring element.
    The resulting partition is put in 'imOut'.
    'edge' is set to FILLED by default.
    This operation works on 8-bit and 32-bit partitions.
    """

    imWrk1 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn, 1)
    mamba.dilate(imIn, imWrk1, n=n, se=se)
    mamba.erode(imIn, imOut, n=n, se=se, edge=edge)
    mamba.generateSupMask(imOut, imWrk1, imWrk2, False)
    mamba.convertByMask(imWrk2, imWrk1, 0, mamba.computeMaxRange(imIn)[1])
    mamba.logic(imOut, imWrk1, imOut, "inf")
Пример #45
0
def dilateByCylinder3D(imInOut, height, section):
    """
    Dilates 3D image 'imInOut' using a cylinder with an hexagonal section of size 
    2x'section' and a height of 2x'height'. The image is modified by this
    function. The edge is always set to EMPTY.
    """
    
    l = len(imInOut)
    for im in imInOut:
        mamba.dilate(im, im, section, se=mamba.HEXAGON)
    provIm3D = m3D.image3DMb(imInOut)
    for i in range(l):
        mamba.copy(imInOut[i], provIm3D[i])
        for j in range(max(0,i-height), min(l,i+height+1)):
            mamba.logic(provIm3D[i], imInOut[j], provIm3D[i], "sup")
    m3D.copy3D(provIm3D, imInOut)
Пример #46
0
def closing(imIn, imOut, n=1, se=mamba.DEFAULT_SE, edge=mamba.FILLED):
    """
    Performs a closing operation on image 'imIn' and puts the result in 'imOut'.
    'n' controls the size of the closing and 'se' the structuring element used.
    
    The default edge is set to 'FILLED'. If 'edge' is set to 'EMPTY', the operation
    is slightly modified to avoid errors (non extensivity).
    """

    imWrk = mamba.imageMb(imIn)
    if edge == mamba.EMPTY:
        mamba.copy(imIn, imWrk)
    mamba.dilate(imIn, imOut, n, se=se)
    mamba.erode(imOut, imOut, n, se=se.transpose(), edge=edge)
    if edge == mamba.EMPTY:
        mamba.logic(imOut, imWrk, imOut, "sup")
Пример #47
0
def cellsErode(imIn, imOut, n=1, se=mamba.DEFAULT_SE, edge=mamba.FILLED):
    """
    Simultaneous erosion of size 'n' (default 1) of all the cells of the
    partition image 'imIn' with 'se' structuring element.
    The resulting partition is put in 'imOut'.
    'edge' is set to FILLED by default.
    This operation works on 8-bit and 32-bit partitions.
    """
    
    imWrk1 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn, 1)
    mamba.dilate(imIn, imWrk1, n=n, se=se)
    mamba.erode(imIn, imOut, n=n, se=se, edge=edge)
    mamba.generateSupMask(imOut, imWrk1, imWrk2, False)
    mamba.convertByMask(imWrk2, imWrk1, 0, mamba.computeMaxRange(imIn)[1])
    mamba.logic(imOut, imWrk1, imOut, "inf")
Пример #48
0
def directionalClose(imIn, imOut, d, size, grid=mamba.DEFAULT_GRID, edge=mamba.FILLED):
    """
    Directional closing of image 'imIn' defined by combining a dilation in
    direction 'd' followed by an erosion in the transposed direction (which
    depends on the grid in use). Result is put in 'imOut'.
    If 'edge' is set to 'EMPTY', the operation must be modified to remain extensive.
    """
    
    imWrk = mamba.imageMb(imIn)
    if edge==mamba.EMPTY:
        mamba.copy(imIn, imWrk)
    directionalDilate(imIn, imOut, d, size, grid=grid, edge=edge)
    j = (d + mamba.gridNeighbors(grid=grid) - 1) % (mamba.gridNeighbors(grid=grid) * 2) + 1
    directionalErode(imOut, imOut, j, size, grid=grid)
    if edge==mamba.EMPTY:
        mamba.logic(imOut, imWrk, imOut, "sup")