예제 #1
0
def hierarchicalLevel(imIn, imOut, grid=mamba.DEFAULT_GRID):
    """
    Computes the next hierarchical level of image 'imIn' in the
    waterfalls transformation and puts the result in 'imOut'.
    This operation makes sure that the next hierarchical level is embedded
    in the previous one.
    'imIn' must be a valued watershed image.
    """

    imWrk0 = mamba.imageMb(imIn)
    imWrk1 = mamba.imageMb(imIn, 1)
    imWrk2 = mamba.imageMb(imIn, 1)
    imWrk3 = mamba.imageMb(imIn, 1)
    imWrk4 = mamba.imageMb(imIn, 32)
    mamba.threshold(imIn, imWrk1, 0, 0)
    mamba.negate(imWrk1, imWrk2)
    hierarchy(imIn, imWrk2, imWrk0, grid=grid)
    mamba.minima(imWrk0, imWrk2, grid=grid)
    mamba.label(imWrk2, imWrk4, grid=grid)
    mamba.watershedSegment(imWrk0, imWrk4, grid=grid)
    mamba.copyBytePlane(imWrk4, 3, imWrk0)
    mamba.threshold(imWrk0, imWrk2, 0, 0)
    mamba.diff(imWrk1, imWrk2, imWrk3)
    mamba.build(imWrk1, imWrk3)
    se = mamba.structuringElement(mamba.getDirections(grid), grid)
    mamba.dilate(imWrk3, imWrk1, 1, se)
    mamba.diff(imWrk2, imWrk1, imWrk1)
    mamba.logic(imWrk1, imWrk3, imWrk1, "sup")
    mamba.convertByMask(imWrk1, imWrk0, 255, 0)
    mamba.logic(imIn, imWrk0, imOut, "inf")
