Пример #1
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)
Пример #2
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)
Пример #3
0
def lowerGeodesicErode(imIn, imMask, imOut, n=1, se=mamba.DEFAULT_SE):
    """
    Performs a lower geodesic erosion of image 'imIn' under '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).

    The binary lower geodesic erosion is realised using the fact that the
    dilation is the dual operation of the erosion.
    
    Warning! 'imMask' and 'imOut' must be different.
    """
    
    if imIn.getDepth() == 1:
        mamba.diff(imMask, imIn, imOut)
        lowerGeodesicDilate(imOut, imMask, imOut, n, se=se)
        mamba.diff(imMask, imOut, imOut)
    else:
        imWrk1 = mamba.imageMb(imIn)
        imWrk2 = mamba.imageMb(imIn, 1)
        mamba.logic(imIn, imMask, imOut, "inf")
        for i in range(n):
            mamba.generateSupMask(imOut, imMask, imWrk2, False)
            mamba.convertByMask(imWrk2, imWrk1, 0, mamba.computeMaxRange(imWrk1)[1])
            mamba.logic(imOut, imWrk1, imOut, "sup")
            mamba.erode(imOut, imOut, se=se)
            mamba.logic(imOut, imMask, imOut, "inf")
Пример #4
0
def isotropicDistance(imIn, imOut, edge=mamba.FILLED):
    """
    Computes the distance function of a set in 'imIn'. This distance function
    uses dodecagonal erosions and the grid is assumed to be hexagonal.
    The procedure is quite slow but the result is more aesthetic.
    This operator also illustrates how to perform successive dodecagonal
    operations of increasing sizes.
    """

    if imIn.getDepth() != 1:
        mamba.raiseExceptionOnError(core.MB_ERR_BAD_DEPTH)
    imOut.reset()
    oldn = 0
    size = 0
    imWrk1 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn)
    mamba.copy(imIn, imWrk1)
    while mamba.computeVolume(imWrk1) != 0:
        mamba.add(imOut, imWrk1, imOut)
        size += 1
        n = int(0.4641 * size)
        n += abs(n % 2 - size % 2)
        if (n - oldn) == 1:
            mamba.copy(imWrk1, imWrk2)
            mamba.erode(imWrk1, imWrk1, 1, se=mamba.HEXAGON, edge=edge)
        else:
            mamba.conjugateHexagonalErode(imWrk2, imWrk1, 1, edge=edge)
        oldn = 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)
Пример #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 buildOpen(imIn, imOut, n=1, se=mamba.DEFAULT_SE):
    """
    Performs an opening by reconstruction operation on image 'imIn' and puts the
    result in 'imOut'. 'n' controls the size of the opening.
    """

    imWrk = mamba.imageMb(imIn)
    mamba.copy(imIn, imWrk)
    mamba.erode(imIn, imOut, n, se=se)
    mamba.build(imWrk, imOut, grid=se.getGrid())
Пример #8
0
def buildOpen(imIn, imOut, n=1, se=mamba.DEFAULT_SE):
    """
    Performs an opening by reconstruction operation on image 'imIn' and puts the
    result in 'imOut'. 'n' controls the size of the opening.
    """
    
    imWrk = mamba.imageMb(imIn)
    mamba.copy(imIn, imWrk)
    mamba.erode(imIn, imOut, n, se=se)
    mamba.build(imWrk, imOut, grid=se.getGrid())
Пример #9
0
def opening(imIn, imOut, n=1, se=mamba.DEFAULT_SE, edge=mamba.FILLED):
    """
    Performs an opening operation on image 'imIn' and puts the result in 'imOut'.
    'n' controls the size of the opening and 'se' the structuring element used.
    
    The default edge is set to 'FILLED'. Note that the edge setting operates in the
    erosion only.
    """

    mamba.erode(imIn, imOut, n, se=se, edge=edge)
    mamba.dilate(imOut, imOut, n, se=se.transpose())
Пример #10
0
def opening(imIn, imOut, n=1, se=mamba.DEFAULT_SE, edge=mamba.FILLED):
    """
    Performs an opening operation on image 'imIn' and puts the result in 'imOut'.
    'n' controls the size of the opening and 'se' the structuring element used.
    
    The default edge is set to 'FILLED'. Note that the edge setting operates in the
    erosion only.
    """
   
    mamba.erode(imIn, imOut, n, se=se, edge=edge)
    mamba.dilate(imOut, imOut, n, se=se.transpose())
Пример #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)
Пример #12
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")
Пример #13
0
def regularisedGradient(imIn, imOut, n, grid=mamba.DEFAULT_GRID):
    """
    Computes the regularized gradient of image 'imIn' of size 'n'.
    The result is put in 'imOut'. A regularized gradient of size 'n' extracts
    in the image contours thinner than 'n' while avoiding false detections.
    
    This operation is only valid for omnidirectional structuring elements.
    """
    
    imWrk = mamba.imageMb(imIn)
    se = mamba.structuringElement(mamba.getDirections(grid), grid)
    gradient(imIn, imWrk, n, se=se)
    whiteTopHat(imWrk, imWrk, n, se=se)
    mamba.erode(imWrk, imOut, n-1, se=se)
Пример #14
0
def erodeByCylinder3D(imInOut, height, section):
    """
    Erodes 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 FILLED.
    """
    
    l = len(imInOut)
    for im in imInOut:
        mamba.erode(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], "inf")
    m3D.copy3D(provIm3D, imInOut)
Пример #15
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")
Пример #16
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")
Пример #17
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")
Пример #18
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")
Пример #19
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)
Пример #20
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)
Пример #21
0
def strongLevelling(imIn, imOut, n, eroFirst, grid=mamba.DEFAULT_GRID):
    """
    Strong levelling of 'imIn', result in 'imOut'. 'n' defines the size of the
    erosion and dilation of 'imIn' in the operation. If 'eroFirst' is true, the
    operation starts with an erosion, it starts with a dilation otherwise.
    
    This filter is stronger (more efficient) that simpleLevelling. However, the
    order of the initial operations (erosion and dilation) matters.    
    """
    
    imWrk = mamba.imageMb(imIn)
    se = mamba.structuringElement(mamba.getDirections(grid), grid)
    if eroFirst:
        mamba.erode(imIn, imWrk, n, se=se)
        mamba.build(imIn, imWrk, grid=grid)
        mamba.dilate(imIn, imOut, n, se=se)
        mamba.dualBuild(imWrk, imOut, grid=grid)
    else:
        mamba.dilate(imIn, imWrk, n, se=se)
        mamba.dualBuild(imIn, imWrk, grid=grid)
        mamba.erode(imIn, imOut, n, se=se)
        mamba.build(imWrk, imOut, grid=grid)
Пример #22
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)
Пример #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)
Пример #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)