;+ ; NAME: ; MM_DIST ; ; ; ; PURPOSE: ; Generates the distance function of a binary image ; ; ; ; CATEGORY: ; Mathematical morphology ; ; ; CALLING SEQUENCE: ; result = mm_dist(image) ; ; ; INPUTS: ; ; image: 2d- or 3d- byte array ; ; ; OPTIONAL INPUTS: ; none ; ; ; KEYWORD PARAMETERS: ; ; RADIUS: For 3d- images: radius of successive erosions ; CUBEOCTAEDER: For 3-d images type ; ; VERBOSE: For 3d- images: print of actual repetition ; ; DISPLAY: For 3d- images: display of one section at actual repetition ; ; OUTPUTS: ; ; result: distance transform: each pixel value represents the minimum ; distance to the background ; ; image: for 3-d the image is binarized (image = image GE 0) ; ; OPTIONAL OUTPUTS: ; none ; ; ; COMMON BLOCKS: ; none ; ; ; SIDE EFFECTS: ; none ; ; ; RESTRICTIONS: ; For 2-d images procedure DISTPN is applied ; For 3-d images for erosion function MM_DIL is applied ; on inverted input. Hence the results differ between 2d and 3d ; for objects touching the border. Up to now there is no ; distance function for 2d by dilation of the inverted binary image. ; (has to be done) ; ; MM_DIST for 2d corresponds with MORPH_DISTANCE with keyword ; NEIGHBORHOOD=3! ; ; ; PROCEDURE: ; For 2-d images procedure DISTPN is applied. ; For 3-d images the input is binarized (input GE 0) and ; successive erosions are added up to the input image is zeroed. ; Successive Erosion means the application of keyword STEP in ; function MM_DIL on the inverted input array (see there). ; ; ; EXAMPLE: ; 2-d: ; a = bytarr(128,128) ; a[32:96,32:96] = 1B ; b = mm_dist(a) ; ; 3-d: ; a = bytarr(128,128,128) ; a[32:96,32:96,32:96] = 1b ; b = mm_dist(a) ; ; ; MODIFICATION HISTORY: ; ; Tue Jul 15 16:33:44 2003, ; ; improved documentation and some test ; ; Mon Mar 03 13:18:21 2003, ; ; Added in 3-d cubeoctaeder dilation/erosion ; Changed MM_xxx_N to MM_xxx ; ; Fri Jul 11 08:43:46 1997, Karsten Rodenacker ; ; ; ; FUNCTION mm_dist, ia, RADIUS=rad, CUBEOCTAEDER = cubeo, $ FORCE_INVERSE=for_inv, $ VERBOSE=verb, DISPLAY=disp IF NOT keyword_set(rad) THEN rad=1 IF rad LT 0 THEN rad = -1 sa=size(ia) a=ia NE 0b IF min(sa(1:3)) LE 256 THEN b=a $ ELSE b=fix(a) CASE sa(0) OF 3:BEGIN j=0 WHILE max(a) NE 0 DO BEGIN if keyword_set(for_inv) then begin a=1b-temporary(a) a=mm_dil(temporary(a), rad, CUBEOCTAEDER = cubeo, step=j+1) a=mm_bord(temporary(a), 1, val=1) a=1b-temporary(a) endif else a=mm_ero(temporary(a), rad, CUBEOCTAEDER = cubeo, step=j+1) b=b+a*abs(rad) j=j+1 IF keyword_set(disp) THEN tvscl, a[*,*,sa[3]/2] IF keyword_set(verb) THEN print, j*rad, format='($,i3)' IF rad LT 0 THEN rad = rad XOR 1 ENDWHILE IF keyword_set(verb) THEN print, ' ' return, b END ELSE:if keyword_set(for_inv) then begin j=0 WHILE max(a) NE 0 DO BEGIN a=1b-temporary(a) a=mm_dil(temporary(a), rad, step=j+1) a=mm_bord(temporary(a), 1, val=1) a=1b-temporary(a) b=b+a*abs(rad) j=j+1 IF keyword_set(disp) THEN tvscl, b IF keyword_set(verb) THEN print, j*rad, format='($,i3)' IF rad LT 0 THEN rad = rad XOR 1 ; IF rad EQ -1 THEN rad=-2 ELSE IF rad EQ -2 THEN rad=-1 ENDWHILE IF keyword_set(verb) THEN print, ' ' return, b endif else return,distpn(a NE 0) ENDCASE END ;-