Example #1
0
def computeConnectivityNumber(imIn, grid=mamba.DEFAULT_GRID):
    """
    Computes the connectivity number (Euler_Poincare constant) of image 'ImIn'.
    The result is an integer number.
    
    Beware, if the input image 'imIn' is not a binary image, the function raises
    an error.
    """

    if imIn.getDepth() != 1:
        mamba.raiseExceptionOnError(core.MB_ERR_BAD_DEPTH)
    imWrk = mamba.imageMb(imIn)
    if grid == mamba.HEXAGONAL:
        dse = mamba.doubleStructuringElement([1, 6], [0], mamba.HEXAGONAL)
        mamba.hitOrMiss(imIn, imWrk, dse)
        n = mamba.computeVolume(imWrk)
        dse = mamba.doubleStructuringElement([1], [0, 2], mamba.HEXAGONAL)
        mamba.hitOrMiss(imIn, imWrk, dse)
        n = n - mamba.computeVolume(imWrk)
    else:
        dse = mamba.doubleStructuringElement([3, 4, 5], [0], mamba.SQUARE)
        mamba.hitOrMiss(imIn, imWrk, dse)
        n = mamba.computeVolume(imWrk)
        dse = mamba.doubleStructuringElement([4], [0, 3, 5], mamba.SQUARE)
        mamba.hitOrMiss(imIn, imWrk, dse)
        n = n - mamba.computeVolume(imWrk)
        dse = mamba.doubleStructuringElement([3, 5], [0, 4], mamba.SQUARE)
        mamba.hitOrMiss(imIn, imWrk, dse)
        n = n + mamba.computeVolume(imWrk)
    return n
Example #2
0
def fullThin(imIn, imOut, dse, edge=mamba.EMPTY):
    """
    Performs a complete thinning of 'imIn' with the successive rotations of 'dse'
    (until idempotence) and puts the result in 'imOut'.
    
    'imIn' and 'imOut' are binary images.
    
    'edge' is set to EMPTY by default.
    """
    
    if edge == mamba.EMPTY:
        imWrk = mamba.imageMb(imIn)
        mamba.copy(imIn, imOut)
        v1 = mamba.computeVolume(imOut)
        v2 = 0
        while v1 != v2:
            v2 = v1
            for i in range(mamba.gridNeighbors(dse.getGrid())):
                hitOrMiss(imOut, imWrk, dse)
                mamba.diff(imOut, imWrk, imOut)
                dse = dse.rotate()
            v1 = mamba.computeVolume(imOut)
    else:
        mamba.negate(imIn, imOut)
        v1 = mamba.computeVolume(imOut)
        v2 = 0
        while v1 != v2:
            v2 = v1
            rotatingThick(imOut, imOut, dse.flip())
            v1 = mamba.computeVolume(imOut)
        mamba.negate(imOut, imOut)
Example #3
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)
Example #4
0
def blackClip(imIn, imOut, step=0, grid=mamba.DEFAULT_GRID):
    """
    Performs a black skeleton clipping (clipping of a black skeleton image). 
    If 'step' is not defined (or equal to 0), the clipping is performed until 
    idempotence. If 'step' is defined, 'step' black points (if possible) will be 
    removed from each branch of the black skeleton.
    
    'edge' is always set to FILLED.
    """
    
    imWrk = mamba.imageMb(imIn)
    mamba.negate(imIn, imOut)
    if step == 0:
        v1 = mamba.computeVolume(imOut)
        v2 = 0
        while v1 != v2:
            v2 = v1
            endPoints(imOut, imWrk, grid=grid, edge=mamba.FILLED)
            mamba.diff(imOut, imWrk, imOut)
            v1 = mamba.computeVolume(imOut)
    else:
        for i in range(step):
            endPoints(imOut, imWrk, grid=grid, edge=mamba.FILLED)
            mamba.diff(imOut, imWrk, imOut)
    mamba.negate(imOut, imOut)
