def conjugateDirectionalErode(imIn, imOut, d, size, grid=mamba.DEFAULT_GRID, edge=mamba.FILLED): """ Performs the erosion of image 'imIn' in the conjugate direction 'd' of the grid and puts the result in image 'imOut'. The images can be binary, greyscale or 32-bit images. 'size' is a multiple of the distance between two adjacent points in the conjugate directions. 'edge' is set to FILLED by default (can be changed). Note that this operator is not equivalent to successive erosions by a doublet of points. """ imWrk1 = mamba.imageMb(imIn) imWrk2 = mamba.imageMb(imIn) mamba.copy(imIn, imOut) j3 = mamba.transposeDirection(d, grid=grid) j2 = mamba.rotateDirection(d, grid=grid) j1 = mamba.transposeDirection(j2, grid=grid) val = mamba.computeMaxRange(imIn)[1] * int(edge == mamba.FILLED) for i in range(size): mamba.copy(imOut, imWrk1) mamba.copy(imOut, imWrk2) mamba.linearErode(imWrk1, imWrk1, d, n=1, grid=grid, edge=edge) mamba.shift(imWrk1, imWrk1, j1, 1, val, grid=grid) mamba.logic(imWrk1, imOut, imWrk1, "inf") mamba.linearErode(imWrk2, imWrk2, j2, n=1, grid=grid, edge=edge) mamba.shift(imWrk2, imWrk2, j3, 1, val, grid=grid) mamba.logic(imWrk2, imOut, imWrk2, "inf") mamba.logic(imWrk1, imWrk2, imOut, "sup")
def conjugateDirectionalDilate(imIn, imOut, d, size, grid=mamba.DEFAULT_GRID, edge=mamba.EMPTY): """ Performs the dilation of image 'imIn' in the conjugate direction 'd' of the grid and puts the result in image 'imOut'. The images can be binary, greyscale or 32-bit images. 'size' is a multiple of the distance between two adjacent points in the conjugate directions. 'edge' is set to EMPTY by default (can be changed). Note that the linear structuring element is not connected. Points connecting adjacent points in the conjugate directions are not present. This is normal if we want to insure that the result is identical when we iterate n size 1 operations to get a size n one (the same remark applies to the erosion). """ imWrk1 = mamba.imageMb(imIn) imWrk2 = mamba.imageMb(imIn) mamba.copy(imIn, imOut) j3 = mamba.transposeDirection(d, grid=grid) j2 = mamba.rotateDirection(d, grid=grid) j1 = mamba.transposeDirection(j2, grid=grid) val = mamba.computeMaxRange(imIn)[1] * int(edge == mamba.FILLED) for i in range(size): mamba.copy(imOut, imWrk1) mamba.copy(imOut, imWrk2) mamba.linearDilate(imWrk1, imWrk1, d, 1, grid=grid, edge=edge) mamba.shift(imWrk1, imWrk1, j1, 1, val, grid=grid) mamba.logic(imWrk1, imOut, imWrk1, "sup") mamba.linearDilate(imWrk2, imWrk2, j2, 1, grid=grid, edge=edge) mamba.shift(imWrk2, imWrk2, j3, 1, val, grid=grid) mamba.logic(imWrk2, imOut, imWrk2, "sup") mamba.logic(imWrk1, imWrk2, imOut, "inf")
def _sparseConjugateHexagonDilate(imIn, imOut, size, edge=mamba.EMPTY): """ Dilation by a conjugate hexagon. The structuring element used by this operation is not complete. Some holes appear inside the structuring element. Therefore, this operation should not be used to obtain true conjugate hexagons dilations (for internal use only). """ imWrk1 = mamba.imageMb(imIn) imWrk2 = mamba.imageMb(imIn) mamba.copy(imIn, imOut) val = mamba.computeMaxRange(imIn)[1]*int(edge!=mamba.EMPTY) for i in _sizeSplit(size): mamba.copy(imOut, imWrk1) j = 2*i supFarNeighbor(imWrk1, imOut, 1, j, grid=mamba.SQUARE, edge=edge) mamba.shift(imWrk1, imWrk2, 2, i, val, grid=mamba.HEXAGONAL) supFarNeighbor(imWrk2, imOut, 4, i, grid=mamba.HEXAGONAL, edge=edge) supFarNeighbor(imWrk2, imOut, 6, i, grid=mamba.HEXAGONAL, edge=edge) supFarNeighbor(imWrk1, imOut, 5, j, grid=mamba.SQUARE, edge=edge) mamba.shift(imWrk1, imWrk2, 5, i, val, grid=mamba.HEXAGONAL) supFarNeighbor(imWrk2, imOut, 1, i, grid=mamba.HEXAGONAL, edge=edge) supFarNeighbor(imWrk2, imOut, 3, i, grid=mamba.HEXAGONAL, edge=edge) j = 3*i//2 supFarNeighbor(imWrk1, imOut, 2, j, grid=mamba.HEXAGONAL, edge=edge) supFarNeighbor(imWrk1, imOut, 5, j, grid=mamba.HEXAGONAL, edge=edge)
def _sparseConjugateHexagonDilate(imIn, imOut, size, edge=mamba.EMPTY): """ Dilation by a conjugate hexagon. The structuring element used by this operation is not complete. Some holes appear inside the structuring element. Therefore, this operation should not be used to obtain true conjugate hexagons dilations (for internal use only). """ imWrk1 = mamba.imageMb(imIn) imWrk2 = mamba.imageMb(imIn) mamba.copy(imIn, imOut) val = mamba.computeMaxRange(imIn)[1] * int(edge != mamba.EMPTY) for i in _sizeSplit(size): mamba.copy(imOut, imWrk1) j = 2 * i supFarNeighbor(imWrk1, imOut, 1, j, grid=mamba.SQUARE, edge=edge) mamba.shift(imWrk1, imWrk2, 2, i, val, grid=mamba.HEXAGONAL) supFarNeighbor(imWrk2, imOut, 4, i, grid=mamba.HEXAGONAL, edge=edge) supFarNeighbor(imWrk2, imOut, 6, i, grid=mamba.HEXAGONAL, edge=edge) supFarNeighbor(imWrk1, imOut, 5, j, grid=mamba.SQUARE, edge=edge) mamba.shift(imWrk1, imWrk2, 5, i, val, grid=mamba.HEXAGONAL) supFarNeighbor(imWrk2, imOut, 1, i, grid=mamba.HEXAGONAL, edge=edge) supFarNeighbor(imWrk2, imOut, 3, i, grid=mamba.HEXAGONAL, edge=edge) j = 3 * i // 2 supFarNeighbor(imWrk1, imOut, 2, j, grid=mamba.HEXAGONAL, edge=edge) supFarNeighbor(imWrk1, imOut, 5, j, grid=mamba.HEXAGONAL, edge=edge)
def shift3D(imIn, imOut, d, amp, fill, grid=m3D.DEFAULT_GRID3D): """ Shifts 3D image 'imIn' in direction 'd' of the 'grid' over an amplitude of 'amp'. The emptied space is filled with 'fill' value. This implementation is fast as a minimal number of shifts is used. The result is put in 'imOut'. """ (width,height,length) = imIn.getSize() if length!=len(imOut): mamba.raiseExceptionOnError(core.MB_ERR_BAD_SIZE) # Computing limits according to the scanning direction. scan = grid.convertFromDir(d,0)[0] if scan == 0: startPlane, endPlane, scanDir = 0, length, 1 startFill, endFill = 0, 0 elif scan == -1: startPlane, endPlane, scanDir = amp, length, 1 startFill, endFill = max(length - amp, 0), length else: startPlane, endPlane, scanDir = length - amp - 1, -1, -1 startFill, endFill = 0, min(amp, length) # Performing the shift operations given by the getShiftDirList method. for i in range(startPlane, endPlane, scanDir): j = i + amp * scan dirList = grid.getShiftDirsList(d, amp, i) mamba.shift(imIn[i], imOut[j], dirList[0][0] , dirList[0][1], fill, grid=dirList[0][2]) if len(dirList) > 1: mamba.shift(imOut[j], imOut[j], dirList[1][0] , dirList[1][1], fill, grid=dirList[1][2]) # Filling the necessary planes. for i in range(startFill, endFill): imOut[i].fill(fill)
def shift3D(imIn, imOut, d, amp, fill, grid=m3D.DEFAULT_GRID3D): """ Shifts 3D image 'imIn' in direction 'd' of the 'grid' over an amplitude of 'amp'. The emptied space is filled with 'fill' value. This implementation is fast as a minimal number of shifts is used. The result is put in 'imOut'. """ (width, height, length) = imIn.getSize() if length != len(imOut): mamba.raiseExceptionOnError(core.MB_ERR_BAD_SIZE) # Computing limits according to the scanning direction. scan = grid.convertFromDir(d, 0)[0] if scan == 0: startPlane, endPlane, scanDir = 0, length, 1 startFill, endFill = 0, 0 elif scan == -1: startPlane, endPlane, scanDir = amp, length, 1 startFill, endFill = max(length - amp, 0), length else: startPlane, endPlane, scanDir = length - amp - 1, -1, -1 startFill, endFill = 0, min(amp, length) # Performing the shift operations given by the getShiftDirList method. for i in range(startPlane, endPlane, scanDir): j = i + amp * scan dirList = grid.getShiftDirsList(d, amp, i) mamba.shift(imIn[i], imOut[j], dirList[0][0], dirList[0][1], fill, grid=dirList[0][2]) if len(dirList) > 1: mamba.shift(imOut[j], imOut[j], dirList[1][0], dirList[1][1], fill, grid=dirList[1][2]) # Filling the necessary planes. for i in range(startFill, endFill): imOut[i].fill(fill)
def infFarNeighbor3D(imIn, imInOut, nb, amp, grid=m3D.DEFAULT_GRID3D, edge=mamba.FILLED): """ Performs an infimum operation between the 'imInOut' 3D image pixels and their neighbor 'nb' at distance 'amp' according to 'grid' in 3D image 'imIn'. The result is put in 'imInOut'. "grid' value can be CUBIC, CENTER_CUBIC or FACE_CENTER_CUBIC. 'edge' value can be EMPTY or FILLED. """ (width,height,length) = imIn.getSize() if length!=len(imInOut): mamba.raiseExceptionOnError(core.MB_ERR_BAD_SIZE) imWrk = mamba.imageMb(imIn[0]) # Computing limits according to the scanning direction. scan = grid.convertFromDir(nb,0)[0] if scan == 0: startPlane, endPlane, scanDir = 0, length, 1 startFill, endFill = 0, 0 elif scan == 1: startPlane, endPlane, scanDir = 0, length - amp, 1 startFill, endFill = max(length - amp, 0), length else: startPlane, endPlane, scanDir = length - 1, amp - 1, -1 startFill, endFill = 0, min(amp, length) # Performing the shift operations given by the getShiftDirList method. if edge == mamba.EMPTY: fillValue = 0 else: fillValue = mamba.computeMaxRange(imIn[0])[1] for i in range(startPlane, endPlane, scanDir): j = i + amp * scan dirList = grid.getShiftDirsList(nb, amp, i) if len(dirList) == 1: mamba.infFarNeighbor(imIn[j], imInOut[i], dirList[0][0] , dirList[0][1], grid=dirList[0][2], edge=edge) else: d = mamba.transposeDirection(dirList[1][0], dirList[1][2]) mamba.shift(imIn[j], imWrk, d, dirList[1][1], fillValue, grid=dirList[1][2]) mamba.infFarNeighbor(imWrk, imInOut[i], dirList[0][0] , dirList[0][1], grid=dirList[0][2], edge=edge) # Filling the necessary planes. if edge == mamba.EMPTY: for i in range(startFill, endFill): imInOut[i].fill(fillValue)