Esempio n. 1
0
    def __init__(self, *args):
        """
        Double structuring 3D element constructor. A double structuring
        element is defined by the first (background points) and second 
        (foreground points) structuring elements 3D.
        
        You can define it in two ways:
            * doubleStructuringElement3D(se0, se1): where 'se0' and 'se1' are 
            instances of the class structuringElement3D found in erodil3D
            module. These structuring elements must be defined on the same grid.
            * doubleStructuringElement3D(dse0, dse1, grid): where 'dse0' and
            'dse1' are direction lists and 'grid' defines the grid on which the
            two structuring elements are defined.
            
        If the constructor is called with inapropriate arguments, it raises a
        ValueError exception.
        """

        if len(args) == 2:
            if args[0].getGrid() != args[1].getGrid():
                raise ValueError("Grid value mismatch")
            self.se0 = args[0]
            self.se1 = args[1]
            self.grid = self.se0.getGrid()
        elif len(args) == 3:
            self.se0 = m3D.structuringElement3D(args[0], args[2])
            self.se1 = m3D.structuringElement3D(args[1], args[2])
            self.grid = args[2]
        else:
            raise ValueError("Incorrect constructor call")
Esempio n. 2
0
 def __init__(self, *args):
     """
     Double structuring 3D element constructor. A double structuring
     element is defined by the first (background points) and second 
     (foreground points) structuring elements 3D.
     
     You can define it in two ways:
         * doubleStructuringElement3D(se0, se1): where 'se0' and 'se1' are 
         instances of the class structuringElement3D found in erodil3D
         module. These structuring elements must be defined on the same grid.
         * doubleStructuringElement3D(dse0, dse1, grid): where 'dse0' and
         'dse1' are direction lists and 'grid' defines the grid on which the
         two structuring elements are defined.
         
     If the constructor is called with inapropriate arguments, it raises a
     ValueError exception.
     """
     
     if len(args)==2:
         if args[0].getGrid()!=args[1].getGrid():
             raise ValueError("Grid value mismatch")
         self.se0 = args[0]
         self.se1 = args[1]
         self.grid = self.se0.getGrid()
     elif len(args)==3:
         self.se0 = m3D.structuringElement3D(args[0], args[2])
         self.se1 = m3D.structuringElement3D(args[1], args[2])
         self.grid = args[2]
     else:
         raise ValueError("Incorrect constructor call")
Esempio n. 3
0
def mosaicGradient3D(imIn, imOut, grid=m3D.DEFAULT_GRID3D):
    """
    Builds the mosaic-gradient 3D 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 = m3D.image3DMb(imIn)
    imWrk2 = m3D.image3DMb(imIn)
    imWrk3 = m3D.image3DMb(imIn)
    imWrk4 = m3D.image3DMb(imIn)
    imWrk5 = m3D.image3DMb(imIn)
    mosaic3D(imIn, imWrk2, imWrk3, grid=grid)
    m3D.sub3D(imWrk2, imWrk3, imWrk1)
    m3D.logic3D(imWrk2, imWrk3, imWrk2, "sup")
    m3D.negate3D(imWrk2, imWrk2)
    se = m3D.structuringElement3D(m3D.getDirections3D(grid), grid)
    while m3D.computeVolume3D(imWrk3) != 0:
        m3D.dilate3D(imWrk1, imWrk4, 2, se=se)
        m3D.dilate3D(imWrk2, imWrk5, 2, se=se)
        m3D.logic3D(imWrk4, imWrk3, imWrk4, "inf")
        m3D.logic3D(imWrk5, imWrk3, imWrk5, "inf")
        m3D.logic3D(imWrk1, imWrk4, imWrk1, "sup")
        m3D.logic3D(imWrk2, imWrk5, imWrk2, "sup")
        m3D.erode3D(imWrk3, imWrk3, 2, se=se)
    m3D.negate3D(imWrk2, imWrk2)
    m3D.sub3D(imWrk1, imWrk2, imOut)
Esempio n. 4
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)
Esempio n. 5
0
def mosaicGradient3D(imIn, imOut, grid=m3D.DEFAULT_GRID3D):
    """
    Builds the mosaic-gradient 3D 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 = m3D.image3DMb(imIn)
    imWrk2 = m3D.image3DMb(imIn)
    imWrk3 = m3D.image3DMb(imIn)
    imWrk4 = m3D.image3DMb(imIn)
    imWrk5 = m3D.image3DMb(imIn)
    mosaic3D(imIn, imWrk2, imWrk3, grid=grid)
    m3D.sub3D(imWrk2, imWrk3, imWrk1)
    m3D.logic3D(imWrk2, imWrk3, imWrk2, "sup")
    m3D.negate3D(imWrk2, imWrk2)
    se = m3D.structuringElement3D(m3D.getDirections3D(grid), grid)
    while m3D.computeVolume3D(imWrk3) != 0:
        m3D.dilate3D(imWrk1, imWrk4, 2, se=se)
        m3D.dilate3D(imWrk2, imWrk5, 2, se=se)
        m3D.logic3D(imWrk4, imWrk3, imWrk4, "inf")
        m3D.logic3D(imWrk5, imWrk3, imWrk5, "inf")
        m3D.logic3D(imWrk1, imWrk4, imWrk1, "sup")
        m3D.logic3D(imWrk2, imWrk5, imWrk2, "sup")
        m3D.erode3D(imWrk3, imWrk3, 2, se=se)
    m3D.negate3D(imWrk2, imWrk2)
    m3D.sub3D(imWrk1, imWrk2, imOut)