Example #5
0
def blackClip(imIn, imOut, step=0, grid=mamba.DEFAULT_GRID):
    """
    Performs a black skeleton clipping (clipping of a black skeleton image). 
    If 'step' is not defined (or equal to 0), the clipping is performed until 
    idempotence. If 'step' is defined, 'step' black points (if possible) will be 
    removed from each branch of the black skeleton.
    
    'edge' is always set to FILLED.
    """

    imWrk = mamba.imageMb(imIn)
    mamba.negate(imIn, imOut)
    if step == 0:
        v1 = mamba.computeVolume(imOut)
        v2 = 0
        while v1 != v2:
            v2 = v1
            endPoints(imOut, imWrk, grid=grid, edge=mamba.FILLED)
            mamba.diff(imOut, imWrk, imOut)
            v1 = mamba.computeVolume(imOut)
    else:
        for i in range(step):
            endPoints(imOut, imWrk, grid=grid, edge=mamba.FILLED)
            mamba.diff(imOut, imWrk, imOut)
    mamba.negate(imOut, imOut)
Example #6
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)
Example #7
0
def computeConnectivityNumber(imIn, grid=mamba.DEFAULT_GRID):
    """
    Computes the connectivity number (Euler_Poincare constant) of image 'ImIn'.
    The result is an integer number.
    
    Beware, if the input image 'imIn' is not a binary image, the function raises
    an error.
    """
    
    if imIn.getDepth() != 1:
        mamba.raiseExceptionOnError(core.MB_ERR_BAD_DEPTH)
    imWrk  = mamba.imageMb(imIn)
    if grid == mamba.HEXAGONAL:
        dse = mamba.doubleStructuringElement([1,6],[0],mamba.HEXAGONAL)
        mamba.hitOrMiss(imIn, imWrk, dse)
        n = mamba.computeVolume(imWrk)
        dse = mamba.doubleStructuringElement([1],[0,2],mamba.HEXAGONAL)
        mamba.hitOrMiss(imIn, imWrk, dse)
        n = n - mamba.computeVolume(imWrk)
    else:
        dse = mamba.doubleStructuringElement([3,4,5],[0],mamba.SQUARE)
        mamba.hitOrMiss(imIn, imWrk, dse)
        n = mamba.computeVolume(imWrk)
        dse = mamba.doubleStructuringElement([4],[0,3,5],mamba.SQUARE)
        mamba.hitOrMiss(imIn, imWrk, dse)
        n = n - mamba.computeVolume(imWrk)
        dse = mamba.doubleStructuringElement([3,5],[0,4],mamba.SQUARE)
        mamba.hitOrMiss(imIn, imWrk, dse)
        n = n + mamba.computeVolume(imWrk)
    return n
Example #8
0
def fullThin(imIn, imOut, dse, edge=mamba.EMPTY):
    """
    Performs a complete thinning of 'imIn' with the successive rotations of 'dse'
    (until idempotence) and puts the result in 'imOut'.
    
    'imIn' and 'imOut' are binary images.
    
    'edge' is set to EMPTY by default.
    """

    if edge == mamba.EMPTY:
        imWrk = mamba.imageMb(imIn)
        mamba.copy(imIn, imOut)
        v1 = mamba.computeVolume(imOut)
        v2 = 0
        while v1 != v2:
            v2 = v1
            for i in range(mamba.gridNeighbors(dse.getGrid())):
                hitOrMiss(imOut, imWrk, dse)
                mamba.diff(imOut, imWrk, imOut)
                dse = dse.rotate()
            v1 = mamba.computeVolume(imOut)
    else:
        mamba.negate(imIn, imOut)
        v1 = mamba.computeVolume(imOut)
        v2 = 0
        while v1 != v2:
            v2 = v1
            rotatingThick(imOut, imOut, dse.flip())
            v1 = mamba.computeVolume(imOut)
        mamba.negate(imOut, imOut)
Example #9
0
def fullGeodesicThick(imIn, imMask, imOut, dse):
    """
    Performs a complete geodesic thickening (until idempotence) of image 'imIn'
    inside mask 'imMask' with all the rotations of the double structuring
    element 'dse'. The result is put in 'imOut'.
    """

    mamba.copy(imIn, imOut)
    v1 = mamba.computeVolume(imOut)
    v2 = 0
    while v1 != v2:
        v2 = v1
        rotatingGeodesicThick(imOut, imMask, imOut, dse)
        v1 = mamba.computeVolume(imOut)
Example #10
0
def fullGeodesicThick(imIn, imMask, imOut, dse):
    """
    Performs a complete geodesic thickening (until idempotence) of image 'imIn'
    inside mask 'imMask' with all the rotations of the double structuring
    element 'dse'. The result is put in 'imOut'.
    """
    
    mamba.copy(imIn, imOut)
    v1 = mamba.computeVolume(imOut)
    v2 = 0
    while v1 != v2:
        v2 = v1
        rotatingGeodesicThick(imOut, imMask, imOut, dse)
        v1 = mamba.computeVolume(imOut)
