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
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
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
def floorSubConst3D(imIn, v, imOut): """ Subtracts a constant value 'v' to image 'imIn' and puts the result in 'imOut'. If imIn - v is negative, the result is truncated and limited to 0. Note that this operator is mainly useful for 32-bit images, as the result of the subtraction is always truncated for 8-bit images. """ outl = len(imOut) inl = len(imIn) if inl!=outl: mamba.raiseExceptionOnError(core.MB_ERR_BAD_SIZE) for i in range(outl): mamba.floorSubConst(imIn[i], v, imOut[i])
def floorSubConst3D(imIn, v, imOut): """ Subtracts a constant value 'v' to image 'imIn' and puts the result in 'imOut'. If imIn - v is negative, the result is truncated and limited to 0. Note that this operator is mainly useful for 32-bit images, as the result of the subtraction is always truncated for 8-bit images. """ outl = len(imOut) inl = len(imIn) if inl != outl: mamba.raiseExceptionOnError(core.MB_ERR_BAD_SIZE) for i in range(outl): mamba.floorSubConst(imIn[i], v, imOut[i])
def highMaxima(imIn, imOut, h, grid=mamba.DEFAULT_GRID): """ Computes the maxima of the reconstruction of image 'imIn' by imIn - h and puts the result in 'imOut'. Grid used by the 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) else: mamba.floorSubConst(imIn, h, imWrk) mamba.build(imIn, imWrk, grid=grid) maxima(imWrk, imOut, 1, grid=grid)
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])
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])