Пример #1
0
def mosaic3D(imIn, imOut, imWts, grid=m3D.DEFAULT_GRID3D):
    """
    Builds the mosaic 3D image of 'imIn' and puts the results into 'imOut'.
    The watershed line (pixel values set to 255) is stored in the 
    greytone 3D image 'imWts'. A mosaic image is a simple image made of various 
    tiles of uniform grey values. It is built using the watershed of 'imIn' 
    gradient and original markers made of gradient minima which are labelled by
    the maximum value of 'imIn' pixels inside them.
    """

    imWrk1 = m3D.image3DMb(imIn, 1)
    imWrk2 = m3D.image3DMb(imIn)
    m3D.copy3D(imIn, imWrk2)
    im_mark = m3D.image3DMb(imIn, 32)
    se = m3D.structuringElement3D(m3D.getDirections3D(grid), grid)
    m3D.gradient3D(imIn, imOut, se=se)
    m3D.minima3D(imOut, imWrk1, grid=grid)
    m3D.add3D(im_mark, imWrk1, im_mark)
    imWrk1.convert(8)
    m3D.build3D(imWrk1, imWrk2, grid=grid)
    m3D.add3D(im_mark, imWrk2, im_mark)
    m3D.watershedSegment3D(imOut, im_mark, grid=grid)
    m3D.copyBytePlane3D(im_mark, 3, imWts)
    m3D.subConst3D(im_mark, 1, im_mark)
    m3D.copyBytePlane3D(im_mark, 0, imOut)
Пример #2
0
def mosaic3D(imIn, imOut, imWts, grid=m3D.DEFAULT_GRID3D):
    """
    Builds the mosaic 3D image of 'imIn' and puts the results into 'imOut'.
    The watershed line (pixel values set to 255) is stored in the 
    greytone 3D image 'imWts'. A mosaic image is a simple image made of various 
    tiles of uniform grey values. It is built using the watershed of 'imIn' 
    gradient and original markers made of gradient minima which are labelled by
    the maximum value of 'imIn' pixels inside them.
    """
   
    imWrk1 = m3D.image3DMb(imIn, 1)
    imWrk2 = m3D.image3DMb(imIn)
    m3D.copy3D(imIn, imWrk2)
    im_mark = m3D.image3DMb(imIn, 32)
    se = m3D.structuringElement3D(m3D.getDirections3D(grid), grid)
    m3D.gradient3D(imIn, imOut, se=se)
    m3D.minima3D(imOut, imWrk1, grid=grid) 
    m3D.add3D(im_mark, imWrk1, im_mark) 
    imWrk1.convert(8)
    m3D.build3D(imWrk1, imWrk2, grid=grid)
    m3D.add3D(im_mark, imWrk2, im_mark)   
    m3D.watershedSegment3D(imOut, im_mark, grid=grid)
    m3D.copyBytePlane3D(im_mark, 3, imWts)
    m3D.subConst3D(im_mark, 1, im_mark)
    m3D.copyBytePlane3D(im_mark, 0, imOut)
Пример #3
0
def linearClose3D(imIn,
                  imOut,
                  dir,
                  n,
                  grid=m3D.DEFAULT_GRID3D,
                  edge=mamba.FILLED):
    """
    Performs a closing by a segment of size 'n' in direction 'dir'.
    
    If 'edge' is set to 'EMPTY', the operation must be modified to
    remain extensive.
    """

    imWrk = m3D.image3DMb(imIn)
    if edge == mamba.EMPTY:
        m3D.copy3D(imIn, imWrk)
    m3D.linearDilate3D(imIn, imOut, dir, n, grid=grid)
    m3D.linearErode3D(imOut,
                      imOut,
                      m3D.transposeDirection3D(dir, grid=grid),
                      n,
                      edge=edge,
                      grid=grid)
    if edge == mamba.EMPTY:
        m3D.logic3D(imOut, imWrk, imOut, "sup")
Пример #4
0
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)
Пример #5
0
def buildClose3D(imIn, imOut, n=1, se=m3D.CUBOCTAHEDRON1):
    """
    Performs a closing by dual reconstruction operation on 3D image 'imIn'
    and puts the result in 'imOut'. 'n' controls the size of the closing.
    """

    imWrk = m3D.image3DMb(imIn)
    m3D.copy3D(imIn, imWrk)
    m3D.dilate3D(imIn, imOut, n, se=se)
    m3D.dualBuild3D(imWrk, imOut, grid=se.getGrid())
