Example #1
0
def volumeLabelling(imIn1, imIn2, imOut):
    """
    Each connected component of the binary image  or the partition 'imIn1' is
    labelled with the volume of the greyscale or 32-bit image 'imIn2' inside
    this component. The result is put in the 32-bit image 'imOut'.
    """
    
    imWrk1 = mamba.imageMb(imIn1, 1)
    imWrk2 = mamba.imageMb(imIn1, 32)
    imWrk3 = mamba.imageMb(imIn1, 8)
    
    imOut.reset()
    n = imIn2.getDepth()
    # Case of a 8-bit image.
    if n == 8:
        for i in range(8):
            # Each bit plane is extracted and used in the labelling.
            mamba.copyBitPlane(imIn2, i, imWrk1)
            measureLabelling(imIn1, imWrk1, imWrk2)
            # The resulting labels are combined to obtain the final one.
            v = 2 ** i
            mamba.mulConst(imWrk2, v, imWrk2)
            mamba.add(imOut, imWrk2, imOut)
    else:
        for j in range(4):
            # Each byte plane is treated.
            mamba.copyBytePlane(imIn2, j, imWrk3)
            for i in range(8):
                mamba.copyBitPlane(imWrk3, i, imWrk1)
                measureLabelling(imIn1, imWrk1, imWrk2)
                v = 2 ** (8 * j + i)
                mamba.mulConst(imWrk2, v, imWrk2)
                mamba.add(imOut, imWrk2, imOut) 
Example #2
0
def mosaic(imIn, imOut, imWts, grid=mamba.DEFAULT_GRID):
    """
    Builds the mosaic image of 'imIn' and puts the results into 'imOut'.
    The watershed line (pixel values set to 255) is stored in the 
    greytone 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 = mamba.imageMb(imIn, 1)
    imWrk2 = mamba.imageMb(imIn)
    mamba.copy(imIn, imWrk2)
    im_mark = mamba.imageMb(imIn, 32)
    se = mamba.structuringElement(mamba.getDirections(grid), grid)
    mamba.gradient(imIn, imOut, se=se)
    mamba.minima(imOut, imWrk1, grid=grid)
    mamba.add(im_mark, imWrk1, im_mark)
    imWrk1.convert(8)
    mamba.build(imWrk1, imWrk2, grid=grid)
    mamba.add(im_mark, imWrk2, im_mark)
    watershedSegment(imOut, im_mark, grid=grid)
    mamba.copyBytePlane(im_mark, 3, imWts)
    mamba.subConst(im_mark, 1, im_mark)
    mamba.copyBytePlane(im_mark, 0, imOut)
Example #3
0
def mosaic(imIn, imOut, imWts, grid=mamba.DEFAULT_GRID):
    """
    Builds the mosaic image of 'imIn' and puts the results into 'imOut'.
    The watershed line (pixel values set to 255) is stored in the 
    greytone 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 = mamba.imageMb(imIn, 1)
    imWrk2 = mamba.imageMb(imIn)
    mamba.copy(imIn, imWrk2)
    im_mark = mamba.imageMb(imIn, 32)
    se = mamba.structuringElement(mamba.getDirections(grid), grid)
    mamba.gradient(imIn, imOut, se=se)
    mamba.minima(imOut, imWrk1, grid=grid)
    mamba.add(im_mark, imWrk1, im_mark)
    imWrk1.convert(8)
    mamba.build(imWrk1, imWrk2, grid=grid)
    mamba.add(im_mark, imWrk2, im_mark)
    watershedSegment(imOut, im_mark, grid=grid)
    mamba.copyBytePlane(im_mark, 3, imWts)
    mamba.subConst(im_mark, 1, im_mark)
    mamba.copyBytePlane(im_mark, 0, imOut)