Example #11
0
def computeDiameter(imIn, dir, scale=(1.0, 1.0), grid=mamba.DEFAULT_GRID):
    """
    Computes the diameter (diametral variation) of binary image 'imIn' in 
    direction 'dir'. 'scale' is a tuple defining the horizontal and vertical
    scale factors (default is 1.0).
    
    Beware, if the input image 'imIn' is not a binary image, the function raises
    an error.
    """
    
    if imIn.getDepth() != 1:
        mamba.raiseExceptionOnError(core.MB_ERR_BAD_DEPTH)
    if dir == 0:
        return 0.0
    dir = ((dir - 1)%(mamba.gridNeighbors(grid)//2)) +1
    imWrk = mamba.imageMb(imIn)
    mamba.copy(imIn, imWrk)
    mamba.diffNeighbor(imIn, imWrk, 1<<dir, grid=grid)
    if grid == mamba.HEXAGONAL:
        l = scale[1]
        if dir != 2:
            l = 2*l*scale[0]/math.sqrt(scale[0]*scale[0] + 4*scale[1]*scale[1])
    else:
        if dir == 1:
            l = scale[0]
        elif dir == 3:
            l = scale[1]
        else:
            l = scale[0]*scale[1]/math.sqrt(scale[0]*scale[0] + scale[1]*scale[1])
    l = l*mamba.computeVolume(imWrk)
    return l
Example #12
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
Example #13
0
def computeDiameter(imIn, dir, scale=(1.0, 1.0), grid=mamba.DEFAULT_GRID):
    """
    Computes the diameter (diametral variation) of binary image 'imIn' in 
    direction 'dir'. 'scale' is a tuple defining the horizontal and vertical
    scale factors (default is 1.0).
    
    Beware, if the input image 'imIn' is not a binary image, the function raises
    an error.
    """

    if imIn.getDepth() != 1:
        mamba.raiseExceptionOnError(core.MB_ERR_BAD_DEPTH)
    if dir == 0:
        return 0.0
    dir = ((dir - 1) % (mamba.gridNeighbors(grid) // 2)) + 1
    imWrk = mamba.imageMb(imIn)
    mamba.copy(imIn, imWrk)
    mamba.diffNeighbor(imIn, imWrk, 1 << dir, grid=grid)
    if grid == mamba.HEXAGONAL:
        l = scale[1]
        if dir != 2:
            l = 2 * l * scale[0] / math.sqrt(scale[0] * scale[0] +
                                             4 * scale[1] * scale[1])
    else:
        if dir == 1:
            l = scale[0]
        elif dir == 3:
            l = scale[1]
        else:
            l = scale[0] * scale[1] / math.sqrt(scale[0] * scale[0] +
                                                scale[1] * scale[1])
    l = l * mamba.computeVolume(imWrk)
    return l
Example #14
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)
Example #15
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)
Example #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)
Example #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)
Example #18
0
def fullThick(imIn, imOut, dse):
    """
    Performs a complete thickening of 'imIn' with the successive rotations of 'dse'
    (until idempotence) and puts the result in 'imOut'. 
    
    'imIn' and 'imOut' are binary images.
    
    The edge is always set to EMPTY.
    """
    
    mamba.copy(imIn, imOut)
    v1 = mamba.computeVolume(imOut)
    v2 = 0
    while v1 != v2:
        v2 = v1
        rotatingThick(imOut, imOut, dse)
        v1 = mamba.computeVolume(imOut)
Example #19
0
def cellsFullThin(imIn, imOut, dse, edge=mamba.EMPTY):
    """
    A full thinning transform is performed on each cell of the partition 'imIn'
    until idempotence. 'dse' is a double structuring element. The result
    is put in 'imOut'. 'edge' is set to EMPTY by default. 
    """
    
    imWrk = mamba.imageMb(imIn)
    mamba.copy(imIn, imOut)
    v1 = mamba.computeVolume(imOut)
    v2 = 0
    while v1 != v2:
        v2 = v1
        for i in range(mamba.gridNeighbors(dse.getGrid())):
            cellsThin(imOut, imOut, dse, edge=edge)
            dse = dse.rotate()
        v1 = mamba.computeVolume(imOut)
Example #20
0
def fullThick(imIn, imOut, dse):
    """
    Performs a complete thickening of 'imIn' with the successive rotations of 'dse'
    (until idempotence) and puts the result in 'imOut'. 
    
    'imIn' and 'imOut' are binary images.
    
    The edge is always set to EMPTY.
    """

    mamba.copy(imIn, imOut)
    v1 = mamba.computeVolume(imOut)
    v2 = 0
    while v1 != v2:
        v2 = v1
        rotatingThick(imOut, imOut, dse)
        v1 = mamba.computeVolume(imOut)
Example #21
0
def cellsFullThin(imIn, imOut, dse, edge=mamba.EMPTY):
    """
    A full thinning transform is performed on each cell of the partition 'imIn'
    until idempotence. 'dse' is a double structuring element. The result
    is put in 'imOut'. 'edge' is set to EMPTY by default. 
    """

    imWrk = mamba.imageMb(imIn)
    mamba.copy(imIn, imOut)
    v1 = mamba.computeVolume(imOut)
    v2 = 0
    while v1 != v2:
        v2 = v1
        for i in range(mamba.gridNeighbors(dse.getGrid())):
            cellsThin(imOut, imOut, dse, edge=edge)
            dse = dse.rotate()
        v1 = mamba.computeVolume(imOut)
 def updateim(self):
     # Updates the display (perform a rendering)
     depth = self.im_ref().getDepth()
     volume = 0
     if depth == 1:
         # binary 3D image
         self.planeLabel.config(text="")
         im8 = mamba.imageMb(self.W, self.H, 8)
         self.raw = b""
         for im2D in self.im_ref():
             mamba.convert(im2D, im8)
             self.raw += im8.extractRaw()
             volume += mamba.computeVolume(im2D)
     elif depth == 32:
         # 32-bit 3D image
         if self.master.bplane == 4:
             self.planeLabel.config(text="Plane : all")
             im3D_8 = m3D.image3DMb(self.im_ref(), 8)
             m3D.convert3D(self.im_ref(), im3D_8)
             self.raw = im3D_8.extractRaw()
             volume = m3D.computeVolume3D(self.im_ref())
         else:
             self.planeLabel.config(text="Plane : %d" %
                                    (self.master.bplane))
             im8 = mamba.imageMb(self.W, self.H, 8)
             self.raw = b""
             for im2D in self.im_ref():
                 mamba.copyBytePlane(im2D, self.master.bplane, im8)
                 self.raw += im8.extractRaw()
                 volume += mamba.computeVolume(im2D)
     else:
         # Greyscale image
         self.planeLabel.config(text="")
         self.raw = self.im_ref().extractRaw()
         volume = m3D.computeVolume3D(self.im_ref())
     self.setImagePlaneZ()
     self.setImagePlaneY()
     self.setImagePlaneX()
     self.planex.eraseTarget()
     self.planey.eraseTarget()
     self.planez.eraseTarget()
     self.volLabel.config(text="Volume : %d" % (volume))
     value = self.im_ref().getPixel((self.x, self.y, self.z))
     self.posLabel.config(text="At (%d,%d,%d) = %d" %
                          (self.x, self.y, self.z, value))
 def updateim(self):
     # Updates the display (perform a rendering)
     depth = self.im_ref().getDepth()
     volume = 0
     if depth==1:
         # binary 3D image
         self.planeLabel.config(text="")
         im8 = mamba.imageMb(self.W, self.H, 8)
         self.raw = b""
         for im2D in self.im_ref():
             mamba.convert(im2D, im8)
             self.raw += im8.extractRaw()
             volume += mamba.computeVolume(im2D)
     elif depth==32:
         # 32-bit 3D image
         if self.master.bplane==4:
             self.planeLabel.config(text="Plane : all")
             im3D_8 = m3D.image3DMb(self.im_ref(), 8)
             m3D.convert3D(self.im_ref(), im3D_8)
             self.raw = im3D_8.extractRaw()
             volume = m3D.computeVolume3D(self.im_ref())
         else:
             self.planeLabel.config(text="Plane : %d" % (self.master.bplane))
             im8 = mamba.imageMb(self.W, self.H, 8)
             self.raw = b""
             for im2D in self.im_ref():
                 mamba.copyBytePlane(im2D, self.master.bplane, im8)
                 self.raw += im8.extractRaw()
                 volume += mamba.computeVolume(im2D)
     else:
         # Greyscale image
         self.planeLabel.config(text="")
         self.raw = self.im_ref().extractRaw()
         volume = m3D.computeVolume3D(self.im_ref())
     self.setImagePlaneZ()
     self.setImagePlaneY()
     self.setImagePlaneX()
     self.planex.eraseTarget()
     self.planey.eraseTarget()
     self.planez.eraseTarget()
     self.volLabel.config(text="Volume : %d" % (volume))
     value = self.im_ref().getPixel((self.x, self.y, self.z))
     self.posLabel.config(text="At (%d,%d,%d) = %d" % (self.x,self.y,self.z,value))
Example #24
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)
Example #25
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)
Example #26
0
def dualbuildNeighbor3D(imMask, imInOut, d, grid=m3D.DEFAULT_GRID3D):
    """
    Dual builds image 'imInout' in direction 'd' according to 'grid' using 
    'imMask' as a mask (the propagation is performed only in 'd' direction).
    
    The function also returns the volume of the image 'imInout' after the
    build operation.
    
    'grid' value can be any 3D grid.
    """

    (width, height, length) = imInOut.getSize()
    if length != len(imMask):
        mamba.raiseExceptionOnError(core.MB_ERR_BAD_SIZE)
    grid2D = grid.get2DGrid()
    scan = grid.convertFromDir(d, 0)[0]
    volume = 0
    if scan == 0:
        for i in range(length):
            vol = mamba.dualbuildNeighbor(imMask[i], imInOut[i], d, grid2D)
            volume += vol
    else:
        if scan == 1:
            startPlane, endPlane = 0, length - 1
        else:
            startPlane, endPlane = length - 1, 0
        for i in range(startPlane, endPlane, scan):
            mamba.logic(imInOut[i], imMask[i], imInOut[i], "sup")
            vol = mamba.computeVolume(imInOut[i])
            volume += vol
            td = grid.getTranDir(d)
            dh = grid.convertFromDir(td, i + scan)[1]
            mamba.infNeighbor(imInOut[i], imInOut[i + scan], 1 << dh, grid2D)
        mamba.logic(imInOut[endPlane], imMask[endPlane], imInOut[endPlane],
                    "sup")
        vol = mamba.computeVolume(imInOut[endPlane])
        volume += vol
    return volume
