; $Id: search2d.pro,v 1.5 1997/01/15 03:11:50 ali Exp $

; Copyright (c) 1992-1997, Research Systems, Inc. All rights reserved.
;	Unauthorized reproduction prohibited.
;
;+
; NAME:
;	SEARCH2D
;
; PURPOSE:
;	This function finds "objects" or regions of similar data
;       values within a 2-D array of data. Given a starting location
;       and a range of values to search for, SEARCH2D will find all
;       the cells within the array that are within the specified range
;       of values, and have some path of connectivity through these cells
;       to the starting location. See the procedure "SEARCH3D" for the
;       three dimensional case.
;
;       This function returns a list of the array subscripts that define
;       the selected object or region.
;
; CATEGORY:
;       Data subsetting.
;	Image manipulation.
;
; CALLING SEQUENCE:
;       Region = SEARCH2D(Array, Xpos, Ypos, Min_val, Max_val)
;
; INPUTS:
;       Array:      The 2-D array of data to search.
;                   Data type : Any 2-D array except string or structure.
;       Xpos:       The X coordinate(s) (first subscript into the 2-D Array)
;                   of the seed point(s) for the search.   Xpos can be a
;                   single value, or an array of subscripts specifying the
;                   X coordinates of a seed region.   Xpos must have the same
;                   number of elements as Ypos.
;                   Data type : Long or Lonarr.
;       Ypos:       The Y coordinate(s) (second subscript into the 2-D Array)
;                   of the seed point(s) for the search.   Ypos can be a
;                   single value, or an array of subscripts specifying the
;                   Y coordinates of a seed region.   Ypos must have the same
;                   number of elements as Xpos.
;                   Data type : Long or Lonarr.
;       Min_val:    The minimum data value to search for. All cells that
;                   are connected to the starting cell, and have a value
;                   greater than or equal to Min_val and less than or equal
;                   to Max_val, will be considered part of the "object".
;                   If omitted, the default is MIN(Array[Xpos, Ypos]) .
;       Max_val:    The maximum data value to search for.
;                   If omitted, the default is MAX(Array[Xpos, Ypos]) .
;
; KEYWORD PARAMETERS:
;       IMAGE:      If set, SEARCH2D returns a bi-level image (2-D byte array)
;                   with the same dimensions as Array, containing the value
;                   (1) where the object is, and (0) where it isn't.
;
;       DIAGONAL:   This keyword is now obsolete since LABEL_REGION is now
;                   used to find the object.
;       DECREASE:   This keyword is now obsolete as are INCREASE and LPF_BAND.
;                   A better way to perform this operation is to pre-process
;                   the Array parameter before passing to SEARCH2D.
;       INCREASE:   See the DECREASE keyword.
;       LPF_BAND:   See the DECREASE keyword.
;
; OUTPUTS:
;       This function returns a list of the indices into the 2-D array
;       that are part of the located object or region. This list is
;       returned as a LONARR(n) where n is the number of cells found.
;
;       If the returned array of indices is called Region, and the
;       size of the 2-D array of data is size_x by size_y, then the
;       actual X and Y indices can be obtained by using the following
;       algorithm :
;
;          index_y = Region / size_x
;          index_x = Region - (index_y * size_x)
;
;       The object within the 2-D Array could then be subscripted as :
;
;          Array[Region]
;       OR
;          Array[index_x, index_y]
;
;       If the IMAGE keyword is set, however, SEARCH2D returns a bi-level
;       image (2-D byte array) with the same dimensions as Array, containing
;       the value (1) where the object is, and (0) where it isn't.
;
; EXAMPLE:
;       Find all the indices corresponding to an object contained in a
;       2-D array of data.
;
;       ; Create some data.
;          img = FLTARR(512, 512)
;          img[3:503, 9:488] = 0.7
;          img[37:455, 18:438] = 0.5
;          img[144:388, 90:400] = 0.7
;          img[200:301, 1:255] = 1.0
;          img[155:193, 333:387] = 0.3
;
;       ; Display the image.
;          TVSCL, img
;
;       ; Search for an object starting at (175, 300) whose data values
;       ; are between (0.6) and (0.8).
;          object = SEARCH2D(img, 175, 300, 0.6, 0.8, /IMAGE)
; 
;       ; Display the object.
;          TVSCL, object
;
; MODIFICATION HISTORY:
;       Written by:     Daniel Carr. Thu Sep  3 15:36:17 MDT 1992
;       Modified:       Daniel Carr.
;                       Re-wrote to improve performance using "LABEL_REGION".
;                       Obsoleted keywords INCREASE, DECREASE, and LPF_BAND.
;                       Added IMAGE keyword.
;-

FUNCTION Search2d, array, xpos, ypos, min_val, max_val, Diagonal=diagonal, $
                   Image=image, Decrease=decrease, Increase=increase, $
                   Lpf_band=smooth_band

ON_ERROR, 2

IF (Keyword_Set(diagonal)) THEN $
   Print, 'Search2D: Obsolete keyword "DIAGONAL" ignored.'
IF (N_Elements(decrease) GT 0L) THEN $
   Print, 'Search2D: Obsolete keyword "DECREASE" ignored.'
IF (N_Elements(increase) GT 0L) THEN $
   Print, 'Search2D: Obsolete keyword "INCREASE" ignored.'
IF (N_Elements(smooth_band) GT 0L) THEN $
   Print, 'Search2D: Obsolete keyword "LPF_BAND" ignored.'

IF (N_Elements(min_val) LE 0L) THEN min_val = MIN(array[xpos, ypos], Max=max_val)
IF (N_Elements(max_val) LE 0L) THEN max_val = MAX(array[xpos, ypos])

size_array = Size(array)
s_array = Bytarr(size_array[1], size_array[2])
index = Where((array GE min_val) AND (array LE max_val))
IF (index[0] GE 0L) THEN s_array[Temporary(index)] = 1B

s_array[xpos, ypos] = 1B

s_array = Label_Region(Temporary(s_array))
seed_point = s_array[xpos[0], ypos[0]]
index = Where(Temporary(s_array) eq seed_point)

IF (Keyword_Set(image)) THEN BEGIN
   s_array = Bytarr(size_array[1], size_array[2])
   IF (index[0] GE 0L) THEN s_array[Temporary(index)] = 1B
   RETURN, s_array
ENDIF ELSE RETURN, index

END