def buildClose(imIn, imOut, n=1, se=mamba.DEFAULT_SE): """ Performs a closing by dual reconstruction operation on image 'imIn' and puts the result in 'imOut'. 'n' controls the size of the closing. """ imWrk = mamba.imageMb(imIn) mamba.copy(imIn, imWrk) mamba.dilate(imIn, imOut, n, se=se) mamba.dualBuild(imWrk, imOut, grid=se.getGrid())
def minPartialBuild(imIn, imMask, imOut, grid=mamba.DEFAULT_GRID): """ Performs the partial reconstruction of 'imIn' with its minima which are contained in the binary mask 'imMask'. The result is put in 'imOut'. 'imIn' and 'imOut' must be different and greyscale images. """ imWrk = mamba.imageMb(imIn, 1) minima(imIn, imWrk, 1, grid=grid) mamba.logic(imMask, imWrk, imWrk, "inf") mamba.convertByMask(imWrk, imOut, mamba.computeMaxRange(imIn)[1], 0) mamba.logic(imIn, imOut, imOut, "sup") mamba.dualBuild(imIn, imOut)
def deepMinima(imIn, imOut, h, grid=mamba.DEFAULT_GRID): """ Computes the minima of the dual reconstruction of image 'imIn' by imIn + 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.addConst(imIn, h, imWrk) mamba.hierarDualBuild(imIn, imWrk, grid=grid) else: mamba.ceilingAddConst(imIn, h, imWrk) mamba.dualBuild(imIn, imWrk, grid=grid) minima(imWrk, imOut, 1, grid=grid)
def minDynamics(imIn, imOut, h, grid=mamba.DEFAULT_GRID): """ Extracts the minima 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.addConst(imIn, h, imWrk) mamba.hierarDualBuild(imIn, imWrk, grid=grid) mamba.sub(imWrk, imIn, imWrk) else: mamba.ceilingAddConst(imIn, h, imWrk) mamba.dualBuild(imIn, imWrk, grid=grid) mamba.floorSub(imWrk, imIn, imWrk) mamba.threshold(imWrk, imOut, h, mamba.computeMaxRange(imIn)[1])
def simpleLevelling(imIn, imMask, imOut, grid=mamba.DEFAULT_GRID): """ Performs a simple levelling of image 'imIn' controlled by image 'imMask' and puts the result in 'imOut'. This operation is composed of two geodesic reconstructions. This filter tends to level regions in the image of homogeneous grey values. """ imWrk1 = mamba.imageMb(imIn) imWrk2 = mamba.imageMb(imIn) mask_im = mamba.imageMb(imIn, 1) mamba.logic(imIn, imMask, imWrk1, "inf") mamba.build(imIn, imWrk1, grid=grid) mamba.logic(imIn, imMask, imWrk2, "sup") mamba.dualBuild(imIn, imWrk2, grid=grid) mamba.generateSupMask(imIn, imMask, mask_im, False) mamba.convertByMask(mask_im, imOut, 0, mamba.computeMaxRange(imIn)[1]) mamba.logic(imOut, imWrk1, imWrk1, "inf") mamba.negate(imOut, imOut) mamba.logic(imOut, imWrk2, imOut, "inf") mamba.logic(imWrk1, imOut, imOut, "sup")
def minima(imIn, imOut, h=1, grid=mamba.DEFAULT_GRID): """ Computes the minima of 'imIn' using a dual build operation and puts the result in 'imOut'. When 'h' is equal to 1 (default value), the operator provides the minima of 'imIn'. 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.addConst(imIn, h, imWrk) mamba.hierarDualBuild(imIn, imWrk, grid=grid) mamba.sub(imWrk, imIn, imWrk) else: mamba.ceilingAddConst(imIn, h, imWrk) mamba.dualBuild(imIn, imWrk, grid=grid) mamba.floorSub(imWrk, imIn, imWrk) mamba.threshold(imWrk, imOut, 1, mamba.computeMaxRange(imIn)[1])
def strongLevelling(imIn, imOut, n, eroFirst, grid=mamba.DEFAULT_GRID): """ Strong levelling of 'imIn', result in 'imOut'. 'n' defines the size of the erosion and dilation of 'imIn' in the operation. If 'eroFirst' is true, the operation starts with an erosion, it starts with a dilation otherwise. This filter is stronger (more efficient) that simpleLevelling. However, the order of the initial operations (erosion and dilation) matters. """ imWrk = mamba.imageMb(imIn) se = mamba.structuringElement(mamba.getDirections(grid), grid) if eroFirst: mamba.erode(imIn, imWrk, n, se=se) mamba.build(imIn, imWrk, grid=grid) mamba.dilate(imIn, imOut, n, se=se) mamba.dualBuild(imWrk, imOut, grid=grid) else: mamba.dilate(imIn, imWrk, n, se=se) mamba.dualBuild(imIn, imWrk, grid=grid) mamba.erode(imIn, imOut, n, se=se) mamba.build(imWrk, imOut, grid=grid)
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)