Example #27
0
def computeVolume3D(imIn):
    """
    Computes the volume of the 3D image 'imIn', i.e. the sum of its pixel
    values. The computed integer value is returned by the function.
    
    'imIn' can be a 1-bit, 8-bit or 32-bit image.
    
    Be aware that because this operator runs on 3D image, the returned value
    can be very high.
    """
    vol = 0
    for im2D in imIn:
        vol += mamba.computeVolume(im2D)
    return vol
Example #28
0
def dualbuildNeighbor3D(imMask, imInOut, d, grid=m3D.DEFAULT_GRID3D):
    """
    Dual builds image 'imInout' in direction 'd' according to 'grid' using 
    'imMask' as a mask (the propagation is performed only in 'd' direction).
    
    The function also returns the volume of the image 'imInout' after the
    build operation.
    
    'grid' value can be any 3D grid.
    """
    
    (width, height, length) = imInOut.getSize()
    if length!=len(imMask):
        mamba.raiseExceptionOnError(core.MB_ERR_BAD_SIZE)
    grid2D = grid.get2DGrid()
    scan = grid.convertFromDir(d,0)[0]
    volume = 0
    if scan == 0:
        for i in range(length):
            vol = mamba.dualbuildNeighbor(imMask[i], imInOut[i], d, grid2D)
            volume += vol
    else:
        if scan == 1:
            startPlane, endPlane = 0, length - 1
        else:
            startPlane, endPlane = length - 1, 0
        for i in range(startPlane, endPlane, scan):
            mamba.logic(imInOut[i], imMask[i], imInOut[i], "sup")
            vol = mamba.computeVolume(imInOut[i])
            volume += vol
            td = grid.getTranDir(d)
            dh = grid.convertFromDir(td,i+scan)[1]
            mamba.infNeighbor(imInOut[i], imInOut[i+scan], 1<<dh, grid2D)
        mamba.logic(imInOut[endPlane], imMask[endPlane], imInOut[endPlane], "sup")
        vol = mamba.computeVolume(imInOut[endPlane])
        volume += vol
    return volume
