Esempio n. 1
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)
Esempio n. 2
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)
Esempio n. 3
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)
Esempio n. 4
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")
Esempio n. 5
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)
Esempio n. 6
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")
Esempio n. 7
0
def cellsThin(imIn, imOut, dse, edge=mamba.EMPTY):
    """
    Performs a simple thinning transform 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.
    """
    
    imWrk = mamba.imageMb(imIn)
    cellsHMT(imIn, imWrk, dse, edge=edge)
    mamba.sub(imIn, imWrk, imOut)
Esempio n. 8
0
def cellsThin(imIn, imOut, dse, edge=mamba.EMPTY):
    """
    Performs a simple thinning transform 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.
    """

    imWrk = mamba.imageMb(imIn)
    cellsHMT(imIn, imWrk, dse, edge=edge)
    mamba.sub(imIn, imWrk, imOut)
Esempio n. 9
0
def blackTopHat(imIn, imOut, n, se=mamba.DEFAULT_SE):
    """
    Performs a black Top Hat operation on 'imIn' and puts the result in 'imOut'.
    This operator extracts from 'imIn' the dark objects thinner than 2*'n'+1. 
    
    The structuring element used is defined by 'se' ('DEFAULT_SE' by default).
    """
    
    imWrk = mamba.imageMb(imIn)
    mamba.closing(imIn, imWrk, n, se=se)
    mamba.sub(imWrk, imIn, imOut)
Esempio n. 10
0
def supBlackTopHat(imIn, imOut, n, grid=mamba.DEFAULT_GRID):
    """
    Performs a black Top Hat operation with the infimum of directional openings
    on 'imIn' and puts the result in 'imOut'.
    This operator partly extracts from 'imIn' the dark objects whose extension
    in at least one direction of 'grid' is smaller than 'n'.
    """
    
    imWrk = mamba.imageMb(imIn)
    mamba.infClose(imIn, imWrk, n, grid=grid)
    mamba.sub(imWrk, imIn, imOut)
Esempio n. 11
0
def gradient(imIn, imOut, n=1, se=mamba.DEFAULT_SE):
    """
    Computes the morphological gradient of image 'imIn' and puts the result in 
    'imOut'. The thickness can be controlled using parameter 'n' (1 by default).
    The structuring element used by the erosion and dilation is defined by 'se'
    (DEFAULT_SE by default).
    """
    
    imWrk = mamba.imageMb(imIn)
    mamba.erode(imIn, imWrk, n, se=se)
    mamba.dilate(imIn, imOut, n, se=se)
    mamba.sub(imOut, imWrk, imOut)
Esempio n. 12
0
def contrastEnhancer(imIn, imOut, n=1, se=mamba.DEFAULT_SE):
    """
    Increase the contrast of image 'imIn' and put the result in
    image 'imOut'. Parameter 'n' will control the size and 'se' the
    structuring element used by the top hat operators.
    """

    imWrk = mamba.imageMb(imIn)
    mamba.whiteTopHat(imIn, imWrk, n, se=se)
    mamba.add(imIn, imWrk, imOut)
    mamba.blackTopHat(imIn, imWrk, n, se=se)
    mamba.sub(imOut, imWrk, imOut) 
