[mmcthin] [Up] [mmskiz] | Thinning And Thickening |
Implemented in Python.
f | Image Gray-scale (uint8 or uint16) image. |
g | Image Gray-scale (uint8 or uint16) or binary image.
marker image: binary or labeled. |
Bc | Structuring Element (watershed connectivity) Default:
|
LINEREG | String 'LINES' or ' REGIONS'. Default:
|
Y | Image Gray-scale (uint8 or uint16) or binary image. |
mmcwatershed creates the image
y
by detecting the domain of the catchment basins of
f
indicated by the marker image
g
, according to the connectivity defined by
Bc
. According to the flag LINEREG
y
will be a labeled image of the catchment basins domain or just a binary image that presents the watershed lines. To know more about watershed and watershed from markers, see BeucMeye:93. The implementation of this function is based on LotuFalc:00. WARNING: There is a common mistake related to the marker image
g
. If this image contains only zeros and ones, but it is not a binary image, the result will be an image with all ones. If the marker image is binary, you have to set this explicitly using the
logical
function.
>>> a = uint8([\ [10, 10, 10, 10, 10, 10, 10],\ [10, 9, 6, 18, 6, 5, 10],\ [10, 9, 6, 18, 6, 8, 10],\ [10, 9, 9, 15, 9, 9, 10],\ [10, 9, 9, 15, 12, 10, 10],\ [10, 10, 10, 10, 10, 10, 10]])
>>> b = mmcmp(a,'==',uint8(6))
>>> print mmcwatershed(a,b)
[[0 0 0 1 0 0 0] [0 0 0 1 0 0 0] [0 0 0 1 0 0 0] [0 0 0 1 0 0 0] [0 0 0 1 0 0 0] [0 0 0 0 1 0 0]]
>>> print mmcwatershed(a,b,mmsecross(),'REGIONS')
[[1 1 1 1 2 2 2] [1 1 1 1 2 2 2] [1 1 1 1 2 2 2] [1 1 1 1 2 2 2] [1 1 1 1 2 2 2] [1 1 1 1 2 2 2]]
def mmcwatershed(f, g, Bc=None, LINEREG="LINES"): from Numeric import ones, zeros, nonzero, array, put, take, argmin, transpose, compress, concatenate if Bc is None: Bc = mmsecross() return g print 'starting' withline = (LINEREG == 'LINES') if mmis(g,'binary'): g = mmlabel(g,Bc) print 'before 1. mmpad4n' status = mmpad4n(uint8(zeros(f.shape)),Bc, 3) f = mmpad4n( f,Bc,0) #pad input image print 'before 2. mmpad4n' y = mmpad4n( g,Bc,0) # pad marker image with 0 if withline: y1 = mmintersec(mmbinary(y), 0) costM = mmlimits(f)[1] * ones(f.shape) # cummulative cost function image mi = nonzero(mmgradm(y,mmsebox(0),Bc).flat) # 1D index of internal contour of marker print 'before put costM' put(costM.flat,mi, 0) HQueue=transpose([mi, take(costM.flat, mi)]) # init hierarquical queue: index,value print 'before mmse2list0' Bi=mmse2list0(f,Bc) # get 1D displacement neighborhood pixels x,v = mmmat2set(Bc) while HQueue: print 'Hq=',HQueue i = argmin(HQueue[:,1]) # i is the index of minimum value print 'imin=',i pi = HQueue[i,0] print 'pi=',pi ii = ones(HQueue.shape[0]) ii[i] = 0 print 'ii=',ii HQueue = transpose(array([compress(ii,HQueue[:,0]), compress(ii,HQueue[:,1])])) # remove this pixel from queue print 'H=',HQueue put(status.flat, pi, 1) # make it a permanent label for qi in pi+Bi : # for each neighbor of pi if (status.flat[qi] != 3): # not image border if (status.flat[qi] != 1): # if not permanent cost_M = max(costM.flat[pi], f.flat[qi]) if cost_M < costM.flat[qi]: print 'qi=',qi costM.flat[qi] = cost_M y.flat[qi] = y.flat[pi] # propagate the label aux = zeros(array(HQueue.shape) + [1,0]) aux[:-1,:] = HQueue aux[-1,:]=[qi, cost_M] HQueue = aux # insert pixel in the queue print 'insert H=',HQueue elif (withline and (y.flat[qi] != y.flat[pi]) and (y1.flat[pi] == 0) and (y1.flat[qi] == 0) ): y1.flat[pi] = 1 if withline: Y = y1 else: Y = y return Y
mmfreedom | Control automatic data type conversion. |
mmwatershed | Watershed detection. |
mmsebox | Create a box structuring element. |
mmsecross | Diamond structuring element and elementary 3x3 cross. |
mmswatershed | Detection of similarity-based watershed from markers. |
mmdcalc | Extract the keys of a calculator. |
[mmcthin] [Up] [mmskiz] | ![]() |
Copyright (c) 2003, Roberto A. Lotufo, UNICAMP-University of Campinas; Rubens C. Machado, CenPRA-Renato Archer Research Center. |