# pansharpcomp.sml # Sample script that illustrates the use of a complex custom # dialog window constructed using an XML dialog specification. # The script computes a pan-sharpened color-composite # image from three bands of a multispectral image and a # higher-resolution panchromatic image. # If the Apply Contrast option is selected for an input raster, # the last-used contrast table is used to make a contrast-adjusted # temporary raster for further processing. Perform necessary # contrast enhancements for the input rasters and save contrast # tables before running the script. # Randy Smith # MicroImages, Inc. # 12 June, 2003 ################################################################### ########## Global Class Declarations ############################## ################################################################### class XMLDOC dlgdoc; # class instance for the XML document class XMLNODE pscdlgnode; # class instance for the node in the XML # document corresponding to the dialog class GUI_DLG pscdialog; # class instance for the GUI dialog class GUI_FORMDATA data; # class instance for retrieved dialog settings ################################################################### ########## Global Variable Declarations ########################### ################################################################### string xml$; # string containing the XML text with the dialog specification numeric err; # value returned by the class method that reads and parses # the XML text numeric ret; # value returned by the class method that opens dialog numeric numlinsP; # number of lines in panchromatic raster numeric numcolsP; # number of columns in panchromatic raster string datatypeP$; # data type of panchromatic raster raster RedCon, GreenCon, BlueCon, PanCon; # temporary rasters for # contrast-enhanced bands raster RedRsp, GreenRsp, BlueRsp; # temporary rasters for resampled # RGB components string method$; # color blending method from dialog listbox; ### variables for color conversion raster RedSharp, GreenSharp, BlueSharp; # temporary rasters for pan-sharpened color components numeric r, g, b, p; # values of red, green, blue, and pan components for current cell numeric h, i, s; # values of hue, intensity, and saturation for current cell (from r, g, b) numeric br; # brightness value for current cell in HBS color model (from r, g, b) numeric scale; # scale factor for Brovey transform ### variables for color composite numeric bdepth; # desired bit depth of output composite from dialog: 24, 16, or 8 string compdatatype$; # string with datatype of composite raster raster Comp; # output raster for color composite numeric compobjnum; # object number of output composite raster string compfilename$; # filename, object name, and object descriptions string compobjname$; # for output composite raster string compobjdescr$; ################################################################## ####################### Procedures ############################### ################################################################## ########################################## # procedure to initially disable OK button # on main dialog window when it opens ########################################## proc OnOpenDlg () { pscdialog.SetOkEnabled( 0 ); } ########################################## # procedure to select band and write its filename / object name # to the dialog (in edittext field) ########################################## proc GetBand(raster Band, string id$) { local string filename$, objname$, dlgtext$; local numeric objnum; GetInputRaster( Band, 0, 0, "8-bit unsigned" ); filename$ = GetObjectFileName( Band ); objnum = GetObjectNumber( Band ); objname$ = GetObjectName( filename$, objnum ); dlgtext$ = sprintf( "%s.%s / %s", FileNameGetName(filename$), FileNameGetExt(filename$), objname$ ); pscdialog.SetCtrlValueStr( id$, dlgtext$ ); } # end proc GetBand() ########################################### # callback procedure for the Red... pushbutton; prompts user to # select the Red color component ########################################### proc SelectRed () { class Raster Red; GetBand( Red, "rname" ); pscdialog.GetCtrlByID( "conred" ).SetEnabled( 1 ); pscdialog.GetCtrlByID( "getg" ).SetEnabled( 1 ); } # end proc SelectRed() ############################################### # callback procedure for the Green... pushbutton; prompts user to # select the Green color component ############################################### proc SelectGreen () { class Raster Green; GetBand( Green, "gname" ); pscdialog.GetCtrlByID( "congrn" ).SetEnabled( 1 ); pscdialog.GetCtrlByID( "getb" ).SetEnabled( 1 ); } # end proc SelectGreen() ############################################### # callback procedure for the Blue... pushbutton; prompts user to # select the Blue color component ############################################### proc SelectBlue () { class Raster Blue; GetBand( Blue, "bname" ); pscdialog.GetCtrlByID( "conblue" ).SetEnabled( 1 ); pscdialog.GetCtrlByID( "getp" ).SetEnabled( 1 ); } # end proc SelectBlue() ################################################ # callback procedure for the Intensity... pushbutton; prompts user to # select the Intensity component ################################################ proc SelectPan () { class Raster Pan; GetBand( Pan, "pname" ); pscdialog.GetCtrlByID( "conpan" ).SetEnabled( 1 ); pscdialog.SetOkEnabled( 1 ); } # end proc SelectPan() ################################################# # callback procedure for the OK button on the dialog # to retrieve the dialog settings and store in GUI_FORMDATA ################################################# proc GetValues () { data = pscdialog.GetValues(); } ################################################# ################################################# ############## Main Program ##################### ################################################# ################################################# clear(); $warnings 3; ################################################# # create string variable with XML specification for control dialog ################################################# xml$=' HIS HBS Brovey 24-bit 16-bit '; ############################################## ### parse XML text for the dialog into memory; ### return an error code (number < 0 ) if there are syntax errors ############################################## err = dlgdoc.Parse(xml$); if ( err < 0 ) { PopupError( err ); # Popup an error dialog. "Details" button shows syntax errors. Exit(); } ################################################ # get the dialog element from the parsed XML document and # show error message if the dialog element can't be found ################################################ pscdlgnode = dlgdoc.GetElementByID("psc"); if ( pscdlgnode == 0 ) { PopupMessage("Could not find dialog node in XML document"); Exit(); } ################################################ # Set the XML dialog element as the source for the GUI_DLG class instance # we are using for the dialog window. ################################################ pscdialog.SetXMLNode(pscdlgnode); ret = pscdialog.DoModal(); if ( ret == -1 ) { # exit script if Cancel button on dialog is pressed Exit(); } ################################################# ### Get the output raster for the composite ################################################# ### Get setting for composite bit-depth bdepth = data.GetValueNum( "comp" ); # printf( "bit-depth = %d\n", bdepth); if ( bdepth == 24 ) then compdatatype$ = "24-bit color RGB"; else compdatatype$ = "16-bit color RGB"; ### Get the output raster numlinsP = NumLins( Pan ); numcolsP = NumCols( Pan ); GetOutputRaster( Comp, numlinsP, numcolsP, compdatatype$ ); ############################################## ### apply contrast tables if requested ############################################## printf( "Applying contrast if requested...\n\n" ); datatypeP$ = RastType( Pan ); CreateTempRaster( RedCon, NumLins( Red ), NumCols( Red ), RastType( Red ) ); CreateTempRaster( GreenCon, NumLins( Green ), NumCols( Green ), RastType( Green ) ); CreateTempRaster( BlueCon, NumLins( Blue ), NumCols( Blue ), RastType( Blue ) ); CreateTempRaster( PanCon, numlinsP, numcolsP, datatypeP$ ); if ( data.GetValueStr( "conred" ) == "yes" ) then RasterApplyContrast2( Red, RedCon, "Subobject" ); else RedCon = Red; CopySubobjects(Red, RedCon, "GEOREF" ); if ( data.GetValueStr( "congrn" ) == "yes" ) then RasterApplyContrast2( Green, GreenCon, "Subobject" ); else GreenCon = Green; CopySubobjects( Green, GreenCon, "GEOREF" ); if ( data.GetValueStr( "conblue" ) == "yes" ) then RasterApplyContrast2( Blue, BlueCon, "Subobject" ); else BlueCon = Blue; CopySubobjects( Blue, BlueCon, "GEOREF" ); if ( data.GetValueStr( "conpan" ) == "yes" ) then RasterApplyContrast2( Pan, PanCon, "Subobject" ); else PanCon = Pan; ################################################### ### resample RGB rasters to match the Panchromatic band ################################################### printf( "Resampling RGB rasters to match Pan... \n\n" ); # create temporary rasters for resampled RedCon, GreenCon, and BlueCon CreateTempRaster( RedRsp, numlinsP, numcolsP, datatypeP$ ); CreateTempRaster( GreenRsp, numlinsP, numcolsP, datatypeP$ ); CreateTempRaster( BlueRsp, numlinsP, numcolsP, datatypeP$ ); ResampleRasterToMatch( RedCon, Pan, RedRsp, "planeproj", "bilinear" ); ResampleRasterToMatch( GreenCon, Pan, GreenRsp, "planeproj", "bilinear" ); ResampleRasterToMatch( BlueCon, Pan, BlueRsp, "planeproj", "bilinear" ); DeleteTempRaster( RedCon ); # delete the temporary rasters for contrast-enhanced DeleteTempRaster( GreenCon ); # RGB bands DeleteTempRaster( BlueCon ); ############################################### ### Do the color adjustments to make sharpened ### red, green, and blue components ############################################### printf( "Performing color conversion...\n\n" ); CreateTempRaster( RedSharp, numlinsP, numcolsP, datatypeP$ ); CreateTempRaster( GreenSharp, numlinsP, numcolsP, datatypeP$ ); CreateTempRaster( BlueSharp, numlinsP, numcolsP, datatypeP$ ); ### check dialog settings for selected color conversion method method$ = data.GetValueStr( "method" ); if ( method$ == "HIS" ) { # convert RGB to HIS, swap P for I, # then convert back to RGB for each RedRsp { r = RedRsp; g = GreenRsp; b = BlueRsp; p = PanCon / 2.55; # scales to intensity range 0-100 # expected by color conversion functions ConvertRGBtoHIS( 254, r, g, b, h, i, s ); ConvertHIStoRGB( 254, h, p, s, r, g, b ); RedSharp = r; GreenSharp = g; BlueSharp = b; } } else if (method$ == "HBS" ) { # convert RGB to HBS, swap P for Brightness, # then convert back to RGB for each RedRsp { r = RedRsp; g = GreenRsp; b = BlueRsp; p = PanCon / 2.55; # scales to intensity range 0-100 # expected by color conversion functions ConvertRGBtoHBS( r, g, b, h, br, s ); ConvertHBStoRGB( h, p, s, r, g, b ); RedSharp = r; GreenSharp = g; BlueSharp = b; } } else { # do Brovey transform for each RedRsp { r = RedRsp; g = GreenRsp; b = BlueRsp; p = PanCon; scale = 3 * p / ( r + g + b + 1 ); RedSharp = r * scale; GreenSharp = g * scale; BlueSharp = b * scale; } } DeleteTempRaster( RedRsp ); DeleteTempRaster( GreenRsp ); DeleteTempRaster( BlueRsp ); ############################################### ### Make the output composite ############################################### printf( "Making the output composite...\n\n" ); ######### ### Get info on the output raster for composite compfilename$ = GetObjectFileName( Comp ); compobjnum = GetObjectNumber( Comp ); compobjname$ = GetObjectName( compfilename$, compobjnum ); compobjdescr$ = GetObjectDescription( compfilename$, compobjnum ); # Delete the Comp object because the stupid RasterRGBToComposite # function wants to make its own; we will just use the names # obtained from the GetOutputRaster dialog DeleteObject( compfilename$, compobjnum ); ################### ### Make output composite RasterRGBToComposite( RedSharp, GreenSharp, BlueSharp, Comp, compfilename$, compobjname$, compobjdescr$, bdepth ); CopySubobjects(Pan, Comp, "GEOREF"); CreatePyramid(Comp); printf( "Done." );