Esempio n. 13
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")
Esempio n. 14
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")
Esempio n. 15
0
def floorSub(imIn1, imIn2, imOut):
    """
    Subtracts image 'imIn2' from image 'imIn1' and puts the result in 'imOut'.
    If imIn1 - imIn2 is negative, the result is truncated and limited to 0.
    
    Although it is possible to use a 8-bit image for imIn2, it is recommended to
    use the same depth for all the images.
    
    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(imIn1, 1)
    imWrk = mamba.imageMb(imIn1)
    mamba.sub(imIn1, imIn2, imWrk)
    mamba.generateSupMask(imIn1, imWrk, imMask, False)
    mamba.convertByMask(imMask, imOut, 0, mamba.computeMaxRange(imOut)[1])
    mamba.logic(imOut, imWrk, imOut, "inf")
Esempio n. 16
0
def maxDynamics(imIn, imOut, h, grid=mamba.DEFAULT_GRID):
    """
    Extracts the maxima of 'imIn' with a dynamics higher or equal to 'h'
    and puts the result in 'imOut'.
    
    Grid used by the dual build operation can be specified by 'grid'.
    
    Only works with 8-bit or 32-bit images as input. 'imOut' must be binary.
    """
    
    imWrk = mamba.imageMb(imIn)
    if imIn.getDepth() == 8:
        mamba.subConst(imIn, h, imWrk)
        mamba.hierarBuild(imIn, imWrk, grid=grid)
        mamba.sub(imIn, imWrk, imWrk)
    else:
        mamba.floorSubConst(imIn, h, imWrk)
        mamba.build(imIn, imWrk, grid=grid)
        mamba.floorSub(imIn, imWrk, imWrk)
    mamba.threshold(imWrk, imOut, h, mamba.computeMaxRange(imIn)[1])
Esempio n. 17
0
def maxima(imIn, imOut, h=1, grid=mamba.DEFAULT_GRID):
    """
    Computes the maxima of 'imIn' using a build operation and puts the result in
    'imOut'. When 'h' is equal to 1 (default value), the operator provides the
    maxima of 'imIn'.
    
    Grid used by the build operation can be specified by 'grid'.
    
    Only works with with 8-bit or 32-bit images as input. 'imOut' must be binary.
    """
    
    imWrk = mamba.imageMb(imIn)
    if imIn.getDepth() == 8:
        mamba.subConst(imIn, h, imWrk)
        mamba.hierarBuild(imIn, imWrk, grid=grid)
        mamba.sub(imIn, imWrk, imWrk)
    else:
        mamba.floorSubConst(imIn, h, imWrk)
        mamba.build(imIn, imWrk, grid=grid)
        mamba.floorSub(imIn, imWrk, imWrk)
    mamba.threshold(imWrk, imOut, 1, mamba.computeMaxRange(imIn)[1])
Esempio n. 18
0
def halfGradient(imIn, imOut, type="intern", n=1, se=mamba.DEFAULT_SE):
    """
    Computes the half morphological gradient of image 'imIn' ond puts the result
    in 'imOut'.
    
    'type' indicates if the half gradient should be internal or external. 
    Possible values are :
        "extern" : dilation(imIn) - imIn
        "intern" : imIn - erosion(imIn)
    
    The thickness can be controlled using parameter 'n' (1 by default). The 
    structuring element used by the erosion or the dilation is defined by 'se'.
    """
    
    imWrk = mamba.imageMb(imIn)
    if type=="extern":
        mamba.dilate(imIn, imWrk, n, se=se)
        mamba.sub(imWrk, imIn, imOut)
    else:
        mamba.erode(imIn, imWrk, n, se=se)
        mamba.sub(imIn, imWrk, imOut)
Esempio n. 19
0
def ultimateOpening(imIn, imOut1, imOut2, grid=mamba.DEFAULT_GRID):
    """
    Ultimate opening of image 'imIn'. 'imOut1' contains the ultimate 
    opening whereas 'imOut2' contains the granulometric function.
    
    Ultimate opening is obtained by using successive openings by hexagons or
    squares as primitive functions depending of the grid in use.
    
    Depth of 'imOut1' is the same as 'imIn', depth of 'imOut2' is 32. 
    """

    maskIm = mamba.imageMb(imIn, 1)
    imWrk1 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn)
    imWrk3 = mamba.imageMb(imIn, 32)
    imWrk4 = mamba.imageMb(imIn)
    se = mamba.structuringElement(mamba.getDirections(grid), grid)
    i = 0
    mamba.copy(imIn, imWrk1)
    v2 = mamba.computeVolume(imWrk1)
    mamba.copy(imWrk1, imWrk4)
    v1 = v2 + 1
    imOut1.reset()
    imOut2.reset()
    if grid == mamba.HEXAGONAL:
        dilation = mamba.largeHexagonalDilate
    else:
        dilation = mamba.largeSquareDilate
    while v1 > v2:
        i += 1
        v1 = v2
        mamba.erode(imWrk4, imWrk4, se=se)
        dilation(imWrk4, imWrk2, i)
        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")
        v2 = mamba.computeVolume(imWrk4)
        mamba.copy(imWrk2, imWrk1)
Esempio n. 20
0
def ultimateIsotropicOpening(imIn, imOut1, imOut2, step =1, grid=mamba.DEFAULT_GRID):
    """
    Ultimate opening of image 'imIn' with more isotropic structuring elements.
    Dodecagons are used on hexagonal grid, octogons on square grid. 'imOut1' 
    contains the ultimate opening whereas 'imOut2' contains the granulometric
    function. 'step' is the increment of the size of the openings. Its default
    value is 1 but it can be increased to reduce the computation time.

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

    maskIm = mamba.imageMb(imIn, 1)
    imWrk1 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn)
    imWrk3 = mamba.imageMb(imIn, 32)
    i = 0
    mamba.copy(imIn, imWrk1)
    v2 = mamba.computeVolume(imWrk1)
    v1 = v2 + 1
    imOut1.reset()
    imOut2.reset()
    if grid == mamba.HEXAGONAL:
        iso_dilation = mamba.largeDodecagonalDilate
        iso_erosion = mamba.largeDodecagonalErode
    else:
        iso_dilation = mamba.largeOctogonalDilate
        iso_erosion = mamba.largeOctogonalErode
    while v1 > v2:
        i += step
        v1 = v2
        iso_erosion(imWrk1, imWrk2, i)
        v2 = mamba.computeVolume(imWrk2)
        iso_dilation(imWrk2, imWrk2, i)
        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)