Пример #6
0
def buildOpen3D(imIn, imOut, n=1, se=m3D.CUBOCTAHEDRON1):
    """
    Performs an opening by reconstruction operation on 3D image 'imIn' and
    puts the result in 'imOut'. 'n' controls the size of the opening.
    """

    imWrk = m3D.image3DMb(imIn)
    m3D.copy3D(imIn, imWrk)
    m3D.erode3D(imIn, imOut, n, se=se)
    m3D.build3D(imWrk, imOut, grid=se.getGrid())
Пример #7
0
def buildOpen3D(imIn, imOut, n=1, se=m3D.CUBOCTAHEDRON1):
    """
    Performs an opening by reconstruction operation on 3D image 'imIn' and
    puts the result in 'imOut'. 'n' controls the size of the opening.
    """

    imWrk = m3D.image3DMb(imIn)
    m3D.copy3D(imIn, imWrk)
    m3D.erode3D(imIn, imOut, n, se=se)
    m3D.build3D(imWrk, imOut, grid=se.getGrid())
Пример #8
0
def buildClose3D(imIn, imOut, n=1, se=m3D.CUBOCTAHEDRON1):
    """
    Performs a closing by dual reconstruction operation on 3D image 'imIn'
    and puts the result in 'imOut'. 'n' controls the size of the closing.
    """

    imWrk = m3D.image3DMb(imIn)
    m3D.copy3D(imIn, imWrk)
    m3D.dilate3D(imIn, imOut, n, se=se)
    m3D.dualBuild3D(imWrk, imOut, grid=se.getGrid())
Пример #9
0
def linearDilate3D(imIn, imOut, d, n=1, grid=m3D.DEFAULT_GRID3D, edge=mamba.EMPTY):
    """
    Dilation by a segment in direction 'd' of 3D image 'imIn', result in 'imOut'.
    The operation is repeated 'n' times (default is 1).This function will assume
    an EMPTY edge unless specified otherwise using 'edge'. The directions
    are defined according to the grid in use.
    """
    
    se = m3D.structuringElement3D([0,d], grid)
    m3D.copy3D(imIn, imOut)
    m3D.dilate3D(imOut, imOut, n, se=se, edge=edge)
Пример #10
0
def largeLinearDilate3D(imIn, imOut, dir, size, grid=m3D.DEFAULT_GRID3D, edge=mamba.EMPTY):
    """
    Dilation of the 3D image 'imIn' by a large segment in direction 'dir' in a reduced
    number of iterations.
    Uses the dilations by doublets of points (supposed to be faster, thanks to
    an enhanced shift operator).
    """
    
    m3D.copy3D(imIn, imOut)
    for i in _sizeSplit(size):
        supFarNeighbor3D(imOut, imOut, dir, i, grid=grid, edge=edge)
Пример #11
0
def linearErode3D( imIn, imOut, d, n=1, grid=m3D.DEFAULT_GRID3D, edge=mamba.FILLED):
    """
    Performs an erosion in direction 'd' of 3D image 'imIn' and puts the
    result in 'imOut'. The operation is repeated 'n' times (default is 1).
    This function will assume a FILLED edge unless specified otherwise using
    'edge'.
    """
    
    se = m3D.structuringElement3D([0,d], grid)
    m3D.copy3D(imIn, imOut)
    m3D.erode3D(imOut, imOut, n, se=se, edge=edge)
Пример #12
0
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)
Пример #13
0
def linearClose3D(imIn, imOut, dir, n, grid=m3D.DEFAULT_GRID3D, edge=mamba.FILLED):
    """
    Performs a closing by a segment of size 'n' in direction 'dir'.
    
    If 'edge' is set to 'EMPTY', the operation must be modified to
    remain extensive.
    """

    imWrk = m3D.image3DMb(imIn)
    if edge == mamba.EMPTY:
        m3D.copy3D(imIn, imWrk)
    m3D.linearDilate3D(imIn, imOut, dir, n, grid=grid)
    m3D.linearErode3D(imOut, imOut, m3D.transposeDirection3D(dir, grid=grid), n, edge=edge, grid=grid)
    if edge == mamba.EMPTY:
        m3D.logic3D(imOut, imWrk, imOut, "sup")
Пример #14
0
def dilateByCylinder3D(imInOut, height, section):
    """
    Dilates 3D image 'imInOut' using a cylinder with an hexagonal section of size 
    2x'section' and a height of 2x'height'. The image is modified by this
    function. The edge is always set to EMPTY.
    """
    
    l = len(imInOut)
    for im in imInOut:
        mamba.dilate(im, im, section, se=mamba.HEXAGON)
    provIm3D = m3D.image3DMb(imInOut)
    for i in range(l):
        mamba.copy(imInOut[i], provIm3D[i])
        for j in range(max(0,i-height), min(l,i+height+1)):
            mamba.logic(provIm3D[i], imInOut[j], provIm3D[i], "sup")
    m3D.copy3D(provIm3D, imInOut)
