X

NV5 Geospatial Blog

Each month, NV5 Geospatial posts new blog content across a variety of categories. Browse our latest posts below to learn about important geospatial information or use the search bar to find a specific topic or author. Stay informed of the latest blog posts, events, and technologies by joining our email list!



Mapping Earthquake Deformation in Taiwan With ENVI

Mapping Earthquake Deformation in Taiwan With ENVI

12/15/2025

Unlocking Critical Insights With ENVI® Tools Taiwan sits at the junction of major tectonic plates and regularly experiences powerful earthquakes. Understanding how the ground moves during these events is essential for disaster preparedness, public safety, and building community resilience. But traditional approaches like field... Read More >

Comparing Amplitude and Coherence Time Series With ICEYE US GTR Data and ENVI SARscape

Comparing Amplitude and Coherence Time Series With ICEYE US GTR Data and ENVI SARscape

12/3/2025

Large commercial SAR satellite constellations have opened a new era for persistent Earth monitoring, giving analysts the ability to move beyond simple two-image comparisons into robust time series analysis. By acquiring SAR data with near-identical geometry every 24 hours, Ground Track Repeat (GTR) missions minimize geometric decorrelation,... Read More >

Empowering D&I Analysts to Maximize the Value of SAR

Empowering D&I Analysts to Maximize the Value of SAR

12/1/2025

Defense and intelligence (D&I) analysts rely on high-resolution imagery with frequent revisit times to effectively monitor operational areas. While optical imagery is valuable, it faces limitations from cloud cover, smoke, and in some cases, infrequent revisit times. These challenges can hinder timely and accurate data collection and... Read More >

Easily Share Workflows With the Analytics Repository

Easily Share Workflows With the Analytics Repository

10/27/2025

With the recent release of ENVI® 6.2 and the Analytics Repository, it’s now easier than ever to create and share image processing workflows across your organization. With that in mind, we wrote this blog to: Introduce the Analytics Repository Describe how you can use ENVI’s interactive workflows to... Read More >

Deploy, Share, Repeat: AI Meets the Analytics Repository

Deploy, Share, Repeat: AI Meets the Analytics Repository

10/13/2025

The upcoming release of ENVI® Deep Learning 4.0 makes it easier than ever to import, deploy, and share AI models, including industry-standard ONNX models, using the integrated Analytics Repository. Whether you're building deep learning models in PyTorch, TensorFlow, or using ENVI’s native model creation tools, ENVI... Read More >

1345678910Last
«January 2026»
SunMonTueWedThuFriSat
28293031123
45678910
11121314151617
18192021222324
25262728293031
1234567
12181 Rate this article:
3.0

An ENVI 5 extension

Anonym

Last week, I showed an example of an ENVI 5 batch program. This week, I’ll show an extension, the successor to a user function in ENVI Classic. (Be warned, though, that this turned into a long post.)

Extensions are programs executed in an interactive ENVI session. Extensions allow programmatic control over not only the file access and analysis components of ENVI, but also the UI. Like batch programs, extensions may use routines from both the ENVI and IDL libraries. ENVI+IDL is required to build an extension, but by compiling an extension into an IDL SAVE file, the extension can be executed in an ENVI (runtime version) session. I’ll outline this technique at the end of the post. In this example, a user is prompted to select a file containing a raster image. The Prewitt edge enhancement operator is applied to each band of the image, with the result written to a new raster file. The first band of the input image is displayed in a new layer in the ENVI 5 UI, with the first band of the output image displayed in the same view as a portal. Here’s the start of the extension code:

pro envi5_extension_ex
   compile_opt idl2

   catch, err
   if err ne 0 then begin
      catch, /cancel
      if e ne !null then $
         e.reporterror, 'Error: ' + !error_state.msg $
      else $
         message, !error_state.msg, /continue, /noname
      message, /reset
      return
   endif

   e = envi(/current)
   if e eq !null then $
      message, 'This extension requires an interactive ENVI session. Exiting.' 

I’ve chosen to write this extension as a procedure (a function or class would also be fine; note there’s an ENVI extension wizard in the IDL Workbench, located under the File menu, that sets up skeleton code for an extension). The CATCH block handles errors thrown in the program. Call the ENVI function to get the reference to the current ENVI session. If ENVI isn’t running, MESSAGE throws an error that's handled by the CATCH block. Next, prompt the user for a raster file to load:

   in_raster = e.ui.selectinputdata(/raster)
   if in_raster eq !null then return 