Example #4
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 #5
0
def volumeLabelling(imIn1, imIn2, imOut):
    """
    Each connected component of the binary image  or the partition 'imIn1' is
    labelled with the volume of the greyscale or 32-bit image 'imIn2' inside
    this component. The result is put in the 32-bit image 'imOut'.
    """

    imWrk1 = mamba.imageMb(imIn1, 1)
    imWrk2 = mamba.imageMb(imIn1, 32)
    imWrk3 = mamba.imageMb(imIn1, 8)

    imOut.reset()
    n = imIn2.getDepth()
    # Case of a 8-bit image.
    if n == 8:
        for i in range(8):
            # Each bit plane is extracted and used in the labelling.
            mamba.copyBitPlane(imIn2, i, imWrk1)
            measureLabelling(imIn1, imWrk1, imWrk2)
            # The resulting labels are combined to obtain the final one.
            v = 2**i
            mamba.mulConst(imWrk2, v, imWrk2)
            mamba.add(imOut, imWrk2, imOut)
    else:
        for j in range(4):
            # Each byte plane is treated.
            mamba.copyBytePlane(imIn2, j, imWrk3)
            for i in range(8):
                mamba.copyBitPlane(imWrk3, i, imWrk1)
                measureLabelling(imIn1, imWrk1, imWrk2)
                v = 2**(8 * j + i)
                mamba.mulConst(imWrk2, v, imWrk2)
                mamba.add(imOut, imWrk2, imOut)
def generalSegment(imIn, imOut, gain=2.0, offset=1, grid=mamba.DEFAULT_GRID):
    """
    General segmentation algorithm. This algorithm is controlled by two
    parameters: the 'gain' (identical to the gain used in standard and P
    segmentation) and a new one, the 'offset'. The 'offset' indicates which
    level of hierarchy is compared to the current hierarchical image.
    The 'offset' is relative to the current hierarchical level. If 'offset' is
    equal to 1, this operator corresponds to the standard segmentation, if
    'offset' is equal to 255 (this value stands for the infinity), the operator
    is equivalent to P algorithm.
    Image 'imOut' contains all these hierarchies which are embedded.
    'imIn' and 'imOut' must be greyscale images. 'imIn' and 'imOut' must be
    different.
    This transformation returns the number of hierarchical levels.    
    """
    
    imWrk0 = mamba.imageMb(imIn)
    imWrk1 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn)
    imWrk3 = mamba.imageMb(imIn)
    imWrk4 = mamba.imageMb(imIn, 1)
    imWrk5 = mamba.imageMb(imIn, 1)
    imWrk6 = mamba.imageMb(imIn, 32)    
    mamba.copy(imIn, imWrk1)
    mamba.mulRealConst(imIn, gain, imWrk6)
    mamba.floorSubConst(imWrk6, 1, imWrk6)
    mamba.threshold(imWrk6, imWrk4, 255, mamba.computeMaxRange(imWrk6)[1])  
    mamba.copyBytePlane(imWrk6, 0, imWrk0)
    mamba.convert(imWrk4, imWrk2)
    mamba.logic(imWrk0, imWrk2, imWrk0, "sup")
    mamba.logic(imWrk0, imWrk1, imWrk0, "sup")
    imOut.reset()
    nbLevels = 0
    mamba.threshold(imWrk1, imWrk4, 1, 255)
    flag = not(mamba.checkEmptiness(imWrk4))
    while flag:
        nbLevels += 1
        hierarchy(imWrk1, imWrk4, imWrk2, grid=grid)
        mamba.add(imOut, imWrk4, imOut)
        v = max(nbLevels - offset, 0) + 1
        mamba.threshold(imOut, imWrk4, v, 255)
        mamba.valuedWatershed(imWrk2, imWrk3, grid=grid)
        mamba.threshold(imWrk3, imWrk5, 1, 255)
        flag = not(mamba.checkEmptiness(imWrk5))
        hierarchy(imWrk3, imWrk5, imWrk2, grid=grid)
        mamba.generateSupMask(imWrk0, imWrk2, imWrk5, strict=False)
        mamba.logic(imWrk4, imWrk5, imWrk4, "inf")
        mamba.convertByMask(imWrk4, imWrk3, 0, 255)
        mamba.logic(imWrk1, imWrk3, imWrk3, "inf")
        mamba.negate(imWrk4, imWrk4)
        mamba.label(imWrk4, imWrk6, grid=grid)
        mamba.watershedSegment(imWrk3, imWrk6, grid=grid)
        mamba.copyBytePlane(imWrk6, 3, imWrk3)
        mamba.logic(imWrk1, imWrk2, imWrk1, "sup")
        mamba.logic(imWrk1, imWrk3, imWrk1, "inf")
        mamba.threshold(imWrk1, imWrk4, 1, 255)
    return nbLevels
