コード例 #1
0
ファイル: script.py プロジェクト: nicolasBeucher/mamba-image
def directionalOpen(imIn, imOut, d, size, grid=mamba.DEFAULT_GRID, edge=mamba.FILLED):
    """
    Directional opening of image 'imIn' defined by combining an erosion in
    direction 'd' followed by a dilation in the transposed direction (which
    depends on the grid in use). Result is put in 'imOut'.
    """
    
    directionalErode(imIn, imOut, d, size, grid=grid, edge=edge)
    j = (d + mamba.gridNeighbors(grid=grid) - 1) % (mamba.gridNeighbors(grid=grid) * 2) + 1
    directionalDilate(imOut, imOut, j, size, grid=grid)
コード例 #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)
コード例 #3
0
ファイル: script.py プロジェクト: nicolasBeucher/mamba-image
def directionalOpen(imIn,
                    imOut,
                    d,
                    size,
                    grid=mamba.DEFAULT_GRID,
                    edge=mamba.FILLED):
    """
    Directional opening of image 'imIn' defined by combining an erosion in
    direction 'd' followed by a dilation in the transposed direction (which
    depends on the grid in use). Result is put in 'imOut'.
    """

    directionalErode(imIn, imOut, d, size, grid=grid, edge=edge)
    j = (d + mamba.gridNeighbors(grid=grid) -
         1) % (mamba.gridNeighbors(grid=grid) * 2) + 1
    directionalDilate(imOut, imOut, j, size, grid=grid)
コード例 #4
0
ファイル: erodil.py プロジェクト: nicolasBeucher/mamba-image
    def __init__(self, directions, grid):
        """
        Structuring element constructor. A structuring element is defined by the 
        couple 'directions' (given in an ordered list) and 'grid'. You cannot
        defines a structuring element that holds a direction more than once.
        
        You can look at the predefined structuring elements to get examples of
        how to make yours.
        """

        self.grid = grid
        xx = {}
        for d in directions:
            xx[d] = 1
        self.directions = list(xx.keys())  # This is actually a trick to
        # remove duplicate from the direction
        # list
        self.directions.sort()
        self.directions_w0 = self.directions[:]
        self.has_zero = False
        if self.directions_w0.count(0) > 0:
            self.directions_w0.remove(0)
            self.has_zero = True
        self.enc_dirs = functools.reduce(lambda x, y: x | (1 << y),
                                         self.directions, 0)
        self.enc_dirs_w0 = functools.reduce(lambda x, y: x | (1 << y),
                                            self.directions_w0, 0)
        # neighbors defines the max number of neighbor points according to the grid
        # in use
        self.neighbors = mamba.gridNeighbors(grid)
コード例 #5
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)
コード例 #6
0
ファイル: script.py プロジェクト: nicolasBeucher/mamba-image
def directionalClose(imIn, imOut, d, size, grid=mamba.DEFAULT_GRID, edge=mamba.FILLED):
    """
    Directional closing of image 'imIn' defined by combining a dilation in
    direction 'd' followed by an erosion in the transposed direction (which
    depends on the grid in use). Result is put in 'imOut'.
    If 'edge' is set to 'EMPTY', the operation must be modified to remain extensive.
    """
    
    imWrk = mamba.imageMb(imIn)
    if edge==mamba.EMPTY:
        mamba.copy(imIn, imWrk)
    directionalDilate(imIn, imOut, d, size, grid=grid, edge=edge)
    j = (d + mamba.gridNeighbors(grid=grid) - 1) % (mamba.gridNeighbors(grid=grid) * 2) + 1
    directionalErode(imOut, imOut, j, size, grid=grid)
    if edge==mamba.EMPTY:
        mamba.logic(imOut, imWrk, imOut, "sup")