Example #29
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)
Example #30
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)
Example #31
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)
Example #32
0
def whiteClip(imIn, imOut, step=0, grid=mamba.DEFAULT_GRID, edge=mamba.FILLED):
    """
    Performs a skeleton clipping of 'imIn' (supposed to contain a skeleton image)
    and puts the result in 'imOut'. If 'step' is not defined (or equal to 0), the 
    clipping is performed until idempotence. If 'step' is defined, 'step' points
    (if possible) will be removed from each branch of the skeleton.
    
    'edge' is set to FILLED by default.
    """
    
    imWrk = mamba.imageMb(imIn)
    mamba.copy(imIn, imOut)
    if step == 0:
        v1 = mamba.computeVolume(imOut)
        v2 = 0
        while v1 != v2:
            v2 = v1
            endPoints(imOut, imWrk, grid=grid, edge=edge)
            mamba.diff(imOut, imWrk, imOut)
            v1 = mamba.computeVolume(imOut)
    else:
        for i in range(step):
            endPoints(imOut, imWrk, grid=grid, edge=edge)
            mamba.diff(imOut, imWrk, imOut)
Example #33
0
def whiteClip(imIn, imOut, step=0, grid=mamba.DEFAULT_GRID, edge=mamba.FILLED):
    """
    Performs a skeleton clipping of 'imIn' (supposed to contain a skeleton image)
    and puts the result in 'imOut'. If 'step' is not defined (or equal to 0), the 
    clipping is performed until idempotence. If 'step' is defined, 'step' points
    (if possible) will be removed from each branch of the skeleton.
    
    'edge' is set to FILLED by default.
    """

    imWrk = mamba.imageMb(imIn)
    mamba.copy(imIn, imOut)
    if step == 0:
        v1 = mamba.computeVolume(imOut)
        v2 = 0
        while v1 != v2:
            v2 = v1
            endPoints(imOut, imWrk, grid=grid, edge=edge)
            mamba.diff(imOut, imWrk, imOut)
            v1 = mamba.computeVolume(imOut)
    else:
        for i in range(step):
            endPoints(imOut, imWrk, grid=grid, edge=edge)
            mamba.diff(imOut, imWrk, imOut)