def generalSegment(imIn, imOut, gain=2.0, offset=1, grid=mamba.DEFAULT_GRID):
    """
    General segmentation algorithm. This algorithm is controlled by two
    parameters: the 'gain' (identical to the gain used in standard and P
    segmentation) and a new one, the 'offset'. The 'offset' indicates which
    level of hierarchy is compared to the current hierarchical image.
    The 'offset' is relative to the current hierarchical level. If 'offset' is
    equal to 1, this operator corresponds to the standard segmentation, if
    'offset' is equal to 255 (this value stands for the infinity), the operator
    is equivalent to P algorithm.
    Image 'imOut' contains all these hierarchies which are embedded.
    'imIn' and 'imOut' must be greyscale images. 'imIn' and 'imOut' must be
    different.
    This transformation returns the number of hierarchical levels.    
    """

    imWrk0 = mamba.imageMb(imIn)
    imWrk1 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn)
    imWrk3 = mamba.imageMb(imIn)
    imWrk4 = mamba.imageMb(imIn, 1)
    imWrk5 = mamba.imageMb(imIn, 1)
    imWrk6 = mamba.imageMb(imIn, 32)
    mamba.copy(imIn, imWrk1)
    mamba.mulRealConst(imIn, gain, imWrk6)
    mamba.floorSubConst(imWrk6, 1, imWrk6)
    mamba.threshold(imWrk6, imWrk4, 255, mamba.computeMaxRange(imWrk6)[1])
    mamba.copyBytePlane(imWrk6, 0, imWrk0)
    mamba.convert(imWrk4, imWrk2)
    mamba.logic(imWrk0, imWrk2, imWrk0, "sup")
    mamba.logic(imWrk0, imWrk1, imWrk0, "sup")
    imOut.reset()
    nbLevels = 0
    mamba.threshold(imWrk1, imWrk4, 1, 255)
    flag = not (mamba.checkEmptiness(imWrk4))
    while flag:
        nbLevels += 1
        hierarchy(imWrk1, imWrk4, imWrk2, grid=grid)
        mamba.add(imOut, imWrk4, imOut)
        v = max(nbLevels - offset, 0) + 1
        mamba.threshold(imOut, imWrk4, v, 255)
        mamba.valuedWatershed(imWrk2, imWrk3, grid=grid)
        mamba.threshold(imWrk3, imWrk5, 1, 255)
        flag = not (mamba.checkEmptiness(imWrk5))
        hierarchy(imWrk3, imWrk5, imWrk2, grid=grid)
        mamba.generateSupMask(imWrk0, imWrk2, imWrk5, strict=False)
        mamba.logic(imWrk4, imWrk5, imWrk4, "inf")
        mamba.convertByMask(imWrk4, imWrk3, 0, 255)
        mamba.logic(imWrk1, imWrk3, imWrk3, "inf")
        mamba.negate(imWrk4, imWrk4)
        mamba.label(imWrk4, imWrk6, grid=grid)
        mamba.watershedSegment(imWrk3, imWrk6, grid=grid)
        mamba.copyBytePlane(imWrk6, 3, imWrk3)
        mamba.logic(imWrk1, imWrk2, imWrk1, "sup")
        mamba.logic(imWrk1, imWrk3, imWrk1, "inf")
        mamba.threshold(imWrk1, imWrk4, 1, 255)
    return nbLevels