Esempio n. 21
0
def sub3D(imIn1, imIn2, imOut):
    """
    Subtracts 'imIn2' pixel values to 'imIn1' pixel values and put the result 
    in 'imOut'. The operation can be sum up in the following formula:
    
    imOut = imIn1 - imIn2

    You can mix formats in the subtraction operation (a binary image can be
    subtracted to a greyscale image, etc...). 
    However you must ensure that the output image is as deep as the deepest of 
    the two subtracted images.
    
    The operation is also saturated for grey-scale images (e.g. on a grey scale 
    image 0-1=0) but not for 32-bit images.
    """
    outl = len(imOut)
    in1l = len(imIn1)
    in2l = len(imIn2)
    if in1l != outl or in2l != outl:
        mamba.raiseExceptionOnError(core.MB_ERR_BAD_SIZE)

    for i in range(outl):
        mamba.sub(imIn1[i], imIn2[i], imOut[i])
Esempio n. 22
0
def sub3D(imIn1, imIn2, imOut):
    """
    Subtracts 'imIn2' pixel values to 'imIn1' pixel values and put the result 
    in 'imOut'. The operation can be sum up in the following formula:
    
    imOut = imIn1 - imIn2

    You can mix formats in the subtraction operation (a binary image can be
    subtracted to a greyscale image, etc...). 
    However you must ensure that the output image is as deep as the deepest of 
    the two subtracted images.
    
    The operation is also saturated for grey-scale images (e.g. on a grey scale 
    image 0-1=0) but not for 32-bit images.
    """
    outl = len(imOut)
    in1l = len(imIn1)
    in2l = len(imIn2)
    if in1l!=outl or in2l!=outl:
        mamba.raiseExceptionOnError(core.MB_ERR_BAD_SIZE)

    for i in range(outl):
        mamba.sub(imIn1[i], imIn2[i], imOut[i])
Esempio n. 23
0
def ultimateBuildOpening(imIn, imOut1, imOut2, grid=mamba.DEFAULT_GRID):
    """
    Ultimate opening  by build of image 'imIn'. 'imOut1' contains the ultimate
    opening whereas 'imOut2' contains the granulometric function.
    
    This ultimate opening is obtained by using successive openings by build.
    
    Depth of 'imOut1' is the same as 'imIn', depth of 'imOut2' is 32. 
    """

    maskIm = mamba.imageMb(imIn, 1)
    imWrk1 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn)
    imWrk3 = mamba.imageMb(imIn, 32)
    imWrk4 = mamba.imageMb(imIn)
    se = mamba.structuringElement(mamba.getDirections(grid), grid)
    i = 0
    mamba.copy(imIn, imWrk1)
    v2 = mamba.computeVolume(imWrk1)
    mamba.copy(imWrk1, imWrk4)
    v1 = v2 + 1
    imOut1.reset()
    imOut2.reset()
    while v1 > v2:
        i += 1
        v1 = v2
        mamba.erode(imWrk4, imWrk4, se=se)
        mamba.copy(imWrk4, imWrk2)
        mamba.hierarBuild(imWrk1, imWrk2, grid=mamba.DEFAULT_GRID)
        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")
        v2 = mamba.computeVolume(imWrk4)
        mamba.copy(imWrk2, imWrk1)