Example #34
0
def geodesicDistance(imIn, imMask, imOut, se=mamba.DEFAULT_SE):
    """
    Computes the geodesic distance function of a set in 'imIn'. This distance
    function uses successive geodesic erosions of 'imIn' performed in the geodesic
    space defined by 'imMask'. The result is stored in 'imOut'. Be sure to use an 
    image of sufficient depth as output.
    
    This geodesic distance is quite slow as it is performed by successive geodesic
    erosions.
    """
    
    if imIn.getDepth() != 1:
        mamba.raiseExceptionOnError(core.MB_ERR_BAD_DEPTH)
    imOut.reset()
    imWrk = mamba.imageMb(imIn)
    mamba.logic(imIn, imMask, imWrk, "inf")
    while mamba.computeVolume(imWrk) != 0:
        mamba.add(imOut, imWrk, imOut)
        lowerGeodesicErode(imWrk, imMask, imWrk, se=se)
Example #35
0
def linearUltimateOpen(imIn, imOut, d, grid=mamba.DEFAULT_GRID):
    """
    This operator performs the ultimate directional opening of the binary image
    'imIn' in direction 'd' and puts the result in the 32-bit image 'imOut'.
    The value of 'imOut' at each point of 'imIn' corresponds to the length of the
    intercept passing through this point.
    """
    
    imWrk1 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn)
    
    size = 0
    imOut.reset()
    mamba.copy(imIn, imWrk1)
    while mamba.computeVolume(imWrk1) != 0:
        size += 1
        directionalErode(imWrk1, imWrk1, d, 1, grid=grid, edge=mamba.EMPTY)
        td = (d + mamba.gridNeighbors(grid) - 1) % (mamba.gridNeighbors(grid) * 2) + 1
        directionalDilate(imWrk1, imWrk2, td, size, grid=grid)
        mamba.add(imOut, imWrk2, imOut)
Example #36
0
def computeArea(imIn, scale=(1.0, 1.0)):
    """
    Calculates the area of the binary image 'imIn'. 'scale' is a tuple 
    containing the horizontal scale factor (distance between two adjacent 
    horizontal points) and the vertical scale factor (distance between two 
    successive lines) of image 'imIn' (default is 1.0 for both). The result is
    a float (when default values are used, the result value is identical to the
    computeVolume operator).
    
    Note that, with hexagonal grid, the "scale' default values do not correspond
    to an isotropic grid (where triangles would be equilateral).
    
    Beware, if the input image 'imIn' is not a binary image, the function raises
    an error.
    """

    if imIn.getDepth() != 1:
        mamba.raiseExceptionOnError(core.MB_ERR_BAD_DEPTH)
    a = scale[0] * scale[1] * mamba.computeVolume(imIn)
    return a
