def nonEqualNeighbors(imIn,
                      imOut,
                      nb,
                      grid=mamba.DEFAULT_GRID,
                      edge=mamba.FILLED):
    """
    This operator compares the value of each pixel of image 'imIn'
    with the value of its neighbors encoded in 'nb'.
    If all the neighbor values are different, the pixel is unchanged.
    Otherwise, it takes value 0.
    This operator works on hexagonal or square 'grid' and
    'edge' is set to FILLED by default.
    This operator works for 8-bit and 32-bit images.
    """

    imWrk1 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn)
    imWrk3 = mamba.imageMb(imIn, 1)
    imWrk4 = mamba.imageMb(imIn, 1)
    for d in mamba.getDirections(grid):
        ed = 1 << d
        if (nb & ed):
            mamba.copy(imIn, imWrk1)
            mamba.copy(imIn, imWrk2)
            mamba.supNeighbor(imWrk1, imWrk1, ed, grid=grid, edge=edge)
            mamba.infNeighbor(imWrk2, imWrk2, ed, grid=grid, edge=edge)
            mamba.generateSupMask(imWrk2, imWrk1, imWrk3, False)
            mamba.logic(imWrk4, imWrk3, imWrk4, "or")
    mamba.convertByMask(imWrk4, imWrk1, mamba.computeMaxRange(imIn)[1], 0)
    mamba.logic(imIn, imWrk1, imOut, "inf")
def nonEqualNeighbors(imIn, imOut, nb, grid=mamba.DEFAULT_GRID, edge=mamba.FILLED):
    """
    This operator compares the value of each pixel of image 'imIn'
    with the value of its neighbors encoded in 'nb'.
    If all the neighbor values are different, the pixel is unchanged.
    Otherwise, it takes value 0.
    This operator works on hexagonal or square 'grid' and
    'edge' is set to FILLED by default.
    This operator works for 8-bit and 32-bit images.
    """
    
    imWrk1 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn)
    imWrk3 = mamba.imageMb(imIn, 1)
    imWrk4 = mamba.imageMb(imIn, 1)
    for d in mamba.getDirections(grid):
        ed = 1<<d
        if (nb & ed):
            mamba.copy(imIn, imWrk1)
            mamba.copy(imIn, imWrk2)
            mamba.supNeighbor(imWrk1, imWrk1, ed, grid=grid, edge=edge)
            mamba.infNeighbor(imWrk2, imWrk2, ed, grid=grid, edge=edge)
            mamba.generateSupMask(imWrk2, imWrk1, imWrk3, False)
            mamba.logic(imWrk4, imWrk3, imWrk4, "or")
    mamba.convertByMask(imWrk4, imWrk1, mamba.computeMaxRange(imIn)[1], 0)
    mamba.logic(imIn, imWrk1, imOut, "inf")
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)
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)
def hitOrMiss3D(imIn, imOut, dse, edge=mamba.EMPTY):
    """
    Performs a binary Hit-or-miss operation on 3D image 'imIn' using the 
    doubleStructuringElement3D 'dse'. Result is put in 'imOut'.
    
    WARNING! 'imIn' and 'imOut' must be different images.
    """

    (width, height, length) = imIn.getSize()
    depth = imIn.getDepth()
    if depth != 1:
        mamba.raiseExceptionOnError(core.MB_ERR_BAD_DEPTH)
    if length != len(imOut):
        mamba.raiseExceptionOnError(core.MB_ERR_BAD_SIZE)
    zext = dse.grid.getZExtension()
    imWrk = m3D.image3DMb(width, height, length + zext * 2, depth)

    # Border handling
    imWrk.reset()
    m3D.copy3D(imIn, imWrk, firstPlaneOut=1)
    if edge == mamba.FILLED:
        m3D.negate3D(imWrk, imWrk)
        for i in range(zext):
            imWrk[i].reset()
            imWrk[length + zext * 2 - 1 - i].reset()
        dse = dse.flip()

    # Central point
    if dse.se1.hasZero():
        m3D.copy3D(imWrk, imOut, firstPlaneIn=1)
    else:
        if dse.se0.hasZero():
            for i in range(length):
                mamba.negate(imWrk[i + 1], imOut[i])
        else:
            imOut.fill(1)

    # Other directions
    dirs = m3D.getDirections3D(dse.getGrid(), True)
    dirs0 = dse.se0.getDirections()
    dirs1 = dse.se1.getDirections()
    grid2D = dse.getGrid().get2DGrid()
    for d in dirs:
        if d in dirs1:
            for i in range(length):
                (planeOffset, dc) = dse.getGrid().convertFromDir(d, i)
                mamba.infNeighbor(imWrk[i + 1 + planeOffset],
                                  imOut[i],
                                  1 << dc,
                                  grid=grid2D,
                                  edge=edge)
        elif d in dirs0:
            for i in range(length):
                (planeOffset, dc) = dse.getGrid().convertFromDir(d, i)
                mamba.diffNeighbor(imWrk[i + 1 + planeOffset],
                                   imOut[i],
                                   1 << dc,
                                   grid=grid2D,
                                   edge=edge)