Пример #15
0
def fullAlternateFilter3D(imIn, imOut, n, openFirst, se=m3D.CUBOCTAHEDRON1):
    """
    Performs a full alternate filter operation (successive alternate filters of
    increasing sizes, from 1 to 'n') on 3D image 'imIn' and puts the result 
    in 'imOut'. 'n' controls the filter size. If 'openFirst' is True, the filter
    begins with an opening, a closing otherwise.
    """

    m3D.copy3D(imIn, imOut)
    for i in range(1, n + 1):
        if openFirst:
            m3D.opening3D(imOut, imOut, i, se=se)
            m3D.closing3D(imOut, imOut, i, se=se)
        else:
            m3D.closing3D(imOut, imOut, i, se=se)
            m3D.opening3D(imOut, imOut, i, se=se)
Пример #16
0
def fullAlternateFilter3D(imIn, imOut, n, openFirst, se=m3D.CUBOCTAHEDRON1):
    """
    Performs a full alternate filter operation (successive alternate filters of
    increasing sizes, from 1 to 'n') on 3D image 'imIn' and puts the result 
    in 'imOut'. 'n' controls the filter size. If 'openFirst' is True, the filter
    begins with an opening, a closing otherwise.
    """
    
    m3D.copy3D(imIn, imOut)
    for i in range(1,n+1):
        if openFirst:
            m3D.opening3D(imOut, imOut, i, se=se)
            m3D.closing3D(imOut, imOut, i, se=se)
        else:
            m3D.closing3D(imOut, imOut, i, se=se)
            m3D.opening3D(imOut, imOut, i, se=se)
Пример #17
0
def closing3D(imIn, imOut, n=1, se=m3D.CUBOCTAHEDRON1, edge=mamba.FILLED):
    """
    Performs a closing operation on 3D 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 = m3D.image3DMb(imIn)
    if edge == mamba.EMPTY:
        m3D.copy3D(imIn, imWrk)
    m3D.dilate3D(imIn, imOut, n, se=se)
    m3D.erode3D(imOut, imOut, n, se=se.transpose(), edge=edge)
    if edge == mamba.EMPTY:
        m3D.logic3D(imOut, imWrk, imOut, "sup")
Пример #18
0
def closing3D(imIn, imOut, n=1, se=m3D.CUBOCTAHEDRON1, edge=mamba.FILLED):
    """
    Performs a closing operation on 3D 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 = m3D.image3DMb(imIn)
    if edge == mamba.EMPTY:
        m3D.copy3D(imIn, imWrk)
    m3D.dilate3D(imIn, imOut, n, se=se)
    m3D.erode3D(imOut, imOut, n, se=se.transpose(), edge=edge)
    if edge == mamba.EMPTY:
        m3D.logic3D(imOut, imWrk, imOut, "sup")
Пример #19
0
def supOpen3D(imIn, imOut, n, grid=m3D.DEFAULT_GRID3D):
    """
    Performs the supremum of directional openings. A white particle is preserved
    (but not entirely) if its length is larger than 'n' in at least one direction.
    
    This operator is an opening. The image edge is set to 'EMPTY' in order to 
    take into account particles touching the edge (they are considered as entirely
    included in the image window).

    When square grid is used, the size in oblique directions are reduced to be
    similar to the horizontal and vertical size.    
    """

    imWrk1 = m3D.image3DMb(imIn)
    imWrk2 = m3D.image3DMb(imIn)
    imWrk1.reset()
    # Default grid is a proxy for an actual grid
    if grid == m3D.CUBIC:
        # First neighbors located at a sqrt(2) distance from the center
        size = int((1.4142 * n + 1) / 2)
        for d in [2, 4, 10, 12, 14, 16]:
            linearOpen3D(imIn, imWrk2, d, size, grid, edge=mamba.EMPTY)
            m3D.logic3D(imWrk1, imWrk2, imWrk1, "sup")
        # First neighbors located at a sqrt(3) distance from the center
        size = int((1.7320 * n + 1) / 2)
        for d in [11, 13, 15, 17]:
            linearOpen3D(imIn, imWrk2, d, size, grid, edge=mamba.EMPTY)
            m3D.logic3D(imWrk1, imWrk2, imWrk1, "sup")
        # Finally neighbors located at a 1 distance from the center
        size = n
        for d in [1, 3, 9]:
            linearOpen3D(imIn, imWrk2, d, size, grid, edge=mamba.EMPTY)
            m3D.logic3D(imWrk1, imWrk2, imWrk1, "sup")
    elif grid == m3D.FACE_CENTER_CUBIC:
        for d in [1, 3, 5, 7, 8, 9]:
            linearOpen3D(imIn, imWrk2, d, n, grid, edge=mamba.EMPTY)
            m3D.logic3D(imWrk1, imWrk2, imWrk1, "sup")
    else:
        mamba.raiseExceptionOnError(core.MB_ERR_BAD_PARAMETER)
    m3D.copy3D(imWrk1, imOut)