예제 #2
0
def mosaicGradient(imIn, imOut, grid=mamba.DEFAULT_GRID):
    """
    Builds the mosaic-gradient 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 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn)
    imWrk3 = mamba.imageMb(imIn)
    imWrk4 = mamba.imageMb(imIn)
    imWrk5 = mamba.imageMb(imIn)
    imWrk6 = mamba.imageMb(imIn, 1)
    mosaic(imIn, imWrk2, imWrk3, grid=grid)
    mamba.sub(imWrk2, imWrk3, imWrk1)
    mamba.logic(imWrk2, imWrk3, imWrk2, "sup")
    mamba.negate(imWrk2, imWrk2)
    mamba.threshold(imWrk3, imWrk6, 1, 255)
    mamba.multiplePoints(imWrk6, imWrk6, grid=grid)
    mamba.convertByMask(imWrk6, imWrk3, 0, 255)
    se = mamba.structuringElement(mamba.getDirections(grid), grid)
    mamba.dilate(imWrk1, imWrk4, se=se)
    mamba.dilate(imWrk2, imWrk5, se=se)
    while mamba.computeVolume(imWrk3) != 0:
        mamba.dilate(imWrk1, imWrk1, 2, se=se)
        mamba.dilate(imWrk2, imWrk2, 2, se=se)
        mamba.logic(imWrk1, imWrk3, imWrk1, "inf")
        mamba.logic(imWrk2, imWrk3, imWrk2, "inf")
        mamba.logic(imWrk1, imWrk4, imWrk4, "sup")
        mamba.logic(imWrk2, imWrk5, imWrk5, "sup")
        mamba.erode(imWrk3, imWrk3, 2, se=se)
    mamba.negate(imWrk5, imWrk5)
    mamba.sub(imWrk4, imWrk5, imOut)
예제 #3
0
def quasiDistance(imIn, imOut1, imOut2, grid=mamba.DEFAULT_GRID):
    """
    Quasi-distance of image 'imIn'. 'imOut1' contains the residues image
    and 'imOut2' contains the quasi-distance (associated function).
    
    The quasi-distance of a greytone image is made of a patch of distance
    functions of some almost flat regions in the image. When the image is a
    simple indicator function of a set, the quasi-distance and the distance
    function are identical.

    Depth of 'imOut1' is the same as 'imIn', depth of 'imOut2' is 32.
    """

    imWrk1 = mamba.imageMb(imIn, 32)
    imWrk2 = mamba.imageMb(imIn, 32)
    imWrk3 = mamba.imageMb(imIn, 32)
    maskIm = mamba.imageMb(imIn, 1) 
    se = mamba.structuringElement(mamba.getDirections(grid), grid)
    _initialQuasiDist_(imIn, imOut1, imOut2, grid=grid)
    mamba.copy(imOut2, imWrk1)
    v1 = mamba.computeVolume(imOut2)
    v2 = v1 + 1
    while v2 > v1:
        v2 = v1
        mamba.erode(imWrk1, imWrk2, se=se)
        mamba.sub(imWrk1, imWrk2, imWrk2)
        mamba.threshold(imWrk2, maskIm, 2, mamba.computeMaxRange(imWrk2)[1])
        mamba.convertByMask(maskIm, imWrk3, 0, mamba.computeMaxRange(imWrk3)[1])
        mamba.logic(imWrk2, imWrk3, imWrk2, "inf")
        mamba.subConst(imWrk2, 1, imWrk3)
        mamba.logic(imWrk2, imWrk3, imWrk2, "inf") # Patch non saturated subtraction
        mamba.sub(imWrk1, imWrk2, imWrk1)
        v1 = mamba.computeVolume(imWrk1)
    mamba.copy(imWrk1, imOut2)
예제 #4
0
def partitionLabel(imIn, imOut):
    """
    This procedure labels each cell of image 'imIn' and puts the result in
    'imOut'. The number of cells is returned. 'imIn' can be a 1-bit, 8-bit or a
    32-bit image. 'imOut' is a 32-bit image. When 'imIn' is a binary image, all the
    connected components of the background are also labelled. When 'imIn' is a grey
    image, the 0-valued cells are also labelled (which is not the case with the label
    operator.
    Warning! The label values of adjacent cells are not necessarily consecutive.
    """
    
    imWrk1 = mamba.imageMb(imIn, 1)
    imWrk2 = mamba.imageMb(imIn, 32)
    
    if imIn.getDepth() == 1:
        mamba.negate(imIn, imWrk1)
    else:
        mamba.threshold(imIn, imWrk1, 0, 0)
    nb1 = mamba.label(imWrk1, imWrk2)
    mamba.convertByMask(imWrk1, imOut, mamba.computeMaxRange(imOut)[1], 0)
    mamba.logic(imOut, imWrk2, imOut, "sup")
    nb2 = mamba.label(imIn, imWrk2)
    mamba.addConst(imWrk2, nb1, imWrk2)
    mamba.logic(imOut, imWrk2, imOut, "inf")
    return nb1 + nb2
예제 #5
0
def mosaicGradient(imIn, imOut, grid=mamba.DEFAULT_GRID):
    """
    Builds the mosaic-gradient 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 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn)
    imWrk3 = mamba.imageMb(imIn)
    imWrk4 = mamba.imageMb(imIn)
    imWrk5 = mamba.imageMb(imIn)
    imWrk6 = mamba.imageMb(imIn, 1)
    mosaic(imIn, imWrk2, imWrk3, grid=grid)
    mamba.sub(imWrk2, imWrk3, imWrk1)
    mamba.logic(imWrk2, imWrk3, imWrk2, "sup")
    mamba.negate(imWrk2, imWrk2)
    mamba.threshold(imWrk3, imWrk6, 1, 255)
    mamba.multiplePoints(imWrk6, imWrk6, grid=grid)
    mamba.convertByMask(imWrk6, imWrk3, 0, 255)
    se = mamba.structuringElement(mamba.getDirections(grid), grid)
    mamba.dilate(imWrk1, imWrk4, se=se)
    mamba.dilate(imWrk2, imWrk5, se=se)
    while mamba.computeVolume(imWrk3) != 0:
        mamba.dilate(imWrk1, imWrk1, 2, se=se)
        mamba.dilate(imWrk2, imWrk2, 2, se=se)
        mamba.logic(imWrk1, imWrk3, imWrk1, "inf")
        mamba.logic(imWrk2, imWrk3, imWrk2, "inf")
        mamba.logic(imWrk1, imWrk4, imWrk4, "sup")
        mamba.logic(imWrk2, imWrk5, imWrk5, "sup")
        mamba.erode(imWrk3, imWrk3, 2, se=se)
    mamba.negate(imWrk5, imWrk5)
    mamba.sub(imWrk4, imWrk5, imOut)