def standardSegment(imIn, imOut, gain=2.0, grid=mamba.DEFAULT_GRID):
    """
    General standard segmentation. This algorithm keeps the contours of the 
    watershed transform which are above or equal to the hierarchical image 
    associated to the next level of hierarchy when the altitude of the contour
    is multiplied by a 'gain' factor (default is 2.0). This transform also ends 
    by idempotence. All the hierarchical levels of image 'imIn'(which is a 
    valued watershed) are computed. 'imOut' contains all these hierarchies which
    are embedded, so that hierarchy i is simply obtained by a threshold
    [i+1, 255] of image 'imOut'.
    'imIn' and 'imOut' must be greyscale images. 'imIn' and 'imOut' must be
    different.
    This transformation returns the number of hierarchical levels.    
    """
    
    imWrk0 = mamba.imageMb(imIn)
    imWrk1 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn)
    imWrk3 = mamba.imageMb(imIn)
    imWrk4 = mamba.imageMb(imIn, 1)
    imWrk5 = mamba.imageMb(imIn, 1)
    imWrk6 = mamba.imageMb(imIn, 32)    
    mamba.copy(imIn, imWrk1)
    mamba.mulRealConst(imIn, gain, imWrk6)
    mamba.floorSubConst(imWrk6, 1, imWrk6)
    mamba.threshold(imWrk6, imWrk4, 255, mamba.computeMaxRange(imWrk6)[1])  
    mamba.copyBytePlane(imWrk6, 0, imWrk0)
    mamba.convert(imWrk4, imWrk2)
    mamba.logic(imWrk0, imWrk2, imWrk0, "sup")
    mamba.logic(imWrk0, imWrk1, imWrk0, "sup")
    imOut.reset()
    nbLevels = 0
    mamba.threshold(imWrk1, imWrk4, 1, 255)
    flag = not(mamba.checkEmptiness(imWrk4))
    while flag:
        hierarchy(imWrk1, imWrk4, imWrk2, grid=grid)
        mamba.add(imOut, imWrk4, imOut)
        mamba.valuedWatershed(imWrk2, imWrk3, grid=grid)
        mamba.threshold(imWrk3, imWrk5, 1, 255)
        flag = not(mamba.checkEmptiness(imWrk5))
        hierarchy(imWrk3, imWrk5, imWrk2, grid=grid)
        mamba.generateSupMask(imWrk0, imWrk2, imWrk5, strict=False)
        mamba.logic(imWrk4, imWrk5, imWrk4, "inf")
        mamba.convertByMask(imWrk4, imWrk3, 0, 255)
        mamba.logic(imWrk1, imWrk3, imWrk3, "inf")
        mamba.negate(imWrk4, imWrk4)
        mamba.label(imWrk4, imWrk6, grid=grid)
        mamba.watershedSegment(imWrk3, imWrk6, grid=grid)
        mamba.copyBytePlane(imWrk6, 3, imWrk3)
        mamba.logic(imWrk1, imWrk2, imWrk1, "sup")
        mamba.logic(imWrk1, imWrk3, imWrk1, "inf")
        mamba.threshold(imWrk1, imWrk4, 1, 255)
        nbLevels += 1
    return nbLevels
def standardSegment(imIn, imOut, gain=2.0, grid=mamba.DEFAULT_GRID):
    """
    General standard segmentation. This algorithm keeps the contours of the 
    watershed transform which are above or equal to the hierarchical image 
    associated to the next level of hierarchy when the altitude of the contour
    is multiplied by a 'gain' factor (default is 2.0). This transform also ends 
    by idempotence. All the hierarchical levels of image 'imIn'(which is a 
    valued watershed) are computed. 'imOut' contains all these hierarchies which
    are embedded, so that hierarchy i is simply obtained by a threshold
    [i+1, 255] of image 'imOut'.
    'imIn' and 'imOut' must be greyscale images. 'imIn' and 'imOut' must be
    different.
    This transformation returns the number of hierarchical levels.    
    """

    imWrk0 = mamba.imageMb(imIn)
    imWrk1 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn)
    imWrk3 = mamba.imageMb(imIn)
    imWrk4 = mamba.imageMb(imIn, 1)
    imWrk5 = mamba.imageMb(imIn, 1)
    imWrk6 = mamba.imageMb(imIn, 32)
    mamba.copy(imIn, imWrk1)
    mamba.mulRealConst(imIn, gain, imWrk6)
    mamba.floorSubConst(imWrk6, 1, imWrk6)
    mamba.threshold(imWrk6, imWrk4, 255, mamba.computeMaxRange(imWrk6)[1])
    mamba.copyBytePlane(imWrk6, 0, imWrk0)
    mamba.convert(imWrk4, imWrk2)
    mamba.logic(imWrk0, imWrk2, imWrk0, "sup")
    mamba.logic(imWrk0, imWrk1, imWrk0, "sup")
    imOut.reset()
    nbLevels = 0
    mamba.threshold(imWrk1, imWrk4, 1, 255)
    flag = not (mamba.checkEmptiness(imWrk4))
    while flag:
        hierarchy(imWrk1, imWrk4, imWrk2, grid=grid)
        mamba.add(imOut, imWrk4, imOut)
        mamba.valuedWatershed(imWrk2, imWrk3, grid=grid)
        mamba.threshold(imWrk3, imWrk5, 1, 255)
        flag = not (mamba.checkEmptiness(imWrk5))
        hierarchy(imWrk3, imWrk5, imWrk2, grid=grid)
        mamba.generateSupMask(imWrk0, imWrk2, imWrk5, strict=False)
        mamba.logic(imWrk4, imWrk5, imWrk4, "inf")
        mamba.convertByMask(imWrk4, imWrk3, 0, 255)
        mamba.logic(imWrk1, imWrk3, imWrk3, "inf")
        mamba.negate(imWrk4, imWrk4)
        mamba.label(imWrk4, imWrk6, grid=grid)
        mamba.watershedSegment(imWrk3, imWrk6, grid=grid)
        mamba.copyBytePlane(imWrk6, 3, imWrk3)
        mamba.logic(imWrk1, imWrk2, imWrk1, "sup")
        mamba.logic(imWrk1, imWrk3, imWrk1, "inf")
        mamba.threshold(imWrk1, imWrk4, 1, 255)
        nbLevels += 1
    return nbLevels
