def binaryUltimateErosion(imIn, imOut1, imOut2, grid=mamba.DEFAULT_GRID, edge=mamba.FILLED): """ Ultimate erosion of binary image 'imIn'. 'imOut1' contains the ultimate eroded set and 'imOut2' contains the associated function (that is the height of each connected component of the ultimate erosion). An ultimate erosion is composed of the union of the last connected components of the successive erosions of the initial set. The associated function provides the size of the corresponding erosion. Depth of 'imOut1' is 1, depth of 'imOut2' is 32. The operation is fast because it is computed using the distance function of 'imIn' (the ultimate erosion is identical to the maxima of this distance function). The edge is set to 'FILLED' by default. """ imWrk1 = mamba.imageMb(imIn, 32) imWrk2 = mamba.imageMb(imIn, 32) mamba.computeDistance(imIn, imWrk1, grid=grid, edge=edge) mamba.maxima(imWrk1, imOut1, grid=grid) mamba.convertByMask(imOut1, imWrk2, 0, mamba.computeMaxRange(imWrk2)[1]) mamba.logic(imWrk1, imWrk2, imOut2, "inf")
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)
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")
def feretDiameterLabelling(imIn, imOut, direc): """ The Feret diameter of each connected component of the binary image or the partition image 'imIn' is computed and its value labels the corresponding component. The labelled image is stored in the 32-bit image 'imOut'. If 'direc' is "vertical", the vertical Feret diameter is computed. If it is set to "horizontal", the corresponding diameter is used. """ imWrk1 = mamba.imageMb(imIn, 1) imWrk2 = mamba.imageMb(imIn, 32) imWrk3 = mamba.imageMb(imIn, 32) imWrk4 = mamba.imageMb(imIn, 32) imWrk1.fill(1) if direc == "horizontal": dir = 7 elif direc == "vertical": dir = 1 else: mamba.raiseExceptionOnError(core.MB_ERR_BAD_DIRECTION) # The above statement generates an error ('direc' is not horizontal or # vertical. # An horizontal or vertical distance function is generated. mamba.linearErode(imWrk1, imWrk1, dir, grid=mamba.SQUARE, edge=mamba.EMPTY) mamba.computeDistance(imWrk1, imOut, grid=mamba.SQUARE, edge=mamba.FILLED) mamba.addConst(imOut, 1, imOut) if imIn.getDepth() == 1: # Each particle is valued with the distance. mamba.convertByMask(imIn, imWrk2, 0, mamba.computeMaxRange(imWrk3)[1]) mamba.logic(imOut, imWrk2, imWrk3, "inf") # The valued image is preserved. mamba.copy(imWrk3, imWrk4) # Each component is labelled by the maximal coordinate. mamba.build(imWrk2, imWrk3) # Using the dual reconstruction, we label the particles with the # minimal ccordinate. mamba.negate(imWrk2, imWrk2) mamba.logic(imWrk2, imWrk4, imWrk4, "sup") mamba.dualBuild(imWrk2, imWrk4) # We subtract 1 because the selected coordinate must be outside the particle. mamba.subConst(imWrk4, 1, imWrk4) mamba.negate(imWrk2, imWrk2) mamba.logic(imWrk2, imWrk4, imWrk4, "inf") # Then, the subtraction gives the Feret diameter. mamba.sub(imWrk3, imWrk4, imOut) else: mamba.copy(imOut, imWrk3) if imIn.getDepth() == 32: mamba.copy(imIn, imWrk2) else: mamba.convert(imIn, imWrk2) # Using the cells builds (direct and dual to label the cells with the maximum # and minimum distance. mamba.cellsBuild(imWrk2, imWrk3) mamba.cellsBuild(imWrk2, imWrk3) mamba.negate(imOut, imOut) mamba.cellsBuild(imWrk2, imOut) mamba.negate(imOut, imOut) # Subtracting 1... mamba.subConst(imOut, 1, imOut) # ... and getting the final result. mamba.sub(imWrk3, imOut, imOut)