예제 #6
0
def partitionLabel(imIn, imOut):
    """
    This procedure labels each cell of image 'imIn' and puts the result in
    'imOut'. The number of cells is returned. 'imIn' can be a 1-bit, 8-bit or a
    32-bit image. 'imOut' is a 32-bit image. When 'imIn' is a binary image, all the
    connected components of the background are also labelled. When 'imIn' is a grey
    image, the 0-valued cells are also labelled (which is not the case with the label
    operator.
    Warning! The label values of adjacent cells are not necessarily consecutive.
    """

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

    if imIn.getDepth() == 1:
        mamba.negate(imIn, imWrk1)
    else:
        mamba.threshold(imIn, imWrk1, 0, 0)
    nb1 = mamba.label(imWrk1, imWrk2)
    mamba.convertByMask(imWrk1, imOut, mamba.computeMaxRange(imOut)[1], 0)
    mamba.logic(imOut, imWrk2, imOut, "sup")
    nb2 = mamba.label(imIn, imWrk2)
    mamba.addConst(imWrk2, nb1, imWrk2)
    mamba.logic(imOut, imWrk2, imOut, "inf")
    return nb1 + nb2
예제 #7
0
def mulRealConst(imIn, v, imOut, nearest=False, precision=2):
    """
    Multiplies image 'imIn' by a real positive constant value 'v' and puts the 
    result in image 'imOut'. 'imIn' and 'imOut' can be 8-bit or 32-bit images.
    If 'imOut' is greyscale (8-bit), the result is saturated (results
    of the multiplication greater than 255 are limited to this value).
    'precision' indicates the number of decimal digits taken into account for
    the constant 'v' (default is 2).
    If 'nearest' is true, the result is rounded to the nearest integer value.
    If not (default), the result is simply truncated.
    """
    
    if imIn.getDepth()==1 or imOut.getDepth()==1:
        mamba.raiseExceptionOnError(core.MB_ERR_BAD_DEPTH)
    imWrk1 = mamba.imageMb(imIn, 32)
    imWrk2 = mamba.imageMb(imIn, 1)
    precVal = (10 ** precision)
    v1 = int(v * precVal)
    if imIn.getDepth()==8:
        imWrk1.reset()
        mamba.copyBytePlane(imIn, 0, imWrk1)
    else:
        mamba.copy(imIn, imWrk1)
    mulConst(imWrk1, v1, imWrk1)
    if nearest:
        adjVal = int(5 * (10 ** (precision - 1)))
        addConst(imWrk1, adjVal , imWrk1)
    divConst(imWrk1, precVal, imWrk1)
    if imOut.getDepth()==8:
        mamba.threshold(imWrk1, imWrk2, 255, mamba.computeMaxRange(imWrk1)[1])
        mamba.copyBytePlane(imWrk1, 0, imOut)
        imWrk2.convert(8)
        mamba.logic(imOut, imWrk2, imOut, "sup")
    else:
        mamba.copy(imWrk1, imOut)
예제 #8
0
def hierarchicalLevel(imIn, imOut, grid=mamba.DEFAULT_GRID):
    """
    Computes the next hierarchical level of image 'imIn' in the
    waterfalls transformation and puts the result in 'imOut'.
    This operation makes sure that the next hierarchical level is embedded
    in the previous one.
    'imIn' must be a valued watershed image.
    """
    
    imWrk0 = mamba.imageMb(imIn)
    imWrk1 = mamba.imageMb(imIn, 1)
    imWrk2 = mamba.imageMb(imIn, 1)
    imWrk3 = mamba.imageMb(imIn, 1)
    imWrk4 = mamba.imageMb(imIn, 32)
    mamba.threshold(imIn,imWrk1, 0, 0)
    mamba.negate(imWrk1, imWrk2)
    hierarchy(imIn, imWrk2, imWrk0, grid=grid)
    mamba.minima(imWrk0, imWrk2, grid=grid)
    mamba.label(imWrk2, imWrk4, grid=grid)
    mamba.watershedSegment(imWrk0, imWrk4, grid=grid)
    mamba.copyBytePlane(imWrk4, 3, imWrk0)
    mamba.threshold(imWrk0, imWrk2, 0, 0)
    mamba.diff(imWrk1, imWrk2, imWrk3)
    mamba.build(imWrk1, imWrk3)
    se = mamba.structuringElement(mamba.getDirections(grid), grid)
    mamba.dilate(imWrk3, imWrk1, 1, se)
    mamba.diff(imWrk2, imWrk1, imWrk1)
    mamba.logic(imWrk1, imWrk3, imWrk1, "sup")
    mamba.convertByMask(imWrk1, imWrk0, 255, 0)
    mamba.logic(imIn, imWrk0, imOut, "inf")
