def mosaicGradient3D(imIn, imOut, grid=m3D.DEFAULT_GRID3D): """ Builds the mosaic-gradient 3D 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 = m3D.image3DMb(imIn) imWrk2 = m3D.image3DMb(imIn) imWrk3 = m3D.image3DMb(imIn) imWrk4 = m3D.image3DMb(imIn) imWrk5 = m3D.image3DMb(imIn) mosaic3D(imIn, imWrk2, imWrk3, grid=grid) m3D.sub3D(imWrk2, imWrk3, imWrk1) m3D.logic3D(imWrk2, imWrk3, imWrk2, "sup") m3D.negate3D(imWrk2, imWrk2) se = m3D.structuringElement3D(m3D.getDirections3D(grid), grid) while m3D.computeVolume3D(imWrk3) != 0: m3D.dilate3D(imWrk1, imWrk4, 2, se=se) m3D.dilate3D(imWrk2, imWrk5, 2, se=se) m3D.logic3D(imWrk4, imWrk3, imWrk4, "inf") m3D.logic3D(imWrk5, imWrk3, imWrk5, "inf") m3D.logic3D(imWrk1, imWrk4, imWrk1, "sup") m3D.logic3D(imWrk2, imWrk5, imWrk2, "sup") m3D.erode3D(imWrk3, imWrk3, 2, se=se) m3D.negate3D(imWrk2, imWrk2) m3D.sub3D(imWrk1, imWrk2, imOut)
def lowerGeodesicErode3D(imIn, imMask, imOut, n=1, se=m3D.CUBOCTAHEDRON1): """ Performs a lower geodesic erosion of 3D image 'imIn' under 'imMask'. The result is put inside 'imOut', 'n' controls the size of the erosion. 'se' specifies the type of structuring element used to perform the computation (CUBOCTAHEDRON by default). The binary lower geodesic erosion is realised using the fact that the dilation is the dual operation of the erosion. Warning! 'imMask' and 'imOut' must be different. """ if imIn.getDepth() == 1: m3D.diff3D(imMask, imIn, imOut) lowerGeodesicDilate3D(imOut, imMask, imOut, n, se=se) m3D.diff3D(imMask, imOut, imOut) else: imWrk1 = m3D.image3DMb(imIn) imWrk2 = m3D.image3DMb(imIn, 1) m3D.logic3D(imIn, imMask, imOut, "inf") for i in range(n): m3D.generateSupMask3D(imOut, imMask, imWrk2, False) m3D.convertByMask3D(imWrk2, imWrk1, 0, m3D.computeMaxRange3D(imWrk1)[1]) m3D.logic3D(imOut, imWrk1, imOut, "sup") m3D.erode3D(imOut, imOut, se=se) m3D.logic3D(imOut, imMask, imOut, "inf")
def buildOpen3D(imIn, imOut, n=1, se=m3D.CUBOCTAHEDRON1): """ Performs an opening by reconstruction operation on 3D image 'imIn' and puts the result in 'imOut'. 'n' controls the size of the opening. """ imWrk = m3D.image3DMb(imIn) m3D.copy3D(imIn, imWrk) m3D.erode3D(imIn, imOut, n, se=se) m3D.build3D(imWrk, imOut, grid=se.getGrid())
def linearErode3D( imIn, imOut, d, n=1, grid=m3D.DEFAULT_GRID3D, edge=mamba.FILLED): """ Performs an erosion in direction 'd' of 3D image 'imIn' and puts the result in 'imOut'. The operation is repeated 'n' times (default is 1). This function will assume a FILLED edge unless specified otherwise using 'edge'. """ se = m3D.structuringElement3D([0,d], grid) m3D.copy3D(imIn, imOut) m3D.erode3D(imOut, imOut, n, se=se, edge=edge)
def gradient3D(imIn, imOut, n=1, se=m3D.CUBOCTAHEDRON1): """ Computes the morphological gradient of 3D image 'imIn' and puts the result in 'imOut'. The thickness can be controlled using parameter 'n' (1 by default). The structuring element used by the erosion and dilation is defined by 'se' (CUBOCTAHEDRON1 by default). """ imWrk = m3D.image3DMb(imIn) m3D.erode3D(imIn, imWrk, n, se=se) m3D.dilate3D(imIn, imOut, n, se=se) m3D.sub3D(imOut, imWrk, imOut)
def opening3D(imIn, imOut, n=1, se=m3D.CUBOCTAHEDRON1, edge=mamba.FILLED): """ Performs an opening operation on 3D image 'imIn' and puts the result in 'imOut'. 'n' controls the size of the opening and 'se' the structuring element used. The default edge is set to 'FILLED'. Note that the edge setting operates in the erosion only. """ m3D.erode3D(imIn, imOut, n, se=se, edge=edge) m3D.dilate3D(imOut, imOut, n, se=se.transpose())
def regularisedGradient3D(imIn, imOut, n, grid=m3D.DEFAULT_GRID3D): """ Computes the regularized gradient of 3D image 'imIn' of size 'n'. The result is put in 'imOut'. A regularized gradient of size 'n' extracts in the 3D image contours thinner than 'n' while avoiding false detections. This operation is only valid for omnidirectional structuring elements. """ imWrk = m3D.image3DMb(imIn) se = m3D.structuringElement3D(m3D.getDirections3D(grid), grid) gradient3D(imIn, imWrk, n, se=se) whiteTopHat3D(imWrk, imWrk, n, se=se) m3D.erode3D(imWrk, imOut, n-1, se=se)
def upperGeodesicErode3D(imIn, imMask, imOut, n=1, se=m3D.CUBOCTAHEDRON1): """ Performs a upper geodesic erosion of 3D image 'imIn' above 'imMask'. The result is put inside 'imOut', 'n' controls the size of the erosion. 'se' specifies the type of structuring element used to perform the computation (CUBOCTAHEDRON by default). Warning! 'imMask' and 'imOut' must be different. """ m3D.logic3D(imIn, imMask, imOut, "sup") for i in range(n): m3D.erode3D(imOut, imOut, se=se) m3D.logic3D(imOut, imMask, imOut, "sup")
def closing3D(imIn, imOut, n=1, se=m3D.CUBOCTAHEDRON1, edge=mamba.FILLED): """ Performs a closing operation on 3D image 'imIn' and puts the result in 'imOut'. 'n' controls the size of the closing and 'se' the structuring element used. The default edge is set to 'FILLED'. If 'edge' is set to 'EMPTY', the operation is slightly modified to avoid errors (non extensivity). """ imWrk = m3D.image3DMb(imIn) if edge == mamba.EMPTY: m3D.copy3D(imIn, imWrk) m3D.dilate3D(imIn, imOut, n, se=se) m3D.erode3D(imOut, imOut, n, se=se.transpose(), edge=edge) if edge == mamba.EMPTY: m3D.logic3D(imOut, imWrk, imOut, "sup")
def halfGradient3D(imIn, imOut, type="intern", n=1, se=m3D.CUBOCTAHEDRON1): """ Computes the half morphological gradient of 3D image 'imIn' ond puts the result in 'imOut'. 'type' indicates if the half gradient should be internal or external. Possible values are : "extern" : dilation(imIn) - imIn "intern" : imIn - erosion(imIn) The thickness can be controlled using parameter 'n' (1 by default). The structuring element used by the erosion or the dilation is defined by 'se'. """ imWrk = m3D.image3DMb(imIn) if type=="extern": m3D.dilate3D(imIn, imWrk, n, se=se) m3D.sub3D(imWrk, imIn, imOut) else: m3D.erode3D(imIn, imWrk, n, se=se) m3D.sub3D(imIn, imWrk, imOut)
def strongLevelling3D(imIn, imOut, n, eroFirst, grid=m3D.DEFAULT_GRID3D): """ 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 simpleLevelling3D. However, the order of the initial operations (erosion and dilation) matters. """ imWrk = m3D.image3DMb(imIn) se = m3D.structuringElement3D(m3D.getDirections3D(grid), grid) if eroFirst: m3D.erode3D(imIn, imWrk, n, se=se) m3D.build3D(imIn, imWrk, grid=grid) m3D.dilate3D(imIn, imOut, n, se=se) m3D.dualBuild3D(imWrk, imOut, grid=grid) else: m3D.dilate3D(imIn, imWrk, n, se=se) m3D.dualBuild3D(imIn, imWrk, grid=grid) m3D.erode3D(imIn, imOut, n, se=se) m3D.build3D(imWrk, imOut, grid=grid)