Example #10
0
def contrastEnhancer(imIn, imOut, n=1, se=mamba.DEFAULT_SE):
    """
    Increase the contrast of image 'imIn' and put the result in
    image 'imOut'. Parameter 'n' will control the size and 'se' the
    structuring element used by the top hat operators.
    """

    imWrk = mamba.imageMb(imIn)
    mamba.whiteTopHat(imIn, imWrk, n, se=se)
    mamba.add(imIn, imWrk, imOut)
    mamba.blackTopHat(imIn, imWrk, n, se=se)
    mamba.sub(imOut, imWrk, imOut) 
Example #11
0
def neighborCounter(imIn, imOut, grid=mamba.DEFAULT_GRID):
    """
    For each pixel set to true in the binary image 'imIn', this function
    counts its neighbor set to true and puts the result in 'imOut'. The
    neighbors are selected according to 'grid'.
    """

    imWrk = mamba.imageMb(imIn)
    imOut.reset()

    for d in mamba.getDirections(grid)[1:]:
        dse = mamba.doubleStructuringElement([], [0, d], grid)
        mamba.hitOrMiss(imIn, imWrk, dse)
        mamba.add(imOut, imWrk, imOut)
Example #12
0
def neighborCounter(imIn, imOut, grid=mamba.DEFAULT_GRID):
    """
    For each pixel set to true in the binary image 'imIn', this function
    counts its neighbor set to true and puts the result in 'imOut'. The
    neighbors are selected according to 'grid'.
    """

    imWrk = mamba.imageMb(imIn)
    imOut.reset()
    
    for d in mamba.getDirections(grid)[1:]:
        dse = mamba.doubleStructuringElement([],[0,d],grid)
        mamba.hitOrMiss(imIn, imWrk, dse)
        mamba.add(imOut, imWrk, imOut)
Example #13
0
def extendedSegment(imIn, imTest, imOut, offset=255, grid=mamba.DEFAULT_GRID):
    """
    Extended (experimental) segmentation algorithm. This algorithm is controlled
    by image 'imTest'. The current hierarchical image is compared to image
    'imTest'. This image must be a greyscale image. The 'offset' indicates which
    level of hierarchy is compared to the current hierarchical image.
    The 'offset' is relative to the current hierarchical level (by default,
    'offset' is equal to 255, so that the initial segmentation is used).
    Image 'imOut' contains all these hierarchies which are embedded.
    'imIn', 'imTest' and 'imOut' must be greyscale images.
    'imIn', 'imTest' and 'imOut' must be different.
    This transformation returns the number of hierarchical levels.    
    """

    imWrk1 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn)
    imWrk3 = mamba.imageMb(imIn)
    imWrk4 = mamba.imageMb(imIn, 1)
    imWrk5 = mamba.imageMb(imIn, 1)
    imWrk6 = mamba.imageMb(imIn, 32)
    mamba.copy(imIn, imWrk1)
    imOut.reset()
    nbLevels = 0
    mamba.threshold(imWrk1, imWrk4, 1, 255)
    flag = not (mamba.checkEmptiness(imWrk4))
    while flag:
        nbLevels += 1
        hierarchy(imWrk1, imWrk4, imWrk2, grid=grid)
        mamba.add(imOut, imWrk4, imOut)
        v = max(nbLevels - offset, 0) + 1
        mamba.threshold(imOut, imWrk4, v, 255)
        mamba.valuedWatershed(imWrk2, imWrk3, grid=grid)
        mamba.threshold(imWrk3, imWrk5, 1, 255)
        flag = not (mamba.checkEmptiness(imWrk5))
        hierarchy(imWrk3, imWrk5, imWrk2, grid=grid)
        mamba.generateSupMask(imTest, imWrk2, imWrk5, strict=False)
        mamba.logic(imWrk4, imWrk5, imWrk4, "inf")
        mamba.convertByMask(imWrk4, imWrk3, 0, 255)
        mamba.logic(imWrk1, imWrk3, imWrk3, "inf")
        mamba.negate(imWrk4, imWrk4)
        mamba.label(imWrk4, imWrk6, grid=grid)
        mamba.watershedSegment(imWrk3, imWrk6, grid=grid)
        mamba.copyBytePlane(imWrk6, 3, imWrk3)
        mamba.logic(imWrk1, imWrk2, imWrk1, "sup")
        mamba.logic(imWrk1, imWrk3, imWrk1, "inf")
        mamba.threshold(imWrk1, imWrk4, 1, 255)
    return nbLevels