コード例 #7
0
ファイル: measure.py プロジェクト: nicolasBeucher/mamba-image
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
コード例 #8
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
コード例 #9
0
ファイル: measure.py プロジェクト: nicolasBeucher/mamba-image
def computePerimeter(imIn, scale=(1.0, 1.0), grid=mamba.DEFAULT_GRID):
    """
    Computes the perimeter of all particles in binary image 'imIn' according
    to the Cauchy-Crofton formula. 'scale' is a tuple defining the horizontal
    and vertical scale factors (default is 1.0).
    
    The edge of the image is always set to 'EMPTY'.
    
    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)
    p = 0.
    for i in range(1, mamba.gridNeighbors(grid)//2 + 1):
        p += computeDiameter(imIn, i, scale=scale, grid=grid)
    p = 2*math.pi*p/mamba.gridNeighbors(grid)
    return p
コード例 #10
0
def computePerimeter(imIn, scale=(1.0, 1.0), grid=mamba.DEFAULT_GRID):
    """
    Computes the perimeter of all particles in binary image 'imIn' according
    to the Cauchy-Crofton formula. 'scale' is a tuple defining the horizontal
    and vertical scale factors (default is 1.0).
    
    The edge of the image is always set to 'EMPTY'.
    
    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)
    p = 0.
    for i in range(1, mamba.gridNeighbors(grid) // 2 + 1):
        p += computeDiameter(imIn, i, scale=scale, grid=grid)
    p = 2 * math.pi * p / mamba.gridNeighbors(grid)
    return p
コード例 #11
0
ファイル: script.py プロジェクト: nicolasBeucher/mamba-image
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)
コード例 #12
0
ファイル: script.py プロジェクト: nicolasBeucher/mamba-image
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)
コード例 #13
0
ファイル: script.py プロジェクト: nicolasBeucher/mamba-image
def directionalClose(imIn,
                     imOut,
                     d,
                     size,
                     grid=mamba.DEFAULT_GRID,
                     edge=mamba.FILLED):
    """
    Directional closing of image 'imIn' defined by combining a dilation in
    direction 'd' followed by an erosion in the transposed direction (which
    depends on the grid in use). Result is put in 'imOut'.
    If 'edge' is set to 'EMPTY', the operation must be modified to remain extensive.
    """

    imWrk = mamba.imageMb(imIn)
    if edge == mamba.EMPTY:
        mamba.copy(imIn, imWrk)
    directionalDilate(imIn, imOut, d, size, grid=grid, edge=edge)
    j = (d + mamba.gridNeighbors(grid=grid) -
         1) % (mamba.gridNeighbors(grid=grid) * 2) + 1
    directionalErode(imOut, imOut, j, size, grid=grid)
    if edge == mamba.EMPTY:
        mamba.logic(imOut, imWrk, imOut, "sup")
コード例 #14
0
def rotatingGeodesicThick(imIn, imMask, imOut, dse):
    """
    Performs successive geodesic thickenings of 'imIn' inside 'imMask' with 
    clockwise rotations of the double structuring element 'dse'. The number of 
    rotations is either 6 or 8 according to the grid where 'dse' is defined.
    All the thickenings are concatenated.
    
    'imIn', 'imMask' and 'imOut' are binary images.
    """

    imWrk = mamba.imageMb(imIn)
    mamba.copy(imIn, imOut)
    for i in range(mamba.gridNeighbors(dse.getGrid())):
        hitOrMiss(imOut, imWrk, dse)
        mamba.logic(imWrk, imOut, imOut, "sup")
        mamba.logic(imMask, imOut, imOut, "inf")
        dse = dse.rotate()
コード例 #15
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)
コード例 #16
0
def rotatingGeodesicThick(imIn, imMask, imOut, dse):
    """
    Performs successive geodesic thickenings of 'imIn' inside 'imMask' with 
    clockwise rotations of the double structuring element 'dse'. The number of 
    rotations is either 6 or 8 according to the grid where 'dse' is defined.
    All the thickenings are concatenated.
    
    'imIn', 'imMask' and 'imOut' are binary images.
    """

    imWrk = mamba.imageMb(imIn)
    mamba.copy(imIn, imOut)
    for i in range(mamba.gridNeighbors(dse.getGrid())):
        hitOrMiss(imOut, imWrk, dse)
        mamba.logic(imWrk, imOut, imOut, "sup")
        mamba.logic(imMask, imOut, imOut, "inf")
        dse = dse.rotate()
