This function returns a reference to a bounding box set. Bounding boxes are used to label features of interest in object detection. The purpose of ENVIBoundingBoxSet is to programmatically add and manage bounding box information in object detection rasters, instead of drawing rectangle annotations on a training raster. Bounding boxes are stored as GeoJSON metadata in object detection rasters. See Bounding Boxes Background for details.

Use the ENVIBoundingBoxSet function to:

  • Import existing bounding boxes, using the INPUT_GEOJSON keyword. Then, add or remove bounding boxes as needed; or:

  • Create a new bounding box set

Another scenario is to import existing labeled data in the form of shapefiles or regions of interest (ROIs). Then convert them to bounding boxes using the ENVIBoundingBoxSet function.

This routine is part of ENVI Deep Learning, which requires a separate license and installation.

Example


This example creates a bounding box set and populates it with three classes, with three bounding boxes each. The example displays, manipulates, and redisplays the bounding box properties, showing the changes that were made. Finally, it displays a GeoJSON hash that contains four features for classes 1 and 2. The bounding boxes for all three classes are in pixel coordinates, so the SPATIALREF keyword does not need to be explicitly set.

Follow these steps:

  1. Copy and paste the code below into the IDL Editor.

  2. Save the program as ENVIBoundingBox_Example.pro.

  3. Compile and run the program.

PRO ENVIBoundingBoxSet_Example
COMPILE_OPT IDL2, hidden
 
  ; Start the application
  e = ENVI(/HEADLESS)
 
  ; Define bounding box rings
  ; [[xMin,yMin], [xMax,yMin], [xMax,yMax], [xMin,yMax], [xMin,yMin]]
  boxes = [ $
    [[530, 381], [570, 381], [570, 421], [530, 421], [530, 381]], $
    [[438, 859], [478, 859], [478, 899], [438, 899], [438, 859]], $
    [[392, 212], [432, 212], [432, 252], [392, 252], [392, 212]], $
    [[636, 499], [676, 499], [676, 539], [636, 539], [636, 499]], $
    [[266, 519], [306, 519], [306, 559], [266, 559], [266, 519]], $
    [[398, 729], [438, 729], [438, 769], [398, 769], [398, 729]], $
    [[300, 486], [340, 486], [340, 526], [300, 526], [300, 486]], $
    [[400, 545], [440, 545], [440, 585], [400, 585], [400, 545]], $
    [[204, 723], [244, 723], [244, 763], [204, 763], [204, 723]]]
   
  ; Supplement class labels, colors, and bounding boxes
  labels = List('red_car', 'green_car', 'blue_car')
  colors = List([255,0,0], [0,255,0], [0,0,255])
  classBoxes = (List(boxes[*,*,0:2], boxes[*,*,3:5], boxes[*,*,6:8])).ToArray(/TRANSPOSE)
   
  ; Construct the bounding box set
  bboxSet = ENVIBoundingBoxSet()
   
  ; Iterate class labels, adding class information to the object
  FOREACH name, labels, index DO BEGIN
    bboxSet.AddClass, CLASS=index, LABEL=name, COLOR=colors[index]
   
    ; Assign three boxes per class
    FOR n=0, 2 DO BEGIN
      bboxSet.AddBoundingBox, CLASS=index, BOUNDING_BOX=classBoxes[*,*,index,n]
    ENDFOR
  ENDFOREACH
   
  Print, 'Classes:'
  Print, bboxSet.Classes
  Print, 'Labels:'
  Print, bboxSet.Labels
  Print, 'Class Colors: '
  Print, bboxSet.Colors
  Print, 'Classes Count: ', bboxSet.nClasses
  Print, 'Bounding Box Count: ', bboxSet.nBounding_Boxes
  Print, 'Class to Bounding Box Map:'
  Print, bboxSet.Bounding_Boxes_Per_Class
  Print, 'Get Bounding Box by Index: '
   
  ; Get the first bounding box in class 0
  Print, bboxSet.GetBoundingBox(CLASS=0, INDEX=0)
   
  Print, 'Get All Class 1 Bounding Boxes:'
   
  ; Get all bounding boxes for class 1
  Print, bboxSet.GetBoundingBox(CLASS=1, /ALL), /IMPLIED 
   
  ; Remove boxes and classes
  ; First, remove all bounding boxes from class 0
  bboxSet.RemoveBoundingBox, CLASS=0, /ALL
   
  ; Remove the bounding box at index 0 in class 1
  bboxSet.RemoveBoundingBox, CLASS=1, INDEX=0
   
  ; Remove a bounding box from class 2 (using coordinates)
  bboxSet.RemoveBoundingBox, CLASS=2, BOUNDING_BOX=classBoxes[*,*,2,0]
   
  ; Remove the red_car class
  bboxSet.RemoveClass, CLASS=0
   
  Print, 'After removing boxes and class 0.
  Print, 'Classes:'
  Print, bboxSet.Classes
  Print, 'Labels:'
  Print, bboxSet.Labels
  Print, 'Class Colors: '
  Print, bboxSet.Colors
  Print, 'Classes Count: ', bboxSet.nClasses
  Print, 'Bounding Box Count: ', bboxSet.nBounding_Boxes
  Print, 'Class to Bounding Box Map:'
  Print, bboxSet.Bounding_Boxes_Per_Class
   
  ; Get GeoJSON and display
  geoJson = bboxSet.GetGeoJSON()
  Print, geoJson, /IMPLIED
   