Example #14
0
def extendedSegment(imIn, imTest, imOut, offset=255, grid=mamba.DEFAULT_GRID):
    """
    Extended (experimental) segmentation algorithm. This algorithm is controlled
    by image 'imTest'. The current hierarchical image is compared to image
    'imTest'. This image must be a greyscale image. The 'offset' indicates which
    level of hierarchy is compared to the current hierarchical image.
    The 'offset' is relative to the current hierarchical level (by default,
    'offset' is equal to 255, so that the initial segmentation is used).
    Image 'imOut' contains all these hierarchies which are embedded.
    'imIn', 'imTest' and 'imOut' must be greyscale images.
    'imIn', 'imTest' and 'imOut' must be different.
    This transformation returns the number of hierarchical levels.    
    """
    
    imWrk1 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn)
    imWrk3 = mamba.imageMb(imIn)
    imWrk4 = mamba.imageMb(imIn, 1)
    imWrk5 = mamba.imageMb(imIn, 1)
    imWrk6 = mamba.imageMb(imIn, 32)    
    mamba.copy(imIn, imWrk1)
    imOut.reset()
    nbLevels = 0
    mamba.threshold(imWrk1, imWrk4, 1, 255)
    flag = not(mamba.checkEmptiness(imWrk4))
    while flag:
        nbLevels += 1
        hierarchy(imWrk1, imWrk4, imWrk2, grid=grid)
        mamba.add(imOut, imWrk4, imOut)
        v = max(nbLevels - offset, 0) + 1
        mamba.threshold(imOut, imWrk4, v, 255)
        mamba.valuedWatershed(imWrk2, imWrk3, grid=grid)
        mamba.threshold(imWrk3, imWrk5, 1, 255)
        flag = not(mamba.checkEmptiness(imWrk5))
        hierarchy(imWrk3, imWrk5, imWrk2, grid=grid)
        mamba.generateSupMask(imTest, imWrk2, imWrk5, strict=False)
        mamba.logic(imWrk4, imWrk5, imWrk4, "inf")
        mamba.convertByMask(imWrk4, imWrk3, 0, 255)
        mamba.logic(imWrk1, imWrk3, imWrk3, "inf")
        mamba.negate(imWrk4, imWrk4)
        mamba.label(imWrk4, imWrk6, grid=grid)
        mamba.watershedSegment(imWrk3, imWrk6, grid=grid)
        mamba.copyBytePlane(imWrk6, 3, imWrk3)
        mamba.logic(imWrk1, imWrk2, imWrk1, "sup")
        mamba.logic(imWrk1, imWrk3, imWrk1, "inf")
        mamba.threshold(imWrk1, imWrk4, 1, 255)
    return nbLevels
Example #15
0
def ceilingAdd(imIn1, imIn2, imOut):
    """
    Adds image 'imIn2' to image 'imIn1' and puts the result in 'imOut'. If
    imIn1 + imIn2 is larger than the maximal possible value in imOut, the result
    is truncated and limited to this maximal value.
    
    Although it is possible to use a 8-bit image for imIn2, it is recommended to
    use the same depth for all the images.
    
    Note that this operator is mainly useful for 32-bit images, as the result
    of the addition is always truncated for 8-bit images.
    """
    
    imMask = mamba.imageMb(imIn1, 1)
    imWrk = mamba.imageMb(imIn1)
    mamba.add(imIn1, imIn2, imWrk)
    mamba.generateSupMask(imIn1, imWrk, imMask, True)
    mamba.convertByMask(imMask, imOut, 0, mamba.computeMaxRange(imOut)[1])
    mamba.logic(imOut, imWrk, imOut, "sup")