コード例 #17
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)
コード例 #18
0
def infThin(imIn, imOut, dse, edge=mamba.EMPTY):
    """
    Performs an inf of thinnings, each thinning being made with the successive 
    rotations of 'dse'. The initial image 'imIn' is used at each step of 
    thinning (intersection of thinnings).
    
    'imIn' and 'imOut' are binary images.
    
    'edge' is set to EMPTY by default.
    """

    imWrk1 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn)
    mamba.copy(imIn, imOut)
    mamba.copy(imIn, imWrk1)
    for i in range(mamba.gridNeighbors(dse.getGrid())):
        hitOrMiss(imWrk1, imWrk2, dse, edge=edge)
        mamba.diff(imOut, imWrk2, imOut)
        dse = dse.rotate()
コード例 #19
0
def supThick(imIn, imOut, dse):
    """
    Performs a sup of thickenings, each thickening being made with the successive 
    rotations of 'dse'. The initial image 'imIn' is used at each step of 
    thickening (union of thickenings).

    'imIn' and 'imOut' are binary images.
    
    The edge is always set to EMPTY.
    """
    
    imWrk1 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn)
    mamba.copy(imIn, imWrk1)
    mamba.copy(imIn, imOut)
    for i in range(mamba.gridNeighbors(dse.getGrid())):
        hitOrMiss(imWrk1, imWrk2, dse)
        mamba.logic(imWrk2, imOut, imOut, "sup")
        dse = dse.rotate()
コード例 #20
0
def infThin(imIn, imOut, dse, edge=mamba.EMPTY):
    """
    Performs an inf of thinnings, each thinning being made with the successive 
    rotations of 'dse'. The initial image 'imIn' is used at each step of 
    thinning (intersection of thinnings).
    
    'imIn' and 'imOut' are binary images.
    
    'edge' is set to EMPTY by default.
    """
    
    imWrk1 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn)
    mamba.copy(imIn, imOut)
    mamba.copy(imIn, imWrk1)
    for i in range(mamba.gridNeighbors(dse.getGrid())):
        hitOrMiss(imWrk1, imWrk2, dse, edge=edge)
        mamba.diff(imOut, imWrk2, imOut)
        dse = dse.rotate()
コード例 #21
0
def supThick(imIn, imOut, dse):
    """
    Performs a sup of thickenings, each thickening being made with the successive 
    rotations of 'dse'. The initial image 'imIn' is used at each step of 
    thickening (union of thickenings).

    'imIn' and 'imOut' are binary images.
    
    The edge is always set to EMPTY.
    """

    imWrk1 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn)
    mamba.copy(imIn, imWrk1)
    mamba.copy(imIn, imOut)
    for i in range(mamba.gridNeighbors(dse.getGrid())):
        hitOrMiss(imWrk1, imWrk2, dse)
        mamba.logic(imWrk2, imOut, imOut, "sup")
        dse = dse.rotate()
コード例 #22
0
ファイル: script.py プロジェクト: nicolasBeucher/mamba-image
def directionalCoding(imIn, imOut, grid=mamba.DEFAULT_GRID):
    """
    Coding of the direction which, at each point of 'imIn', corresponds to the
    direction of the maximal intercept through this point. The result of this
    coding is put in the grey scale image 'imOut'.
    6 directions are coded on the hexagonal grid, 8 on the square one.
    """
    imWrk1 = mamba.imageMb(imIn, 32)
    imWrk2 = mamba.imageMb(imIn, 32)
    imWrk3 = mamba.imageMb(imIn)
    imWrk4 = mamba.imageMb(imIn, 8)
    
    imOut.reset()
    imWrk1.reset()
    for i in range(mamba.gridNeighbors(grid=grid)):
        d = i + 1
        linearUltimateOpen(imIn, imWrk2, d, grid=grid)
        mamba.generateSupMask(imWrk2, imWrk1, imWrk3, True)
        mamba.logic(imWrk2, imWrk1, imWrk1, "sup")
        mamba.convertByMask(imWrk3, imWrk4, 0, d)
        mamba.logic(imWrk4, imOut, imOut, "sup")       