Example #37
0
def computeArea(imIn, scale=(1.0, 1.0)):
    """
    Calculates the area of the binary image 'imIn'. 'scale' is a tuple 
    containing the horizontal scale factor (distance between two adjacent 
    horizontal points) and the vertical scale factor (distance between two 
    successive lines) of image 'imIn' (default is 1.0 for both). The result is
    a float (when default values are used, the result value is identical to the
    computeVolume operator).
    
    Note that, with hexagonal grid, the "scale' default values do not correspond
    to an isotropic grid (where triangles would be equilateral).
    
    Beware, if the input image 'imIn' is not a binary image, the function raises
    an error.
    """
    
    if imIn.getDepth() != 1:
        mamba.raiseExceptionOnError(core.MB_ERR_BAD_DEPTH)
    a = scale[0]*scale[1]*mamba.computeVolume(imIn)
    return a
Example #38
0
def linearUltimateOpen(imIn, imOut, d, grid=mamba.DEFAULT_GRID):
    """
    This operator performs the ultimate directional opening of the binary image
    'imIn' in direction 'd' and puts the result in the 32-bit image 'imOut'.
    The value of 'imOut' at each point of 'imIn' corresponds to the length of the
    intercept passing through this point.
    """

    imWrk1 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn)

    size = 0
    imOut.reset()
    mamba.copy(imIn, imWrk1)
    while mamba.computeVolume(imWrk1) != 0:
        size += 1
        directionalErode(imWrk1, imWrk1, d, 1, grid=grid, edge=mamba.EMPTY)
        td = (d + mamba.gridNeighbors(grid) - 1) % (mamba.gridNeighbors(grid) *
                                                    2) + 1
        directionalDilate(imWrk1, imWrk2, td, size, grid=grid)
        mamba.add(imOut, imWrk2, imOut)
Example #39
0
 def updateim(self):
     # Updates the display with the new contents of the mamba image.
     if self.im_ref() and self.state()=="normal" and not self.frozen:
         if self.im_ref().getDepth()==32:
             im = mamba.imageMb(self.im_ref(), 8)
             if self.bplane==4:
                 mamba.convert(self.im_ref(), im)
                 self.infos[1].set("plane : all")
             else:
                 mamba.copyBytePlane(self.im_ref(),self.bplane,im)
                 self.infos[1].set("plane : %d" % (self.bplane))
             self.pilImage = utils.convertToPILFormat(im.mbIm)
         else:
             self.infos[1].set("")
             self.pilImage = utils.convertToPILFormat(self.im_ref().mbIm)
         if self.palname:
             self.pilImage.putpalette(palette.getPalette(self.palname))
         volume = mamba.computeVolume(self.im_ref())
         self.infos[0].set("volume : "+str(volume))
         self.icon = ImageTk.PhotoImage(self.pilImage.resize(self.icon_size, Image.NEAREST))
         self.tk.call('wm','iconphoto', self._w, self.icon)
         self.drawImage()
Example #40
0
 def updateim(self):
     # Updates the display with the new contents of the mamba image.
     if self.im_ref() and self.state() == "normal" and not self.frozen:
         if self.im_ref().getDepth() == 32:
             im = mamba.imageMb(self.im_ref(), 8)
             if self.bplane == 4:
                 mamba.convert(self.im_ref(), im)
                 self.infos[1].set("plane : all")
             else:
                 mamba.copyBytePlane(self.im_ref(), self.bplane, im)
                 self.infos[1].set("plane : %d" % (self.bplane))
             self.pilImage = utils.convertToPILFormat(im.mbIm)
         else:
             self.infos[1].set("")
             self.pilImage = utils.convertToPILFormat(self.im_ref().mbIm)
         if self.palname:
             self.pilImage.putpalette(palette.getPalette(self.palname))
         volume = mamba.computeVolume(self.im_ref())
         self.infos[0].set("volume : " + str(volume))
         self.icon = ImageTk.PhotoImage(
             self.pilImage.resize(self.icon_size, Image.NEAREST))
         self.tk.call('wm', 'iconphoto', self._w, self.icon)
         self.drawImage()