def hitOrMiss3D(imIn, imOut, dse, edge=mamba.EMPTY):
    """
    Performs a binary Hit-or-miss operation on 3D image 'imIn' using the 
    doubleStructuringElement3D 'dse'. Result is put in 'imOut'.
    
    WARNING! 'imIn' and 'imOut' must be different images.
    """
    
    (width,height,length) = imIn.getSize()
    depth = imIn.getDepth()
    if depth!=1:
        mamba.raiseExceptionOnError(core.MB_ERR_BAD_DEPTH)
    if length!=len(imOut):
        mamba.raiseExceptionOnError(core.MB_ERR_BAD_SIZE)
    zext = dse.grid.getZExtension()
    imWrk = m3D.image3DMb(width, height, length+zext*2, depth)
    
    # Border handling
    imWrk.reset()
    m3D.copy3D(imIn, imWrk, firstPlaneOut=1)
    if edge==mamba.FILLED:
        m3D.negate3D(imWrk, imWrk)
        for i in range(zext):
            imWrk[i].reset()
            imWrk[length+zext*2-1-i].reset()
        dse = dse.flip()

    # Central point
    if dse.se1.hasZero():
        m3D.copy3D(imWrk, imOut, firstPlaneIn=1)
    else:
        if dse.se0.hasZero():
            for i in range(length):
                mamba.negate(imWrk[i+1], imOut[i])
        else:
            imOut.fill(1)

    # Other directions
    dirs = m3D.getDirections3D(dse.getGrid(), True)
    dirs0 = dse.se0.getDirections()
    dirs1 = dse.se1.getDirections()
    grid2D = dse.getGrid().get2DGrid()
    for d in dirs:
        if d in dirs1:
            for i in range(length):
                (planeOffset, dc) = dse.getGrid().convertFromDir(d,i)
                mamba.infNeighbor(imWrk[i+1+planeOffset], imOut[i], 1<<dc, grid=grid2D, edge=edge)
        elif d in dirs0:
            for i in range(length):
                (planeOffset, dc) = dse.getGrid().convertFromDir(d,i)
                mamba.diffNeighbor(imWrk[i+1+planeOffset], imOut[i], 1<<dc, grid=grid2D, edge=edge)
def equalNeighbors(imIn, imOut, nb, grid=mamba.DEFAULT_GRID, edge=mamba.FILLED):
    """
    This operator compares the value of each pixel of image 'imIn'
    with the value of its neighbors encoded in 'nb'.
    If all the neighbor values are equal, the pixel is unchanged.
    Otherwise, it takes value 0.
    This operator works on hexagonal or square 'grid' and 
    'edge' is set to FILLED by default.
    This operator works for 8-bit and 32-bit images.
    """
    
    imWrk1 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn, 1)
    mamba.copy(imIn, imWrk1)
    mamba.copy(imIn, imOut)
    mamba.supNeighbor(imIn, imWrk1, nb, grid=grid, edge=edge)
    mamba.infNeighbor(imOut, imOut, nb, grid=grid, edge=edge)
    mamba.generateSupMask(imOut, imWrk1, imWrk2, False)
    mamba.convertByMask(imWrk2, imWrk1, 0, mamba.computeMaxRange(imIn)[1])
    mamba.logic(imOut, imWrk1, imOut, "inf")
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
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
def equalNeighbors(imIn,
                   imOut,
                   nb,
                   grid=mamba.DEFAULT_GRID,
                   edge=mamba.FILLED):
    """
    This operator compares the value of each pixel of image 'imIn'
    with the value of its neighbors encoded in 'nb'.
    If all the neighbor values are equal, the pixel is unchanged.
    Otherwise, it takes value 0.
    This operator works on hexagonal or square 'grid' and 
    'edge' is set to FILLED by default.
    This operator works for 8-bit and 32-bit images.
    """

    imWrk1 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn, 1)
    mamba.copy(imIn, imWrk1)
    mamba.copy(imIn, imOut)
    mamba.supNeighbor(imIn, imWrk1, nb, grid=grid, edge=edge)
    mamba.infNeighbor(imOut, imOut, nb, grid=grid, edge=edge)
    mamba.generateSupMask(imOut, imWrk1, imWrk2, False)
    mamba.convertByMask(imWrk2, imWrk1, 0, mamba.computeMaxRange(imIn)[1])
    mamba.logic(imOut, imWrk1, imOut, "inf")
Exemple #11
0
def erode3D(imIn, imOut, n=1, se=CUBOCTAHEDRON1, edge=mamba.FILLED):
    """
    This operator performs an erosion, using the structuring element 'se' (set
    by default as CUBOCTAHEDRON1), of 3D image 'imIn' and puts the result in 
    'imOut'. The operation is repeated 'n' times (default is 1). This operator
    assumes a 'FILLED' edge by default.
    
    This operator always considers that the origin of the structuring element
    in use is at position 0 even if this point does not belong to it.
    """
    
    (width,height,length) = imIn.getSize()
    depth = imIn.getDepth()
    if length!=len(imOut):
        mamba.raiseExceptionOnError(core.MB_ERR_BAD_SIZE)
    zext = se.grid.getZExtension()
    imWrk = m3D.image3DMb(width, height, length+zext*2, depth)
    if edge==mamba.EMPTY:
        for i in range(zext):
            imWrk[i].reset()
            imWrk[length+zext*2-1-i].reset()
    else:
        value = mamba.computeMaxRange(imIn[0])[1]
        for i in range(zext):
            imWrk[i].fill(value)
            imWrk[length+zext*2-1-i].fill(value)
    
    m3D.copy3D(imIn, imOut)
    
    dirs = se.getDirections(withoutZero=True)
    for size in range(n):
        m3D.copy3D(imOut, imWrk, 0, 1)
        if not se.hasZero():
            imOut.fill(m3D.computeMaxRange3D(imIn)[1])
        for i in range(length):
            dirs_enc = se.grid.getEncodedDirs(dirs,i)
            mamba.infNeighbor(imWrk[i], imOut[i], dirs_enc[-1], grid=se.grid.get2DGrid(), edge=edge)
            mamba.infNeighbor(imWrk[i+1], imOut[i], dirs_enc[0], grid=se.grid.get2DGrid(), edge=edge)
            mamba.infNeighbor(imWrk[i+2], imOut[i], dirs_enc[1], grid=se.grid.get2DGrid(), edge=edge)