Esempio n. 6
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)
def drawEdge3D(imOut, thick=1):
    """
    Draws a frame around the edge of 'imOut' whose value equals the maximum
    range value and whose thickness is given by 'thick' (default 1).
    """
    
    imOut.reset()
    se=m3D.structuringElement3D(list(m3D.getDirections3D(m3D.CUBIC)), m3D.CUBIC)
    m3D.dilate3D(imOut, imOut, thick, se=se, edge=mamba.FILLED)
Esempio n. 8
0
def drawEdge3D(imOut, thick=1):
    """
    Draws a frame around the edge of 'imOut' whose value equals the maximum
    range value and whose thickness is given by 'thick' (default 1).
    """

    imOut.reset()
    se = m3D.structuringElement3D(list(m3D.getDirections3D(m3D.CUBIC)),
                                  m3D.CUBIC)
    m3D.dilate3D(imOut, imOut, thick, se=se, edge=mamba.FILLED)
Esempio n. 9
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)
Esempio n. 10
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)
Esempio n. 11
0
def removeEdgeParticles3D(imIn, imOut, grid=m3D.DEFAULT_GRID3D):
    """
    Removes particles (connected components) touching the edge in 3D image
    'imIn'. The resulting image is put in image 'imOut'.
    Although this operator may be used with greytone images, it should be
    considered with caution.
    """
    
    imWrk = m3D.image3DMb(imIn)
    se = m3D.structuringElement3D(m3D.getDirections3D(grid), grid)
    m3D.dilate3D(imWrk, imWrk, se=se, edge=mamba.FILLED)
    m3D.logic3D(imIn, imWrk, imWrk, "inf")
    build3D(imIn, imWrk, grid=grid)
    m3D.diff3D(imIn, imWrk, imOut)
Esempio n. 12
0
def removeEdgeParticles3D(imIn, imOut, grid=m3D.DEFAULT_GRID3D):
    """
    Removes particles (connected components) touching the edge in 3D image
    'imIn'. The resulting image is put in image 'imOut'.
    Although this operator may be used with greytone images, it should be
    considered with caution.
    """

    imWrk = m3D.image3DMb(imIn)
    se = m3D.structuringElement3D(m3D.getDirections3D(grid), grid)
    m3D.dilate3D(imWrk, imWrk, se=se, edge=mamba.FILLED)
    m3D.logic3D(imIn, imWrk, imWrk, "inf")
    build3D(imIn, imWrk, grid=grid)
    m3D.diff3D(imIn, imWrk, imOut)
Esempio n. 13
0
def regularisedGradient3D(imIn, imOut, n, grid=m3D.DEFAULT_GRID3D):
    """
    Computes the regularized gradient of 3D image 'imIn' of size 'n'.
    The result is put in 'imOut'. A regularized gradient of size 'n' extracts
    in the 3D image contours thinner than 'n' while avoiding false detections.
    
    This operation is only valid for omnidirectional structuring elements.
    """
    
    imWrk = m3D.image3DMb(imIn)
    se = m3D.structuringElement3D(m3D.getDirections3D(grid), grid)
    gradient3D(imIn, imWrk, n, se=se)
    whiteTopHat3D(imWrk, imWrk, n, se=se)
    m3D.erode3D(imWrk, imOut, n-1, se=se)
Esempio n. 14
0
def strongLevelling3D(imIn, imOut, n, eroFirst, grid=m3D.DEFAULT_GRID3D):
    """
    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 simpleLevelling3D. However, the
    order of the initial operations (erosion and dilation) matters.
    """

    imWrk = m3D.image3DMb(imIn)
    se = m3D.structuringElement3D(m3D.getDirections3D(grid), grid)
    if eroFirst:
        m3D.erode3D(imIn, imWrk, n, se=se)
        m3D.build3D(imIn, imWrk, grid=grid)
        m3D.dilate3D(imIn, imOut, n, se=se)
        m3D.dualBuild3D(imWrk, imOut, grid=grid)
    else:
        m3D.dilate3D(imIn, imWrk, n, se=se)
        m3D.dualBuild3D(imIn, imWrk, grid=grid)
        m3D.erode3D(imIn, imOut, n, se=se)
        m3D.build3D(imWrk, imOut, grid=grid)
Esempio n. 15
0
def strongLevelling3D(imIn, imOut, n, eroFirst, grid=m3D.DEFAULT_GRID3D):
    """
    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 simpleLevelling3D. However, the
    order of the initial operations (erosion and dilation) matters.
    """
    
    imWrk = m3D.image3DMb(imIn)
    se = m3D.structuringElement3D(m3D.getDirections3D(grid), grid)
    if eroFirst:
        m3D.erode3D(imIn, imWrk, n, se=se)
        m3D.build3D(imIn, imWrk, grid=grid)
        m3D.dilate3D(imIn, imOut, n, se=se)
        m3D.dualBuild3D(imWrk, imOut, grid=grid)
    else:
        m3D.dilate3D(imIn, imWrk, n, se=se)
        m3D.dualBuild3D(imIn, imWrk, grid=grid)
        m3D.erode3D(imIn, imOut, n, se=se)
        m3D.build3D(imWrk, imOut, grid=grid)