Пример #20
0
def infClose3D(imIn, imOut, n, grid=m3D.DEFAULT_GRID3D):
    """
    Performs the infimum of directional closings. A black particle is preserved
    if its length is larger than 'n' in at least one direction.
    
    This operator is a closing. The image edge is set to 'FILLED' in order to 
    take into account particles touching the edge (they are supposed not to 
    extend outside the image window).
    
    When square grid is used, the size in oblique directions are reduced to be
    similar to the horizontal and vertical size.    
    """

    imWrk1 = m3D.image3DMb(imIn)
    imWrk2 = m3D.image3DMb(imIn)
    imWrk1.fill(m3D.computeMaxRange3D(imIn)[1])
    # Default grid is a proxy for an actual grid
    if grid == m3D.CUBIC:
        # First neighbors located at a sqrt(2) distance from the center
        size = int((1.4142 * n + 1) / 2)
        for d in [2, 4, 10, 12, 14, 16]:
            linearClose3D(imIn, imWrk2, d, size, grid)
            m3D.logic3D(imWrk1, imWrk2, imWrk1, "inf")
        # First neighbors located at a sqrt(3) distance from the center
        size = int((1.7320 * n + 1) / 2)
        for d in [11, 13, 15, 17]:
            linearClose3D(imIn, imWrk2, d, size, grid)
            m3D.logic3D(imWrk1, imWrk2, imWrk1, "inf")
        # Finally neighbors located at a 1 distance from the center
        size = n
        for d in [1, 3, 9]:
            linearClose3D(imIn, imWrk2, d, size, grid)
            m3D.logic3D(imWrk1, imWrk2, imWrk1, "inf")
    elif grid == m3D.FACE_CENTER_CUBIC:
        for d in [1, 3, 5, 7, 8, 9]:
            linearClose3D(imIn, imWrk2, d, n, grid)
            m3D.logic3D(imWrk1, imWrk2, imWrk1, "inf")
    else:
        mamba.raiseExceptionOnError(core.MB_ERR_BAD_PARAMETER)
    m3D.copy3D(imWrk1, imOut)
Пример #21
0
def infClose3D(imIn, imOut, n, grid=m3D.DEFAULT_GRID3D):
    """
    Performs the infimum of directional closings. A black particle is preserved
    if its length is larger than 'n' in at least one direction.
    
    This operator is a closing. The image edge is set to 'FILLED' in order to 
    take into account particles touching the edge (they are supposed not to 
    extend outside the image window).
    
    When square grid is used, the size in oblique directions are reduced to be
    similar to the horizontal and vertical size.    
    """

    imWrk1 = m3D.image3DMb(imIn)
    imWrk2 = m3D.image3DMb(imIn)
    imWrk1.fill(m3D.computeMaxRange3D(imIn)[1])
    # Default grid is a proxy for an actual grid
    if grid == m3D.CUBIC:
        # First neighbors located at a sqrt(2) distance from the center
        size = int((1.4142 * n + 1) / 2)
        for d in [2, 4, 10, 12, 14, 16]:
            linearClose3D(imIn, imWrk2, d, size, grid)
            m3D.logic3D(imWrk1, imWrk2, imWrk1, "inf")
        # First neighbors located at a sqrt(3) distance from the center
        size = int((1.7320 * n + 1) / 2)
        for d in [11, 13, 15, 17]:
            linearClose3D(imIn, imWrk2, d, size, grid)
            m3D.logic3D(imWrk1, imWrk2, imWrk1, "inf")
        # Finally neighbors located at a 1 distance from the center
        size = n
        for d in [1, 3, 9]:
            linearClose3D(imIn, imWrk2, d, size, grid)
            m3D.logic3D(imWrk1, imWrk2, imWrk1, "inf")
    elif grid == m3D.FACE_CENTER_CUBIC:
        for d in [1, 3, 5, 7, 8, 9]:
            linearClose3D(imIn, imWrk2, d, n, grid)
            m3D.logic3D(imWrk1, imWrk2, imWrk1, "inf")
    else:
        mamba.raiseExceptionOnError(core.MB_ERR_BAD_PARAMETER)
    m3D.copy3D(imWrk1, imOut)