Example #16
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 #17
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 #18
0
def enhancedWaterfalls(imIn, imOut, grid=mamba.DEFAULT_GRID):
    """
    Enhanced waterfall algorithm. Compared to the classical waterfalls
    algorithm, this one adds the contours of the watershed transform which are
    above the hierarchical image associated to the next level of hierarchy. This
    waterfalls transform also ends to an empty set. All the hierarchical levels
    of image 'imIn' (which is a valued watershed) are computed. 'imOut' contains
    all these hierarchies which are embedded, so that hierarchy i is simply 
    obtained by a threshold [i+1, 255] of image 'imOut'.
    'imIn' and 'imOut' must be greyscale images. 'imIn' and 'imOu't must be 
    different.
    This transformation returns the number of hierarchical levels.    
    """
    
    imWrk1 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn)
    imWrk3 = mamba.imageMb(imIn)
    imWrk4 = mamba.imageMb(imIn, 1)
    imWrk5 = mamba.imageMb(imIn, 32)   
    mamba.copy(imIn, imWrk1)
    imOut.reset()
    nbLevels = 0
    mamba.threshold(imWrk1, imWrk4, 1, 255)
    flag = not(mamba.checkEmptiness(imWrk4))
    while flag:
        mamba.add(imOut, imWrk4, imOut)
        hierarchy(imWrk1, imWrk4, imWrk2, grid=grid)
        mamba.valuedWatershed(imWrk2, imWrk3, grid=grid)
        mamba.threshold(imWrk3, imWrk4, 1, 255)
        flag = not(mamba.checkEmptiness(imWrk4))
        hierarchy(imWrk3, imWrk4, imWrk2, grid=grid)
        mamba.generateSupMask(imWrk2, imWrk1, imWrk4, strict=True)
        mamba.convertByMask(imWrk4, imWrk3, 255, 0)
        mamba.logic(imWrk1, imWrk3, imWrk3, "inf")
        mamba.label(imWrk4, imWrk5, grid=grid)
        mamba.watershedSegment(imWrk3, imWrk5, grid=grid)
        mamba.copyBytePlane(imWrk5, 3, imWrk1)
        mamba.logic(imWrk1, imWrk3, imWrk1, "inf")
        mamba.threshold(imWrk1, imWrk4, 1, 255)
        nbLevels += 1
    return nbLevels
Example #19
0
def enhancedWaterfalls(imIn, imOut, grid=mamba.DEFAULT_GRID):
    """
    Enhanced waterfall algorithm. Compared to the classical waterfalls
    algorithm, this one adds the contours of the watershed transform which are
    above the hierarchical image associated to the next level of hierarchy. This
    waterfalls transform also ends to an empty set. All the hierarchical levels
    of image 'imIn' (which is a valued watershed) are computed. 'imOut' contains
    all these hierarchies which are embedded, so that hierarchy i is simply 
    obtained by a threshold [i+1, 255] of image 'imOut'.
    'imIn' and 'imOut' must be greyscale images. 'imIn' and 'imOu't must be 
    different.
    This transformation returns the number of hierarchical levels.    
    """

    imWrk1 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn)
    imWrk3 = mamba.imageMb(imIn)
    imWrk4 = mamba.imageMb(imIn, 1)
    imWrk5 = mamba.imageMb(imIn, 32)
    mamba.copy(imIn, imWrk1)
    imOut.reset()
    nbLevels = 0
    mamba.threshold(imWrk1, imWrk4, 1, 255)
    flag = not (mamba.checkEmptiness(imWrk4))
    while flag:
        mamba.add(imOut, imWrk4, imOut)
        hierarchy(imWrk1, imWrk4, imWrk2, grid=grid)
        mamba.valuedWatershed(imWrk2, imWrk3, grid=grid)
        mamba.threshold(imWrk3, imWrk4, 1, 255)
        flag = not (mamba.checkEmptiness(imWrk4))
        hierarchy(imWrk3, imWrk4, imWrk2, grid=grid)
        mamba.generateSupMask(imWrk2, imWrk1, imWrk4, strict=True)
        mamba.convertByMask(imWrk4, imWrk3, 255, 0)
        mamba.logic(imWrk1, imWrk3, imWrk3, "inf")
        mamba.label(imWrk4, imWrk5, grid=grid)
        mamba.watershedSegment(imWrk3, imWrk5, grid=grid)
        mamba.copyBytePlane(imWrk5, 3, imWrk1)
        mamba.logic(imWrk1, imWrk3, imWrk1, "inf")
        mamba.threshold(imWrk1, imWrk4, 1, 255)
        nbLevels += 1
    return nbLevels
