This procedure automates the Rule-Based Feature Extraction workflow, using an imported rule file (.rul).
Based on the segmentation options that you specify, ENVI will compute spatial, spectral, and texture attributes and will generate the following optional images: segmentation, attribute, rule confidence, and classification.
You must have an ENVI Feature Extraction license in order to use this routine.
ENVI_DOIT, 'ENVI_FX_RULEBASED_DOIT' [, A_FID=array] [, A_POS=array] [, ATTRIBUTE_RASTER_FILENAME=string] [, BR_BANDS=array] [, CLASSIFICATION_RASTER_FILENAME=string] [, CONFIDENCE_RASTER_IMAGE=string] [, CS_BANDS=array] [, DIMS=array] [, /DO_MERGE], FID=file ID [, /EXPORT_VECTOR_ATTRIBUTES] [, /INVERSE_MASK] [, KERNEL_SIZE=long integer] [, M_FID=file ID][, MERGE_ALGORITHM=string] [ , MERGE_BANDS=array] [, MERGE_LEVEL=floating point] [, POS=array] [, R_FID=variable] [, REPORT_FILENAME=string], RULE_FILENAME=string [, SCALE_LEVEL=floating point] [, SEGMENT_ALGORITHM=string], SEGMENTATION_RASTER_FILENAME=string [, SEGMENT_BANDS=array] [, VECTOR_FILENAME=string]
Set this keyword to an array of file IDs for ancillary data files. Use this keyword in conjunction with the A_POS keyword. The number of elements of A_FID must equal the number of elements of A_POS.
Set this keyword to an array of long integers representing band numbers to process in the ancillary data files. Use this keyword in conjunction with the A_FID keyword. Specify bands starting with zero (Band 1 = 0, Band 2 = 1, etc.)
Each element in the A_POS array corresponds to an element in the A_FID array. For example, suppose you have two ancillary files whose file IDs are 100 and 200. To process Band 1 from file ID 200, and to process Bands 2-5 from file 100, write the code as follows:
A_FID = [200, 100, 100, 100, 100]
A_POS = [0, 1, 2, 3, 4]
To process all bands from the same file (100), write the code as follows:
A_FID = [100, 100, 100, 100, 100]
A_POS = [0, 1, 2, 3, 4]
Set this keyword to a string with the name of the output attribute image, which is a multi-layer image in ENVI raster format where each layer represents the values of a specific attribute. All attributes are included.
Set this keyword to a two-element array of long integers that represent bands used to compute an optional Normalized Difference index to use in segmentation. The Normalized Difference index is computed as follows:
[(b2 - b1) / (b2 + b1 + eps)]
Where "eps" is a very small number to avoid division by zero.
Note: Set BR_BANDS using the following order: [b1, b2]. Band numbers start with 0.
If b2 is near-infrared and b1 is red, then Normalized Difference will be a measure of normalized difference vegetation index (NDVI). ENVI will create a "Normalized Difference" band that you can use for segmentation or classification.
For example, multispectral QuickBird images have the following band definitions:
Zero-based band number
|Blue (485 nm)
|Green (560 nm)
|Red (660 nm)
Near-infrared (830 nm)
To compute NDVI using QuickBird imagery, set BR_BANDS=[2,3].
Set this keyword to a string with the name of the output classification image. This type of image is in ENVI raster format, and the pixel vaues represent different classes.
Set this keyword to a string with the name of the output rule confidence image. This type of image is in ENVI raster format and shows the relative confidence of each object belonging to a class. The higher the brightness of an object, the higher the confidence that the object belongs to the class. If an object is very dark, it likely does not belong to the class. This is a multi-layer file, with each layer representing one class.
Set this keyword to a three-element array of long integers that represent the red, green, and blue bands from the input image. Bands are zero-based, so Band 1=0, Band 2=1, etc. These will be used to perform an optional RGB to HSI color space transformation that will create Hue, Saturation, and Intensity bands to use in segmentation.
The “dimensions” keyword is a five-element array of long integers that defines the spatial subset (of a file or array) to use for processing. Nearly every time you specify the keyword FID, you must also specify the spatial subset of the corresponding file (even if the entire file, with no spatial subsetting, is to be processed).
- DIMS: A pointer to an open ROI; use only in cases where ROIs define the spatial subset. Otherwise, set to -1L.
- DIMS: The starting sample number. The first x pixel is 0.
- DIMS: The ending sample number
- DIMS: The starting line number. The first y pixel is 0.
- DIMS: The ending line number
To process an entire file (with no spatial subsetting), define DIMS as shown in the following code example. This example assumes you have already opened a file using ENVI_SELECT or ENVI_PICKFILE:
envi_file_query, fid, dims=dims
This keyword is set by default to merge adjacent features in the polygon shapefile specified in the VECTOR_FILENAME keyword. This keyword is set by default.
Perform merging if you are confident that adjacent polygons belong to the same class and you want to consolidate them into a single polygon. This results in a smaller file size. This option merges all adjacent segments at once across the entire image; you cannot select specific polygons to merge.
Tip: A good example is an angled rooftop that reveals different brightness levels from an aerial sensor, depending on the sun's angle. The segmentation step would typically create multiple regions within the rooftop, each with different spectral values. But if you build a good rule set that identifies rooftops, the classification image (and/or shapefile) will assign these regions to the same class. Since you know that they all belong to one rooftop, you can choose to merge the adjacent segments so that the entire rooftop is one polygon.
This keyword is set by default to include the spatial, spectral, and texture attributes that were computed for each region, when creating a shapefile of classification results.
The file ID (FID) is a long-integer scalar with a value greater than 0. An invalid FID has a value of -1. The FID is provided as a named variable by any routine used to open or select a file. Often, the FID is returned from the keyword R_FID in the ENVIRasterToFID routine. Files are processed by referring to their FIDs. If you work directly with the file in IDL, the FID is not equivalent to a logical unit number (LUN).
Set this keyword to invert the mask specified by the M_FID keyword. Inverting the mask means that Feature Extraction will process regions with pixel values of 0 in the mask.
Set this keyword to a long-integer odd number representing the size of the kernel used in texture attribute calculations. The default value is 3.
Set this keyword to the file ID of a raster mask image. If you specify this keyword, Feature Extraction will ignore regions with pixel values of 0 in the mask.
Set this keyword to one of the following strings, specifying the method used to perform merging:
- Full Lambda Schedule: (default). Merges small segments within larger, textured areas such as trees or clouds, where over-segmentation may be a problem.
- Fast Lambda: Merges adjacent segments with similar colors and border sizes.
See Merge Algorithms Background for more detailed descriptions of each option.
Set this keyword to an array of long integers that represent band numbers to use with the merge algorithm and merge level that you specify. Merging will be based on the differences between region colors on all selected bands. By default, all bands of the input image will be used.
If you selected a spectral subset of bands using the POS keyword, then specify band numbers according to the POS array, not the original dataset. For example, suppose that you created a spectral subset of bands 1, 2, 5, and 7 from a 7-band dataset. The POS array for these four bands is [0, 1, 2, 3]. To perform merging on bands 1, 2, and 5 from the original dataset, then use the corresponding POS band numbers as follows:
MERGE_BANDS=[0, 1, 2]
If you do not select a spectral subset, then you do not have to keep track of the POS band numbering, as in this example. By default, the MERGE_BANDS keyword will use all bands from the input image.
Set this keyword to a floating-point value between 0 and 100.0, specifying the merge level used to combine segments with similar colors (Fast Lambda method) or to merge over-segmented areas (Full Lambda Schedule method). The default value is 0.
Use this keyword to specify an array of band numbers used to perform segmentation. POS indicates the spectral subset of bands to use in processing. Specify bands starting with zero (Band 1 = 0, Band 2 = 1, etc.)
ENVI creates a single dataset from the combined bands of the input image, ancillary data, normalized difference, hue, saturation, and intensity (if selected). For best results, you should not perform segmentation with a combination of custom bands (normalized difference or HSI color space) and visible/NIR bands. You can perform segmentation on the normalized difference or color space bands by themselves. So in most cases, you will need to select a spectral subset for segmentation instead of using all bands.
Specify band numbers in the following order:
- Input image: one or more bands
- Ancillary image(s): one or more bands
- Normalized difference: one band
- Hue: one band
- Saturation: one band
- Intensity: one band
For example, if the input image has four bands and you want to perform segmentation on these bands only, set POS = [0, 1, 2, 3].
Or, suppose you have a 4-band image and you set the BR_BANDS and CS_BANDS keywords. The band numbers are as follows:
- Input image: [0, 1, 2, 3]
- Normalized difference: 
- Hue: 
- Saturation: 
- Intensity: 
To perform segmentation on the saturation band only, set POS =  in this example.
For hyperspectral imagery, we strongly recommend that you run a principal components analysis or independent components analysis on the dataset before using it in Feature Extraction. Segmentation and merging work best on datasets with only a few bands, plus it helps you keep track of the band numbers when setting the POS keyword.
This keyword is a returned variable containing the file ID of the segmentation image. If processing fails for any reason, then R_FID = -1.
Set this keyword to a string indicating the filename of a text report that lists the segmentation and merge settings used, the input and ancillary files used, a list of attributes that were computed for the segmentation image, and any output files that were created.
Set this keyword to a string with the full path and filename of a rule file (.rul) that contains the rule set to use for classification.
Set this keyword to a floating-point value between 0 and 100.0, indicating the scale level used to delineate features of interest in segmentation. Increasing the value reduces the number of segments. The default value is 50.0 for the Edge segmentation method and 0 for the Intensity method.
Set this keyword to one of the following strings, indicating the segmentation method to use:
- Edge (default): Best for detecting edges of features where objects of interest have sharp edges. Set the SCALE_LEVEL and MERGE_LEVEL as needed to best delineate features of interest.
- Intensity: Best for segmenting images with subtle gradients such as digital elevation models (DEMs) or images of electromagnetic fields. When selecting this method, don't perform any merging; set MERGE_LEVEL=0. Merging is used primarily to combine segments with similar spectral information. Elevation and other related attributes are not appropriate for merging.
See Watershed Algorithm Background for more detailed descriptions of each option.
Set this keyword to a string indicating the filename of the output segmentation image. This is an image in ENVI raster format that shows the regions defined by segmentation; each region is assigned the mean spectral values of all the pixels that belong to that region.
Set this keyword to an array of long integers representing the band numbers to use in the segmentation method and scale level that you specify. All bands from the input image are selected by default. The settings will apply to a grayscale image derived from the average of all selected bands. For best segmentation results, select a combination of bands that have similar spectral ranges such as red, green, blue, and near-infrared bands.
If you selected a spectral subset of bands using the POS keyword, then specify band numbers according to the POS array, not the original dataset. For example, suppose that you created a spectral subset of bands 1, 2, 5, and 7 from a seven-band dataset. The POS array for these four bands is [0, 1, 2, 3]. To perform segmentation on bands 1, 2, and 5 from the original dataset, then set SEGMENT_BANDS to the corresponding POS band numbers as follows:
SEGMENT_BANDS=[0, 1, 2]
If you do not select a spectral subset, then you do not have to keep track of the POS band numbering, as in this example. By default, the SEGMENT_BANDS keyword will use all bands from the input image.
Set this keyword to a string indicating the filename of a polygon shapefile of classification results. If you do not specify this keyword, then no shapefile will be created.
This example uses files that are on the ENVI Resource DVD, which is provided with the software installation disk. Go to the feature_extraction folder, and copy the files Hobart_GeoEye_pansharp*.* to the data directory of the ENVI installation:
Windows: C:\Program Files\Harris\ENVIxx\data
This example rule set extracts asphalt roads from a GeoEye image of Hobart, Austrailia. The sample image is courtesy of GeoEye.
e = ENVI(/HEADLESS)
temp_dir = e.GetPreference('TEMPORARY_DIRECTORY')
e.LOG_FILE = temp_dir+'batch.txt'
file = FILEPATH('Hobart_GeoEye_pansharp.dat', $
SUBDIRECTORY = ['data'])
raster = e.OpenRaster(file)
fid = ENVIRasterToFID(raster)
IF (FID eq -1) THEN BEGIN
rule_file = FILEPATH('Hobart_GeoEye_ruleset.rul', $
SUBDIR = ['data'])
report_filename = temp_dir+'report.txt'
confidence_raster_filename = temp_dir+'confidence.dat'
classification_raster_filename = temp_dir+'class.dat'
segmentation_raster_filename = temp_dir+'segmentation.dat'
dims = [-1L, 0, raster.ncolumns-1, 0, raster.nrows-1]
pos = lindgen(raster.nbands)
envi_doit, 'envi_fx_rulebased_doit', $
fid=fid, pos=pos, dims=dims, $
r_fid=r_fid, merge_level=80.0, $
segmentation_raster = ENVIFIDToRaster(r_fid)
segmentation_raster_URI = segmentation_raster.URI
e = ENVI()
raster = e.OpenRaster(segmentation_raster_URI)
view = e.GetView()
layer1 = view.CreateLayer(raster)
raster2 = e.OpenRaster(classification_raster_filename)
layer2 = view.CreateLayer(raster2)