[INTERNAL] How to programmatically subset an image using multiple ROIs in ENVI Classic
Anonym
Topic:
This article discusses how to programmatically create spatial subsets of an image using multiple ROIs when working with ENVI Classic. Working example code is provided.
Discussion:
Programmatically creating spatial subsets of an image using ROIs in ENVI is unfortunately not very straightforward. There are a few steps that should be followed in order for it to work properly:
1) Provide an input file, an associated ROI file, and an output path for the subsets.
2) Make sure that any ROIs currently loaded are removed from the ENVI session prior to restoring the selected ROI file.
3) Retrieve the ID for an ROI, then calculate its minimum and maximum extents (upper left and lower right corners) in image coordinates. This is done by (A) retrieving the one-dimensional address of every pixel in the ROI using ENVI_GET_ROI(), (B) dividing this address by the number of samples in the entire image to obtain the Y location of each pixel, and (C) dividing this address by the number of samples in the entire image and capturing the remainder using the MOD operator to obtain the X location of each pixel.
4) Use IDL's MIN and MAX functions on the X and Y pixel locations to create an ENVI DIMS array [-1, min x, max x, min y, max y], then pass this array to the CF_DOIT routine in order to subset the image. Make sure to specify the image bands to be subsetted as well using the POS keyword.Solution:
pro create_subsets_from_rois
compile_opt idl2
;Select image file, associated ROI file, and specify output location for subsets
input_file = envi_pickfile(title='Select Input File')
roi_file = envi_pickfile(filter='*.roi', title='Select Associated ROI File')
subset_path = envi_pickfile(title='Select Output Location for Subsets', /directory)
;Get rid of any ROIs currently loaded in ENVI
envi_delete_rois, /all
;Open image file and load associated ROIs
envi_open_file, input_file, r_fid=input_fid
envi_restore_rois, roi_file
;Find out file name and how many bands of data are present
envi_file_query, input_fid, nb=num_bands, fname=filename, $
ns=num_samples, nl=num_lines
;Get unique IDs and names for all of the ROIs
roi_info = envi_get_roi_ids(fid=input_fid, roi_names=names, /short_name)
;Save subset via an ROI
for i=0, n_elements(roi_info)-1 do begin
roi_subset = envi_get_roi(roi_info[i])
roi_samples = lon64arr(n_elements(roi_subset))
roi_lines = lon64arr(n_elements(roi_subset))
for j=0, n_elements(roi_subset)-1 do begin
roi_samples[j] = roi_subset[j] mod num_samples
roi_lines[j] = roi_subset[j]/num_samples
endfor
x_start = min(roi_samples)
x_stop = max(roi_samples)
y_start = min(roi_lines)
y_stop = max(roi_lines)
subset = [-1, x_start, x_stop, y_start, y_stop]
subset_name = subset_path + path_sep()+ file_basename(input_file) + '_' + 'Subset' + '_' + strtrim(names[i], 2) + '.img'
envi_doit, 'cf_doit', dims=subset, fid=input_fid, pos=lindgen(num_bands), $
out_name=subset_name
endfor
end
Company Confidential - Reviewed by CS 8/25/2014