예제 #9
0
def measureLabelling(imIn, imMeasure, imOut):
    """
    Labelling each particle of the binary image or each cell of the partition 'imIn'
    with the number of pixels in the binary image 'imMeasure' contained in each particle
    or each cell of the partition. The result is put is the 32-bit image 'imOut'.
    """
    
    imWrk1 = mamba.imageMb(imIn, 32)
    imWrk2 = mamba.imageMb(imIn, 1)
    imWrk3 = mamba.imageMb(imIn, 8)
    imWrk4 = mamba.imageMb(imIn, 8)
    imWrk5 = mamba.imageMb(imIn, 8)
    imWrk6 = mamba.imageMb(imIn, 32)
    
    # Output image is emptied.
    imOut.reset()
    # Labelling the initial image.
    if imIn.getDepth() == 1:
        nbParticles = mamba.label(imIn, imWrk1)
    else:
        nbParticles = partitionLabel(imIn, imWrk1)
    # Defining output LUTs.
    outLuts = [[0 for i in range(256)] for i in range(4)]
    # Converting the imMeasure image to 8-bit.
    mamba.convert(imMeasure, imWrk4)
    while nbParticles > 0:
        # Particles with labels between 1 and 255 are extracted.
        mamba.threshold(imWrk1, imWrk2, 0, 255)
        mamba.convert(imWrk2, imWrk3)
        mamba.copyBytePlane(imWrk1, 0, imWrk5)
        mamba.logic(imWrk3, imWrk5, imWrk3, "inf")
        # The points contained in each particle are labelled.
        mamba.logic(imWrk3, imWrk4, imWrk5, "inf")
        # The histogram is computed.
        histo = mamba.getHistogram(imWrk5)
        # The same operation is performed for the 255 particles. 
        for i in range(1, 256):
            # The number of points in each particle is obtained from the histogram.
            value = histo[i]
            j = 3
            # This value is splitted in powers of 256 and stored in the four 
            # output LUTs.
            while j >= 0:
                n = 2 ** (8 * j)
                outLuts[j][i] = value // n
                value = value % n
                j -= 1
        # Each LUT is used to label each byte plane of a temporary image with the
        # corresponding value.
        for i in range(4):
            mamba.lookup(imWrk3, imWrk5, outLuts[i])
            mamba.copyBytePlane(imWrk5, i, imWrk6)
        # The intermediary result is accumulated in the final image.
        mamba.logic(imOut, imWrk6, imOut, "sup")
        # 255 is subtracted from the initial labelled image in order to process
        # the next 255 particles.
        mamba.floorSubConst(imWrk1, 255, imWrk1)
        nbParticles -= 255
예제 #10
0
def measureLabelling(imIn, imMeasure, imOut):
    """
    Labelling each particle of the binary image or each cell of the partition 'imIn'
    with the number of pixels in the binary image 'imMeasure' contained in each particle
    or each cell of the partition. The result is put is the 32-bit image 'imOut'.
    """

    imWrk1 = mamba.imageMb(imIn, 32)
    imWrk2 = mamba.imageMb(imIn, 1)
    imWrk3 = mamba.imageMb(imIn, 8)
    imWrk4 = mamba.imageMb(imIn, 8)
    imWrk5 = mamba.imageMb(imIn, 8)
    imWrk6 = mamba.imageMb(imIn, 32)

    # Output image is emptied.
    imOut.reset()
    # Labelling the initial image.
    if imIn.getDepth() == 1:
        nbParticles = mamba.label(imIn, imWrk1)
    else:
        nbParticles = partitionLabel(imIn, imWrk1)
    # Defining output LUTs.
    outLuts = [[0 for i in range(256)] for i in range(4)]
    # Converting the imMeasure image to 8-bit.
    mamba.convert(imMeasure, imWrk4)
    while nbParticles > 0:
        # Particles with labels between 1 and 255 are extracted.
        mamba.threshold(imWrk1, imWrk2, 0, 255)
        mamba.convert(imWrk2, imWrk3)
        mamba.copyBytePlane(imWrk1, 0, imWrk5)
        mamba.logic(imWrk3, imWrk5, imWrk3, "inf")
        # The points contained in each particle are labelled.
        mamba.logic(imWrk3, imWrk4, imWrk5, "inf")
        # The histogram is computed.
        histo = mamba.getHistogram(imWrk5)
        # The same operation is performed for the 255 particles.
        for i in range(1, 256):
            # The number of points in each particle is obtained from the histogram.
            value = histo[i]
            j = 3
            # This value is splitted in powers of 256 and stored in the four
            # output LUTs.
            while j >= 0:
                n = 2**(8 * j)
                outLuts[j][i] = value // n
                value = value % n
                j -= 1
        # Each LUT is used to label each byte plane of a temporary image with the
        # corresponding value.
        for i in range(4):
            mamba.lookup(imWrk3, imWrk5, outLuts[i])
            mamba.copyBytePlane(imWrk5, i, imWrk6)
        # The intermediary result is accumulated in the final image.
        mamba.logic(imOut, imWrk6, imOut, "sup")
        # 255 is subtracted from the initial labelled image in order to process
        # the next 255 particles.
        mamba.floorSubConst(imWrk1, 255, imWrk1)
        nbParticles -= 255