Esempio n. 24
0
def skeletonByOpening(imIn, imOut1, imOut2, grid=mamba.DEFAULT_GRID):
    """
    General skeleton by openings working on greytone image 'imIn'.
    'imOut1' contains the skeleton function and 'imOut2' contains the 
    associated function.
    
    This skeleton corresponds to the centers of maximal cylinders included
    in the set under the graph of the image 'imIn'.
    
    Depth of 'imOut1' is the same as 'imIn', depth of 'imOut2' is 32. 

    The edge is always set to 'FILLED'.
    """

    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.opening(imWrk1, imWrk2, se=se)
        mamba.sub(imWrk1, imWrk2, imWrk2)
        _generateMask_(imWrk2, imOut1, maskIm)
        mamba.convertByMask(maskIm, imWrk3, 0, i)
        mamba.logic(imOut1, imWrk2, imOut1, "sup")
        mamba.logic(imOut2, imWrk3, imOut2, "sup")
        mamba.erode(imWrk1, imWrk1, se=se)
        v2 = mamba.computeVolume(imWrk1)
Esempio n. 25
0
def ultimateErosion(imIn, imOut1, imOut2, grid=mamba.DEFAULT_GRID):
    """
    General ultimate erosion working on greytone image 'imIn'. 'imOut1'
    contains the ultimate eroded function and 'imOut2' contains the 
    associated function.
    
    This ultimate erosion can be applied to greytone images.

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

    The edge is always set to 'FILLED'.
    """

    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.build(imWrk1, imWrk2, grid=grid)
        mamba.sub(imWrk1, imWrk2, imWrk2)
        _generateMask_(imWrk2, imOut1, maskIm)
        mamba.convertByMask(maskIm, imWrk3, 0, i)
        mamba.logic(imOut1, imWrk2, imOut1, "sup")
        mamba.logic(imOut2, imWrk3, imOut2, "sup")
        mamba.erode(imWrk1, imWrk1, se=se)
        v2 = mamba.computeVolume(imWrk1)
Esempio n. 26
0
def feretDiameterLabelling(imIn, imOut, direc):
    """
    The Feret diameter of each connected component of the binary image or the
    partition image 'imIn' is computed and its value labels the corresponding
    component. The labelled image is stored in the 32-bit image 'imOut'.
    If 'direc' is "vertical", the vertical Feret diameter is computed. If it is
    set to "horizontal", the corresponding diameter is used.    
    """

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

    imWrk1.fill(1)
    if direc == "horizontal":
        dir = 7
    elif direc == "vertical":
        dir = 1
    else:
        mamba.raiseExceptionOnError(core.MB_ERR_BAD_DIRECTION)
        # The above statement generates an error ('direc' is not horizontal or
        # vertical.
    # An horizontal or vertical distance function is generated.
    mamba.linearErode(imWrk1, imWrk1, dir, grid=mamba.SQUARE, edge=mamba.EMPTY)
    mamba.computeDistance(imWrk1, imOut, grid=mamba.SQUARE, edge=mamba.FILLED)
    mamba.addConst(imOut, 1, imOut)
    if imIn.getDepth() == 1:
        # Each particle is valued with the distance.
        mamba.convertByMask(imIn, imWrk2, 0, mamba.computeMaxRange(imWrk3)[1])
        mamba.logic(imOut, imWrk2, imWrk3, "inf")
        # The valued image is preserved.
        mamba.copy(imWrk3, imWrk4)
        # Each component is labelled by the maximal coordinate.
        mamba.build(imWrk2, imWrk3)
        # Using the dual reconstruction, we label the particles with the
        # minimal ccordinate.
        mamba.negate(imWrk2, imWrk2)
        mamba.logic(imWrk2, imWrk4, imWrk4, "sup")
        mamba.dualBuild(imWrk2, imWrk4)
        # We subtract 1 because the selected coordinate must be outside the particle.
        mamba.subConst(imWrk4, 1, imWrk4)
        mamba.negate(imWrk2, imWrk2)
        mamba.logic(imWrk2, imWrk4, imWrk4, "inf")
        # Then, the subtraction gives the Feret diameter.
        mamba.sub(imWrk3, imWrk4, imOut)
    else:
        mamba.copy(imOut, imWrk3)
        if imIn.getDepth() == 32:
            mamba.copy(imIn, imWrk2)
        else:
            mamba.convert(imIn, imWrk2)

