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
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 ceilingAddConst(imIn, v, imOut): """ Adds a constant value 'v' to image 'imIn' and puts the result in 'imOut'. If imIn + v is larger than the maximal possible value in imOut, the result is truncated and limited to this maximal value. 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(imIn, 1) imWrk = mamba.imageMb(imIn) mamba.addConst(imIn, v, imWrk) mamba.generateSupMask(imIn, imWrk, imMask, True) mamba.convertByMask(imMask, imOut, 0, mamba.computeMaxRange(imOut)[1]) mamba.logic(imOut, imWrk, imOut, "sup")
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 addConst3D(imIn, v, imOut): """ Adds 'imIn' pixel values to value 'v' and puts the result in 'imOut'. The operation can be sum up in the following formula: imOut = imIn + v 'imIn' and imOut' can be 8-bit or 32-bit images of same size and depth. The operation is saturated (limited to 255) for greyscale images. """ outl = len(imOut) inl = len(imIn) if inl!=outl: mamba.raiseExceptionOnError(core.MB_ERR_BAD_SIZE) for i in range(outl): mamba.addConst(imIn[i], v, imOut[i])
def addConst3D(imIn, v, imOut): """ Adds 'imIn' pixel values to value 'v' and puts the result in 'imOut'. The operation can be sum up in the following formula: imOut = imIn + v 'imIn' and imOut' can be 8-bit or 32-bit images of same size and depth. The operation is saturated (limited to 255) for greyscale images. """ outl = len(imOut) inl = len(imIn) if inl != outl: mamba.raiseExceptionOnError(core.MB_ERR_BAD_SIZE) for i in range(outl): mamba.addConst(imIn[i], v, imOut[i])
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 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 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)