예제 #11
0
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
예제 #12
0
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
예제 #13
0
def fastSKIZ(imIn, imOut, grid=mamba.DEFAULT_GRID):
    """
    Fast skeleton by zones of influence of binary image 'imIn'. Result is put in
    binary image 'imOut'. The transformation is faster as it uses the watershed
    transform by hierarchical queues.
    """

    imWrk = mamba.imageMb(imIn, 8)
    mamba.convertByMask(imIn, imWrk, 1, 0)
    markerControlledWatershed(imWrk, imIn, imWrk, grid=grid)
    mamba.threshold(imWrk, imOut, 0, 0)
예제 #14
0
def fastSKIZ(imIn, imOut, grid=mamba.DEFAULT_GRID):
    """
    Fast skeleton by zones of influence of binary image 'imIn'. Result is put in
    binary image 'imOut'. The transformation is faster as it uses the watershed
    transform by hierarchical queues.
    """

    imWrk = mamba.imageMb(imIn, 8)
    mamba.convertByMask(imIn, imWrk, 1, 0)
    markerControlledWatershed(imWrk, imIn, imWrk, grid=grid)
    mamba.threshold(imWrk, imOut, 0, 0)
예제 #15
0
def _generateMask_(imIn1, imIn2, imOut):
    #This procedure is used internally by the residues operators. It computes
    #a mask indicating the points in the image where 'imIn1' is greater or equal
    #to 'imIn2' with 'imIn1' strictly positive.
    #Depth of 'imOut' is 1.
    
    imWrk = mamba.imageMb(imOut)
    mamba.generateSupMask(imIn1, imIn2, imOut, False)
    if imIn1.getDepth()==1:
        mamba.negate(imIn1, imWrk)
    else:
        mamba.threshold(imIn1, imWrk, 0, 0)
    mamba.diff(imOut, imWrk, imOut)
예제 #16
0
def geodesicSKIZ(imIn, imMask, imOut, grid=mamba.DEFAULT_GRID):
    """
    Geodesic skeleton by zones of influence of binary image 'imIn' inside the
    geodesic mask 'imMask'. The result is in binary image 'imOut'.
    """

    imWrk1 = mamba.imageMb(imIn, 8)
    imWrk2 = mamba.imageMb(imIn)
    mamba.copy(imIn, imWrk2)
    mamba.build(imMask, imWrk2, grid=grid)
    mamba.convertByMask(imWrk2, imWrk1, 2, 1)
    mamba.sub(imWrk1, imIn, imWrk1)
    markerControlledWatershed(imWrk1, imIn, imWrk1, grid=grid)
    mamba.threshold(imWrk1, imOut, 0, 0)
    mamba.logic(imOut, imWrk2, imOut, "inf")
예제 #17
0
def geodesicSKIZ(imIn, imMask, imOut, grid=mamba.DEFAULT_GRID):
    """
    Geodesic skeleton by zones of influence of binary image 'imIn' inside the
    geodesic mask 'imMask'. The result is in binary image 'imOut'.
    """

    imWrk1 = mamba.imageMb(imIn, 8)
    imWrk2 = mamba.imageMb(imIn)
    mamba.copy(imIn, imWrk2)
    mamba.build(imMask, imWrk2, grid=grid)
    mamba.convertByMask(imWrk2, imWrk1, 2, 1)
    mamba.sub(imWrk1, imIn, imWrk1)
    markerControlledWatershed(imWrk1, imIn, imWrk1, grid=grid)
    mamba.threshold(imWrk1, imOut, 0, 0)
    mamba.logic(imOut, imWrk2, imOut, "inf")