END

Syntax


Result = ENVIBoundingBoxSet([Properties=value] [, Keywords=value])

Return Value


This function returns a reference to an ENVIBoundingBoxSet object.

Arguments


None

Methods


AddBoundingBox

AddClass

GetBoundingBox

GetENVIGeoJSON

GetGeoJSON

RemoveBoundingBox

RemoveClass

Properties


BOUNDING_BOXES_PER_CLASS (Get)

A hash containing a class index, followed by the number of bounding boxes for the class. In the following example, class 0 has 250 bounding boxes:

{
  0:250,
  1:300,
  etc.
}

CLASSES (Get)

An array of class values; for example:

[0,1,2]

COLORS (Get)

An array of RGB triplets with class colors; for example:

[[255,0,0],[0,255,0],[0,0,255]]

LABELS (Get)

A string array of class labels; for example:

['red_car', 'green_car', 'blue car']

NUM_BOUNDING_BOXES (Get)

The total number of bounding boxes.

NUM_CLASSES (Get)

The total number of classes.

SPATIALREF (Get)

The spatial reference used when instantiating the ENVIBoundingBoxSet instance or when the latest bounding box was added. This can be a reference to an ENVIStandardSpatialRef, ENVIRPCRasterSpatialRef, ENVIGLTRasterSpatialRef, or ENVIPseudoRasterSpatialRef object.

If the input GeoJSON code (set with the INPUT_GEOJSON keyword) or newly added bounding boxes (set with the AddBoundingBox method) are in pixel coordinates, then this property will be null.

Keywords


ERROR (optional)

Set this keyword to a named variable that will contain any error message issued during execution of this routine. If no error occurs, the ERROR variable will be set to a null string (''). If an error occurs and the routine is a function, then the function result will be undefined.

When this keyword is not set and an error occurs, ENVI returns to the caller and execution halts. In this case, the error message is contained within !ERROR_STATE and can be caught using IDL's CATCH routine. See IDL Help for more information on !ERROR_STATE and CATCH.

See the Manage Errors topic in ENVI Help for more information on error handling.

SPATIALREF (optional)

Set this keyword to an ENVIStandardSpatialRef, ENVIRPCRasterSpatialRef, ENVIGLTRasterSpatialRef, or ENVIPseudoRasterSpatialRef object if the bounding box was derived from a source raster that has a spatial reference. Set this keyword to that spatial reference. ENVI will internally convert the bounding box coordinates to pixel coordinates. If you do not specify this keyword, no projection conversion will happen, and pixel coordinates will be assumed for the bounding boxes.

INPUT_GEOJSON (optional)

Specify one of the following:

  • A hash containing bounding box properties. The hash must be in a specific format. See an example in the Bounding Boxes Background topic.

  • A fully qualified URI to a JSON file that contains a hash of bounding box properties. The hash must be in the expected format.

  • An ENVIGeoJSON object that contains a hash of bounding box properties. The hash must be in the expected format.

The purpose of this keyword is to import existing bounding box information so that you can add or remove bounding boxes. You can also add and remove classes as needed.

If you do not specify this keyword, an empty hash will be created so that you can add your own bounding box information.

Version History


1.2

Introduced

See Also


BuildObjectDetectionRasterFromAnnotation Task