コード例 #23
0
ファイル: script.py プロジェクト: nicolasBeucher/mamba-image
def directionalCoding(imIn, imOut, grid=mamba.DEFAULT_GRID):
    """
    Coding of the direction which, at each point of 'imIn', corresponds to the
    direction of the maximal intercept through this point. The result of this
    coding is put in the grey scale image 'imOut'.
    6 directions are coded on the hexagonal grid, 8 on the square one.
    """
    imWrk1 = mamba.imageMb(imIn, 32)
    imWrk2 = mamba.imageMb(imIn, 32)
    imWrk3 = mamba.imageMb(imIn)
    imWrk4 = mamba.imageMb(imIn, 8)

    imOut.reset()
    imWrk1.reset()
    for i in range(mamba.gridNeighbors(grid=grid)):
        d = i + 1
        linearUltimateOpen(imIn, imWrk2, d, grid=grid)
        mamba.generateSupMask(imWrk2, imWrk1, imWrk3, True)
        mamba.logic(imWrk2, imWrk1, imWrk1, "sup")
        mamba.convertByMask(imWrk3, imWrk4, 0, d)
        mamba.logic(imWrk4, imOut, imOut, "sup")
コード例 #24
0
def diameterLabelling(imIn, imOut, dir, grid=mamba.DEFAULT_GRID):
    """
    Labels each connected component of the binary image 'imIn' with its diameter in 
    direction 'dir'. The labelled image is stored in the 32-bit image 'imOut'.
    If 'imIn' is a 8-bit or 32-bit image, this function works too. However, the
    0-valued connected components are labelled with 0.
    This procedure works on hexagonal or square grid.
    'dir' can be any strictly positive integer value.
    """
    
    imWrk1 = mamba.imageMb(imIn, 1)
    imWrk2 = mamba.imageMb(imIn)
    
    ed = 1 << ((dir - 1)%(mamba.gridNeighbors(grid)//2)) +1
    if imIn.getDepth() == 1:
        mamba.copy(imIn, imWrk1)
        mamba.diffNeighbor(imIn, imWrk1, ed, grid=grid)
    else:
        mamba.nonEqualNeighbors(imIn, imWrk2, ed, grid=grid, edge= mamba.EMPTY)
        mamba.threshold(imWrk2, imWrk1, 1, mamba.computeMaxRange(imWrk2)[1])
    # They are used for the labelling.
    measureLabelling(imIn, imWrk1, imOut)
コード例 #25
0
def diameterLabelling(imIn, imOut, dir, grid=mamba.DEFAULT_GRID):
    """
    Labels each connected component of the binary image 'imIn' with its diameter in 
    direction 'dir'. The labelled image is stored in the 32-bit image 'imOut'.
    If 'imIn' is a 8-bit or 32-bit image, this function works too. However, the
    0-valued connected components are labelled with 0.
    This procedure works on hexagonal or square grid.
    'dir' can be any strictly positive integer value.
    """

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

    ed = 1 << ((dir - 1) % (mamba.gridNeighbors(grid) // 2)) + 1
    if imIn.getDepth() == 1:
        mamba.copy(imIn, imWrk1)
        mamba.diffNeighbor(imIn, imWrk1, ed, grid=grid)
    else:
        mamba.nonEqualNeighbors(imIn, imWrk2, ed, grid=grid, edge=mamba.EMPTY)
        mamba.threshold(imWrk2, imWrk1, 1, mamba.computeMaxRange(imWrk2)[1])
    # They are used for the labelling.
    measureLabelling(imIn, imWrk1, imOut)