# Using the cells builds (direct and dual to label the cells with the maximum
# and minimum distance.
        mamba.cellsBuild(imWrk2, imWrk3)
        mamba.cellsBuild(imWrk2, imWrk3)
        mamba.negate(imOut, imOut)
        mamba.cellsBuild(imWrk2, imOut)
        mamba.negate(imOut, imOut)
        # Subtracting 1...
        mamba.subConst(imOut, 1, imOut)
        # ... and getting the final result.
        mamba.sub(imWrk3, imOut, imOut)
Esempio n. 27
0
def feretDiameterLabelling(imIn, imOut, direc):
    """
    The Feret diameter of each connected component of the binary image or the
    partition image 'imIn' is computed and its value labels the corresponding
    component. The labelled image is stored in the 32-bit image 'imOut'.
    If 'direc' is "vertical", the vertical Feret diameter is computed. If it is
    set to "horizontal", the corresponding diameter is used.    
    """
    
    imWrk1 = mamba.imageMb(imIn, 1)
    imWrk2 = mamba.imageMb(imIn, 32)
    imWrk3 = mamba.imageMb(imIn, 32)
    imWrk4 = mamba.imageMb(imIn, 32)
    
    imWrk1.fill(1)
    if direc == "horizontal":
        dir = 7    
    elif direc == "vertical":
        dir = 1
    else:
        mamba.raiseExceptionOnError(core.MB_ERR_BAD_DIRECTION)
        # The above statement generates an error ('direc' is not horizontal or 
        # vertical.
    # An horizontal or vertical distance function is generated.
    mamba.linearErode(imWrk1, imWrk1, dir, grid=mamba.SQUARE, edge=mamba.EMPTY)
    mamba.computeDistance(imWrk1, imOut, grid=mamba.SQUARE, edge=mamba.FILLED)
    mamba.addConst(imOut, 1, imOut)
    if imIn.getDepth() == 1:
	    # Each particle is valued with the distance.
        mamba.convertByMask(imIn, imWrk2, 0, mamba.computeMaxRange(imWrk3)[1])
        mamba.logic(imOut, imWrk2, imWrk3, "inf")
        # The valued image is preserved.
        mamba.copy(imWrk3, imWrk4)
        # Each component is labelled by the maximal coordinate.
        mamba.build(imWrk2, imWrk3)
        # Using the dual reconstruction, we label the particles with the
        # minimal ccordinate.
        mamba.negate(imWrk2, imWrk2)
        mamba.logic(imWrk2, imWrk4, imWrk4, "sup")
        mamba.dualBuild(imWrk2, imWrk4)
        # We subtract 1 because the selected coordinate must be outside the particle.
        mamba.subConst(imWrk4, 1, imWrk4)
        mamba.negate(imWrk2, imWrk2)
        mamba.logic(imWrk2, imWrk4, imWrk4, "inf")
        # Then, the subtraction gives the Feret diameter.
        mamba.sub(imWrk3, imWrk4, imOut)
    else:
        mamba.copy(imOut, imWrk3)
        if imIn.getDepth() == 32:
            mamba.copy(imIn, imWrk2)
        else:
            mamba.convert(imIn, imWrk2)
	# Using the cells builds (direct and dual to label the cells with the maximum
        # and minimum distance.
        mamba.cellsBuild(imWrk2, imWrk3)
        mamba.cellsBuild(imWrk2, imWrk3)
        mamba.negate(imOut, imOut)
        mamba.cellsBuild(imWrk2, imOut)
        mamba.negate(imOut, imOut)
        # Subtracting 1...
        mamba.subConst(imOut, 1, imOut)
        # ... and getting the final result.
        mamba.sub(imWrk3, imOut, imOut)