Пример #22
0
def supOpen3D(imIn, imOut, n, grid=m3D.DEFAULT_GRID3D):
    """
    Performs the supremum of directional openings. A white particle is preserved
    (but not entirely) if its length is larger than 'n' in at least one direction.
    
    This operator is an opening. The image edge is set to 'EMPTY' in order to 
    take into account particles touching the edge (they are considered as entirely
    included in the image window).

    When square grid is used, the size in oblique directions are reduced to be
    similar to the horizontal and vertical size.    
    """

    imWrk1 = m3D.image3DMb(imIn)
    imWrk2 = m3D.image3DMb(imIn)
    imWrk1.reset()
    # Default grid is a proxy for an actual grid
    if grid == m3D.CUBIC:
        # First neighbors located at a sqrt(2) distance from the center
        size = int((1.4142 * n + 1) / 2)
        for d in [2, 4, 10, 12, 14, 16]:
            linearOpen3D(imIn, imWrk2, d, size, grid, edge=mamba.EMPTY)
            m3D.logic3D(imWrk1, imWrk2, imWrk1, "sup")
        # First neighbors located at a sqrt(3) distance from the center
        size = int((1.7320 * n + 1) / 2)
        for d in [11, 13, 15, 17]:
            linearOpen3D(imIn, imWrk2, d, size, grid, edge=mamba.EMPTY)
            m3D.logic3D(imWrk1, imWrk2, imWrk1, "sup")
        # Finally neighbors located at a 1 distance from the center
        size = n
        for d in [1, 3, 9]:
            linearOpen3D(imIn, imWrk2, d, size, grid, edge=mamba.EMPTY)
            m3D.logic3D(imWrk1, imWrk2, imWrk1, "sup")
    elif grid == m3D.FACE_CENTER_CUBIC:
        for d in [1, 3, 5, 7, 8, 9]:
            linearOpen3D(imIn, imWrk2, d, n, grid, edge=mamba.EMPTY)
            m3D.logic3D(imWrk1, imWrk2, imWrk1, "sup")
    else:
        mamba.raiseExceptionOnError(core.MB_ERR_BAD_PARAMETER)
    m3D.copy3D(imWrk1, imOut)
Пример #23
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)
Пример #24
0
def autoMedian3D(imIn, imOut, n, se=m3D.CUBOCTAHEDRON1):
    """
    Morphological automedian filter performed with alternate sequential filters.
    """
    
    oc_im = m3D.image3DMb(imIn)
    co_im = m3D.image3DMb(imIn)
    imWrk = m3D.image3DMb(imIn)
    alternateFilter3D(imIn, oc_im, n, True, se=se)
    alternateFilter3D(imIn, co_im, n, False, se=se)
    m3D.copy3D(imIn, imOut)
    m3D.copy3D(oc_im, imWrk)
    m3D.logic3D(co_im, imWrk, imWrk, "sup")
    m3D.logic3D(imWrk, imOut, imOut, "inf")
    m3D.copy3D(oc_im, imWrk)
    m3D.logic3D(co_im, imWrk, imWrk, "inf")
    m3D.logic3D(imWrk, imOut, imOut, "sup")
Пример #25
0
def autoMedian3D(imIn, imOut, n, se=m3D.CUBOCTAHEDRON1):
    """
    Morphological automedian filter performed with alternate sequential filters.
    """

    oc_im = m3D.image3DMb(imIn)
    co_im = m3D.image3DMb(imIn)
    imWrk = m3D.image3DMb(imIn)
    alternateFilter3D(imIn, oc_im, n, True, se=se)
    alternateFilter3D(imIn, co_im, n, False, se=se)
    m3D.copy3D(imIn, imOut)
    m3D.copy3D(oc_im, imWrk)
    m3D.logic3D(co_im, imWrk, imWrk, "sup")
    m3D.logic3D(imWrk, imOut, imOut, "inf")
    m3D.copy3D(oc_im, imWrk)
    m3D.logic3D(co_im, imWrk, imWrk, "inf")
    m3D.logic3D(imWrk, imOut, imOut, "sup")