Example #41
0
def waterfalls(imIn, imOut, grid=mamba.DEFAULT_GRID):
    """
    Classical waterfall algorithm. All the hierarchical levels of greyscale
    image 'imIn' (which must be a valued watershed) are computed.
    'imOut' contains all these hierarchies which are embedded, so that
    hierarchy i is simply obtained by a threshold at [i+1, 255].
    This transformation returns the number of hierarchical levels.
    """
    
    imWrk1 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn)
    imWrk3 = mamba.imageMb(imIn, 1)
    mamba.copy(imIn, imWrk1)
    imOut.reset()
    nbLevels = 0
    mamba.threshold(imWrk1, imWrk3, 1, 255)
    while mamba.computeVolume(imWrk3) != 0:
        mamba.add(imOut, imWrk3, imOut)
        hierarchicalLevel(imWrk1, imWrk2, grid=grid)
        mamba.threshold(imWrk2, imWrk3, 1, 255)
        mamba.copy(imWrk2, imWrk1)
        nbLevels += 1
    return nbLevels
Example #42
0
def waterfalls(imIn, imOut, grid=mamba.DEFAULT_GRID):
    """
    Classical waterfall algorithm. All the hierarchical levels of greyscale
    image 'imIn' (which must be a valued watershed) are computed.
    'imOut' contains all these hierarchies which are embedded, so that
    hierarchy i is simply obtained by a threshold at [i+1, 255].
    This transformation returns the number of hierarchical levels.
    """

    imWrk1 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn)
    imWrk3 = mamba.imageMb(imIn, 1)
    mamba.copy(imIn, imWrk1)
    imOut.reset()
    nbLevels = 0
    mamba.threshold(imWrk1, imWrk3, 1, 255)
    while mamba.computeVolume(imWrk3) != 0:
        mamba.add(imOut, imWrk3, imOut)
        hierarchicalLevel(imWrk1, imWrk2, grid=grid)
        mamba.threshold(imWrk2, imWrk3, 1, 255)
        mamba.copy(imWrk2, imWrk1)
        nbLevels += 1
    return nbLevels
Example #43
0
# Importing mamba
import mamba
import mambaDisplay

im = mamba.imageMb("wheel.png", 1)
im1 = mamba.imageMb(im, 1)
im2 = mamba.imageMb(im, 1)

# Opening of image
mamba.opening(im, im1, 3)
# Selection of the outside region
mamba.negate(im1, im2)
mamba.removeEdgeParticles(im2, im1)
mamba.diff(im2, im1, im2)
# Extracting the wheel teeth
mamba.logic(im, im2, im2, "inf")
# Cleaning the image
mamba.opening(im2, im2)
# Counting and marking each tooth
mamba.thinD(im2, im1)
nb_teeth = mamba.computeVolume(im1)
print("Number of teeth: %d" % (nb_teeth))
mamba.dilate(im1, im1, 3, mamba.SQUARE3X3)
im1.convert(8)
im8 = mamba.imageMb(im, 8)
mamba.convert(im, im8)
mamba.subConst(im8, 1, im8)
mamba.logic(im8, im1, im8, "sup")
name = mambaDisplay.tagOneColorPalette(255, (0,0,255))
im8.save('wheel_teeth.png', palette=mambaDisplay.getPalette(name))
Example #44
0
# Importing mamba
import mamba
import mambaDisplay

im = mamba.imageMb("wheel.png", 1)
im1 = mamba.imageMb(im, 1)
im2 = mamba.imageMb(im, 1)

# Opening of image
mamba.opening(im, im1, 3)
# Selection of the outside region
mamba.negate(im1, im2)
mamba.removeEdgeParticles(im2, im1)
mamba.diff(im2, im1, im2)
# Extracting the wheel teeth
mamba.logic(im, im2, im2, "inf")
# Cleaning the image
mamba.opening(im2, im2)
# Counting and marking each tooth
mamba.thinD(im2, im1)
nb_teeth = mamba.computeVolume(im1)
print("Number of teeth: %d" % (nb_teeth))
mamba.dilate(im1, im1, 3, mamba.SQUARE3X3)
im1.convert(8)
im8 = mamba.imageMb(im, 8)
mamba.convert(im, im8)
mamba.subConst(im8, 1, im8)
mamba.logic(im8, im1, im8, "sup")
name = mambaDisplay.tagOneColorPalette(255, (0, 0, 255))
im8.save('wheel_teeth.png', palette=mambaDisplay.getPalette(name))