예제 #18
0
def cellsComputeDistance(imIn, imOut, grid=mamba.DEFAULT_GRID, edge=mamba.EMPTY):
    """
    Computation of the distance function for each cell of the partition
    image 'imIn'.
    The result is put in the 32-bit image 'imOut'.
    This operator works on hexagonal or square 'grid' and
    'edge' is set to EMPTY by default.
    """
    
    imWrk1 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn, 1)
    se = mamba.structuringElement(mamba.getDirections(grid), grid)
    cellsErode(imIn, imWrk1, 1, se=se, edge=edge)
    mamba.threshold(imWrk1, imWrk2, 1, 255)
    mamba.computeDistance(imWrk2, imOut, grid=grid, edge=edge)
    mamba.addConst(imOut, 1, imOut)
예제 #19
0
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
예제 #20
0
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
예제 #21
0
def cellsComputeDistance(imIn,
                         imOut,
                         grid=mamba.DEFAULT_GRID,
                         edge=mamba.EMPTY):
    """
    Computation of the distance function for each cell of the partition
    image 'imIn'.
    The result is put in the 32-bit image 'imOut'.
    This operator works on hexagonal or square 'grid' and
    'edge' is set to EMPTY by default.
    """

    imWrk1 = mamba.imageMb(imIn)
    imWrk2 = mamba.imageMb(imIn, 1)
    se = mamba.structuringElement(mamba.getDirections(grid), grid)
    cellsErode(imIn, imWrk1, 1, se=se, edge=edge)
    mamba.threshold(imWrk1, imWrk2, 1, 255)
    mamba.computeDistance(imWrk2, imOut, grid=grid, edge=edge)
    mamba.addConst(imOut, 1, imOut)
예제 #22
0
def maxDynamics(imIn, imOut, h, grid=mamba.DEFAULT_GRID):
    """
    Extracts the maxima of 'imIn' with a dynamics higher or equal to 'h'
    and puts the result in 'imOut'.
    
    Grid used by the dual build operation can be specified by 'grid'.
    
    Only works with 8-bit or 32-bit images as input. 'imOut' must be binary.
    """
    
    imWrk = mamba.imageMb(imIn)
    if imIn.getDepth() == 8:
        mamba.subConst(imIn, h, imWrk)
        mamba.hierarBuild(imIn, imWrk, grid=grid)
        mamba.sub(imIn, imWrk, imWrk)
    else:
        mamba.floorSubConst(imIn, h, imWrk)
        mamba.build(imIn, imWrk, grid=grid)
        mamba.floorSub(imIn, imWrk, imWrk)
    mamba.threshold(imWrk, imOut, h, mamba.computeMaxRange(imIn)[1])
예제 #23
0
def threshold3D(imIn, imOut, low, high):
    """
    Performs a threshold operation over image 'imIn'.
    The result is put in binary image 'imOut'.
    
    All the pixels that have a strictly lower value than 'low' or 
    strictly higher than 'high' are set to false.
    Otherwise they are set to true.
    
    'imIn' can be a 8-bit or 32-bit image.
    
    This function works with 3D images.
    """
    outl = len(imOut)
    inl = len(imIn)
    if inl != outl:
        mamba.raiseExceptionOnError(core.MB_ERR_BAD_SIZE)

    for i in range(outl):
        mamba.threshold(imIn[i], imOut[i], low, high)
예제 #24
0
def threshold3D(imIn, imOut, low, high):
    """
    Performs a threshold operation over image 'imIn'.
    The result is put in binary image 'imOut'.
    
    All the pixels that have a strictly lower value than 'low' or 
    strictly higher than 'high' are set to false.
    Otherwise they are set to true.
    
    'imIn' can be a 8-bit or 32-bit image.
    
    This function works with 3D images.
    """
    outl = len(imOut)
    inl = len(imIn)
    if inl!=outl:
        mamba.raiseExceptionOnError(core.MB_ERR_BAD_SIZE)
    
    for i in range(outl):
        mamba.threshold(imIn[i], imOut[i], low, high)