The SelectInputData method of the ENVIUI object presents a file picker dialog, the ENVI 5 analog to ENVI_SELECT in Classic. It returns an ENVIRaster object. Recall that an ENVIRaster is analogous to a FID in Classic, but it also holds metadata. If the user cancels the operation, then exit the extension. Now prepare for the processed results:

   outdir = e.getpreference('output_directory')
   outfile = outdir + 'envi5_extension_ex.img'
   if file_test(outfile) then begin
      basenames = file_basename(outfile, '.img') + ['.img', '.img.enp', '.hdr']
      file_delete, outdir + basenames, /allow_nonexistent
   endif
   out_raster = e.createraster(outfile, inherits_from=in_raster)

In a manner similar to the batch program example from last week, I’ve set up a path to a file in the user’s output directory. The CreateRaster method makes a new ENVIRaster for the output. Because CreateRaster won’t allow an existing file to be overwritten, I've included some IDL code to delete the output file and its support files, if they exist. By using the INHERITS_FROM keyword, the CreateRaster method uses metadata from the input raster to populate the metadata for the output raster. Now perform the processing. Iterate over the input bands, applying the Prewitt edge enhancement operator (with the IDL PREWITT function) to each and writing the result to the output file:

   widget_control, /hourglass
   for i=0, in_raster.nbands-1 do begin
      band = in_raster.getdata(bands=i)
      edge = bytscl(prewitt(band))
      out_raster.setdata, edge, bands=i
   endfor
   out_raster.save 

The GetData method is the ENVI 5 analog to ENVI_GET_DATA in Classic. The Save method is the analog to ENVI_WRITE_ENVI_FILE. Finally, visualize the result in the ENVI UI. Using the default view, create new layers for the input and output images and display the first band of each, with the output displayed in a portal:

   view = e.getview()
   layer1 = view.createlayer(out_raster, bands=0, /clear_display)
   layer2 = view.createlayer(in_raster, bands=0)
   portal = view.createportal(layer=layer1, size=[150,150])
end 

As it currently stands, this extension could be executed in an interactive ENVI session with the Run button in the IDL Workbench, or by calling it from the IDL command prompt:

ENVI> envi5_extension_ex
% Compiled module: ENVI5_EXTENSION_EX.

However, analogous to a user function in Classic, an extension can be set up to automatically load into ENVI on startup and be visible in the Toolbox. To do this, two additional steps are needed. First, create an “extensions_init” program:

pro envi5_extension_ex_extensions_init
   compile_opt idl2

   e = envi(/current)
   e.addextension, 'Prewitt Edge Enhancement', 'envi5_extension_ex'
end 

This program is called by ENVI at startup. The purpose of this program is to add the item “Prewitt Edge Enhancement” to the Extensions folder of the ENVI 5 Toolbox, and to associate the program ENVI5_EXTENSION_EX with this item. Note that the name of this program is the name of the extension followed by _extensions_init. This program can be placed in the same file as the extension code, or in a separate file. This is the analog to the “define_buttons” routine for user functions in ENVI Classic. Second, the extension, along with the “extensions_init” program, must be placed in one of three locations: either a directory defined by the ENVI_EXTENSIONS environment variable, the extensions directory included in the ENVI installation, or the default extensions directory in the user's home directory. The ENVI Help provides more detail: see Contents > Programming > Toolbox Extensions. One final, optional, step. The extension in this example is written in IDL source code, and therefore can only be used in ENVI+IDL, not ENVI, which lacks the IDL compiler. You can deploy an extension in ENVI if you build the extension and its dependencies into an IDL SAVE file. Here are the steps used for the example above: Reset the current IDL session:

IDL> .reset

This removes all variables and compiled routines from the IDL session. Next, compile the extension with the Compile button in the IDL Workbench or the .compile executive command:

IDL> .compile envi5_extension_ex

Call RESOLVE_ALL to compile all dependencies:

IDL> resolve_all, /continue_on_error, skip_routines='envi'

The SKIP_ROUTINES keyword is set to ignore all ENVI routines, compiling only IDL routines. The ignored ENVI routines are supplied by ENVI when the extension is executed. Finally, with the SAVE procedure, dump all compiled routines from the IDL session to a file:

IDL> save, /routines, filename='envi5_extension_ex.sav'

The resulting IDL SAVE file envi5_extension_ex.sav can be dropped into one of the extension directories described above. On startup, ENVI will find the file, unpack the extension contained within it, and display it in the Toolbox. This works in both ENVI and ENVI+IDL! Grab the source code and SAVE file for this example here. Update: I modified the call to RESOLVE_ALL above to include the SKIP_ROUTINES keyword on advice from Adam O'Connor (thanks, Adam!); this not only prevents any ENVI routines from being included in the SAVE file, but also makes the SAVE file agnostic to the ENVI version.

Please login or register to post comments.