Example #20
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 #21
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
def add3D(imIn1, imIn2, imOut):
    """
    Adds 'imIn2' pixel values to 'imIn1' pixel values and puts the result in
    'imOut'. The operation can be sum up in the following formula: 
    
    imOut = imIn1 + imIn2.

    You can mix formats in the addition operation (a binary image can be added
    to a greyscale image, etc...).
    However you must ensure that the output image is as deep as the deepest of 
    the two added images.
    
    The operation is also saturated for greyscale images (e.g. on a 8-bit
    greyscale image, 255+1=255). With 32-bit images, the addition is not saturated.
    """
    outl = len(imOut)
    in1l = len(imIn1)
    in2l = len(imIn2)
    if in1l!=outl or in2l!=outl:
        mamba.raiseExceptionOnError(core.MB_ERR_BAD_SIZE)

    for i in range(outl):
        mamba.add(imIn1[i], imIn2[i], imOut[i])
def add3D(imIn1, imIn2, imOut):
    """
    Adds 'imIn2' pixel values to 'imIn1' pixel values and puts the result in
    'imOut'. The operation can be sum up in the following formula: 
    
    imOut = imIn1 + imIn2.

    You can mix formats in the addition operation (a binary image can be added
    to a greyscale image, etc...).
    However you must ensure that the output image is as deep as the deepest of 
    the two added images.
    
    The operation is also saturated for greyscale images (e.g. on a 8-bit
    greyscale image, 255+1=255). With 32-bit images, the addition is not saturated.
    """
    outl = len(imOut)
    in1l = len(imIn1)
    in2l = len(imIn2)
    if in1l != outl or in2l != outl:
        mamba.raiseExceptionOnError(core.MB_ERR_BAD_SIZE)

    for i in range(outl):
        mamba.add(imIn1[i], imIn2[i], imOut[i])
Example #24
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 #25
0
        def _watershed_using_quasi_distance(self):
            """
            疑似ユークリッド距離(Quasi Distance) に基づく
            Watershed 領域分割
            
            Returns
            -------
            numpy.ndarray
                領域分割線の画像
            """

            from mamba import (
                imageMb,
                gradient,
                add,
                negate,
                quasiDistance,
                copyBytePlane,
                subConst,
                build,
                maxima,
                label,
                watershedSegment,
                logic,
                mix,
            )

            from utils.convert import mamba2np, np2mamba

            # Channel Split
            if self.src_img.ndim == 3:
                b, g, r = [np2mamba(self.src_img[:, :, i]) for i in range(3)]
            elif self.src_img.ndim == 2:
                b, g, r = [np2mamba(self.src_img)] * 3

            # We will perform a thick gradient on each color channel (contours in original
            # picture are more or less fuzzy) and we add all these gradients
            gradient = imageMb(r)
            tmp_1 = imageMb(r)
            gradient.reset()
            gradient(r, tmp_1, 2)
            add(tmp_1, gradient, gradient)
            gradient(g, tmp_1, 2)
            add(tmp_1, gradient, gradient)
            gradient(b, tmp_1, 2)
            add(tmp_1, gradient, gradient)

            # Then we invert the gradient image and we compute its quasi-distance
            quasi_dist = imageMb(gradient, 32)
            negate(gradient, gradient)
            quasiDistance(gradient, tmp_1, quasi_dist)

            if self.is_logging:
                self.logger.logging_img(tmp_1, "quasi_dist_gradient")
                self.logger.logging_img(quasi_dist, "quasi_dist")

            # The maxima of the quasi-distance are extracted and filtered (too close maxima,
            # less than 6 pixels apart, are merged)
            tmp_2 = imageMb(r)
            marker = imageMb(gradient, 1)
            copyBytePlane(quasi_dist, 0, tmp_1)
            subConst(tmp_1, 3, tmp_2)
            build(tmp_1, tmp_2)
            maxima(tmp_2, marker)

            # The marker-controlled watershed of the gradient is performed
            watershed = imageMb(gradient)
            label(marker, quasi_dist)
            negate(gradient, gradient)
            watershedSegment(gradient, quasi_dist)
            copyBytePlane(quasi_dist, 3, watershed)

            # The segmented binary and color image are stored
            logic(r, watershed, r, "sup")
            logic(g, watershed, g, "sup")
            logic(b, watershed, b, "sup")

            segmented_image = mix(r, g, b)

            if self.is_logging:
                self.logger.logging_img(segmented_image, "segmented_image")

            watershed = mamba2np(watershed)

            return watershed