예제 #25
0
def maxima(imIn, imOut, h=1, grid=mamba.DEFAULT_GRID):
    """
    Computes the maxima of 'imIn' using a build operation and puts the result in
    'imOut'. When 'h' is equal to 1 (default value), the operator provides the
    maxima of 'imIn'.
    
    Grid used by the build operation can be specified by 'grid'.
    
    Only works with with 8-bit or 32-bit images as input. 'imOut' must be binary.
    """
    
    imWrk = mamba.imageMb(imIn)
    if imIn.getDepth() == 8:
        mamba.subConst(imIn, h, imWrk)
        mamba.hierarBuild(imIn, imWrk, grid=grid)
        mamba.sub(imIn, imWrk, imWrk)
    else:
        mamba.floorSubConst(imIn, h, imWrk)
        mamba.build(imIn, imWrk, grid=grid)
        mamba.floorSub(imIn, imWrk, imWrk)
    mamba.threshold(imWrk, imOut, 1, mamba.computeMaxRange(imIn)[1])
예제 #26
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)
예제 #27
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)
예제 #28
0
def binarySkeletonByOpening(imIn, imOut1, imOut2, grid=mamba.DEFAULT_GRID, edge=mamba.FILLED):
    """
    Skeleton by openings (maximal balls skeleton) of binary image 'imIn'.
    'imOut1' contains the skeleton points (centers of maximal balls) and
    'imOut2' contains the associated function (that is the radius of each
    maximal ball included in the initial set.

    The operation is fast because it is computed through the use of the
    distance function of 'imIn' (skeleton points can be obtained by a
    Top Hat transform on the distance function).

    The edge is set to 'FILLED' by default.
    """

    imWrk1 = mamba.imageMb(imIn, 32)
    imWrk2 = mamba.imageMb(imIn, 32)
    se = mamba.structuringElement(mamba.getDirections(grid), grid)
    mamba.computeDistance(imIn, imWrk1, grid=grid, edge=edge)
    mamba.whiteTopHat(imWrk1, imWrk2, 1, se=se)
    mamba.threshold(imWrk2, imOut1, 1, mamba.computeMaxRange(imWrk2)[1])
    mamba.convertByMask(imOut1, imWrk2, 0, mamba.computeMaxRange(imWrk2)[1])
    mamba.logic(imWrk1, imWrk2, imOut2, "inf")
예제 #29
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
예제 #30
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
예제 #31
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
예제 #32
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
예제 #33
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
예제 #34
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
예제 #35
0
    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")


# Trying these operators on a fibers image.
# Loading the initial image.
im1 = mamba.imageMb('ferrite.png')
# Defining some working images.
im2 = mamba.imageMb(im1)
imbin1 = mamba.imageMb(im1, 1)
# Performing a directional opening of size 30 in direction 6.
# This should select fibers with a length greater than 60 in
# direction 165 degrees approximately (a square grid is used).
directionalOpen(im1, im2, 6, 30, grid=mamba.SQUARE)
# The markers (obtained by a simple threshold) of the corresponding
# fibers are superposed to the original image (some filtering is
# performed by removing fibers cutting the edges).
mamba.threshold(im2, imbin1, 100, 255)
mamba.removeEdgeParticles(imbin1, imbin1)
# The same operation is performed once again on the thresholded
# image to verify the markers sizes.
directionalOpen(imbin1, imbin1, 6, 30, grid=mamba.SQUARE)
# displaying the result.
mE.superpose(im1, imbin1)
예제 #36
0
    
    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")

# Trying these operators on a fibers image.
# Loading the initial image.
im1 = mamba.imageMb('ferrite.png')
# Defining some working images.
im2 = mamba.imageMb(im1)
imbin1 = mamba.imageMb(im1, 1)
# Performing a directional opening of size 30 in direction 6.
# This should select fibers with a length greater than 60 in
# direction 165 degrees approximately (a square grid is used).
directionalOpen(im1, im2, 6, 30, grid=mamba.SQUARE)
# The markers (obtained by a simple threshold) of the corresponding
# fibers are superposed to the original image (some filtering is
# performed by removing fibers cutting the edges).
mamba.threshold(im2, imbin1, 100, 255)
mamba.removeEdgeParticles(imbin1, imbin1)
# The same operation is performed once again on the thresholded
# image to verify the markers sizes.
directionalOpen(imbin1, imbin1, 6, 30, grid=mamba.SQUARE)
# displaying the result.
mE.superpose(im1, imbin1)