Geospatial Image Processing¶
This section provides some basic recipes for image processing with Geomatica’s python functions. Included in this section are recipes for pansharpening and atmospheric correction.
Pansharpen satellite images¶
This recipe provides a simple way to pansharpen the multispectral and panchromatic bands of a satellite image. Specifically, this recipe is pansharpening Landsat-8 ortho images downloaded directly from the Earth Explorer website: https://earthexplorer.usgs.gov/
Note: the images must be coregistered
from pci.pansharp2 import pansharp2 ms_file = r"C:\landsat8\LC80150292013111LGN01\LC80150292013111LGN01_MTL.txt-MS" pan_file = r"C:\landsat8\LC80150292013111LGN01\LC80150292013111LGN01_MTL.txt-PAN" pansharp_file = r"C:\landsat8\pansharp\psh_landsat8.pix" pansharp2(fili=ms_file, fili_pan=pan_file, filo=pansharp_file)
Pansharpen satellite images - Batch Processing¶
This recipe provides a simple way to batch pansharpen a directory of Landsat Images. Full Tutorial: https://support.pcigeomatics.com/hc/en-us/articles/207707003-Creating-a-Batch-Workflow-Pansharpening-
from pci.pansharp2 import pansharp2 from pci.exceptions import * import os import fnmatch # Set the working directory working_dir = r'I:\Data\Sensors\Landsat8' output_dir = os.path.join(working_dir, 'Pan_Images') if not os.path.isdir(output_dir): os.mkdir(output_dir) input_files = [] for r, d, f in os.walk(working_dir): for inFile in fnmatch.filter(f, '*_MTL.txt'): input_files.append(os.path.join(r, inFile)) # Iterate through list of files and run for image in input_files: try: pansharp2(fili='-'.join([image, 'MS']), fili_pan='-'.join([image, 'PAN']), filo=os.path.join(output_dir, '.'.join([os.path.basename(image).split('_MTL')[0], 'pix']))) except PCIException, e: print e except Exception, e: print e
Level 2 to Level 3 Airphoto Processing (Pansharpening)¶
This recipe provides a simple way to pansharpen level 2 aerial imagery in order to convert it to level 3 imagery.
from pci.ihr import ihr from pci.link import link from pci.setpro2 import setpro2 from pci.pansharp2 import pansharp2 from pci.fexport import fexport #create pix live link file for MS and PAN images pan_level2 = r"E:\Esri_cloud_Aerial\demo_DryRun\Level2\00025\Lvl02-00025-Pan.tif" pan_link = r"E:\Esri_cloud_Aerial\demo_DryRun\working\Lvl02-00025-Pan.pix" link(fili=pan_level2, filo=pan_link) ms_level2 = r"E:\Esri_cloud_Aerial\demo_DryRun\Level2\00025\Lvl02-00025-Col.tif" ms_link = r"E:\Esri_cloud_Aerial\demo_DryRun\working\Lvl02-00025-Col.pix" link(fili=ms_level2, filo=ms_link) #get extents of pan image header_info = [] ihr(file=pan_link, imstat=header_info) '''ihr returns the extents of the imagery to the output list 'header_info': header_info[11] = Upper Left X header_info[12] = Upper Left Y header_info[13] = Lower Right X header_info[14] = Lower Right Y''' #set meter projection for pan (have to flip the ULY and LRY values for meter projection setpro2(file=pan_link, project="METRE", llbound="N", ulx=str(header_info[11]), uly=str(header_info[14]), lrx=str(header_info[13]), lry=str(header_info[12])) #set meter projection for MS image (use same extents as PAN image and change resolution). Using same values setpro2(file=ms_link, project="METRE", llbound="N", ulx=str(header_info[11]), uly=str(header_info[14]), lrx=str(header_info[13]), lry=str(header_info[12])) #run Pansharp2 on MS and PAN imagery level3_image = r"E:\Esri_cloud_Aerial\demo_DryRun\output_level3\00025-PSH.pix" pansharp2(fili=ms_link, dbic=[1,2,3,4], dbic_ref=[1,2,3,4], fili_pan=pan_link, dbic_pan=[1], filo=level3_image) #set Level3 (pansharpened image) back to pixel projection (no projection) setpro2(file=level3_image, project="PIXEL", llbound="N", ulx=str(header_info[11]), uly=str(header_info[12]), lrx=str(header_info[13]), lry=str(header_info[14])) #optionally convert it to a TIF image level3_image_tif = r"E:\Esri_cloud_Aerial\demo_DryRun\output_level3\00025-PSH.tif" fexport(fili=level3_image, filo=level3_image_tif, dbic=[1,2,3,4], ftype="TIF")
Cloud Masking & Haze Removal with optional Atmospheric Correction¶
This recipe outlines an ATCOR workflow. Depending on your requirements, you can simply run masking and hazerem to produce a haze free image.
import os from pci.masking import masking from pci.hazerem import hazerem from pci.atcor import atcor from pci.tersetup import tersetup from pci.illumcast import illumcast working_dir = r'C:\ATCOR\Landsat8' ms_image = os.path.join(working_dir, 'Raw', 'LC80180302014247LGN00_MTL.txt-MS') dem = os.path.join(working_dir, 'DEM', 'dem_30m.pix') output_dir = r'C:\ATCOR\Mask_Haze_Atcor' masks = os.path.join(output_dir, "LC80090272016206LGN00-Masks.pix") hazefree_ms = os.path.join(output_dir, 'LC80090272016206LGN00_MS_HazeFree.pix') ter_file = os.path.join(output_dir, 'dem_30m_Tersetup.pix') illum_file = os.path.join(output_dir, 'dem_30m_Illumcast.pix') atcor_ms = os.path.join(output_dir, 'LC80090272016206LGN00_MS_Atcor.pix') # Create cloud, water and haze masks masking(fili=ms_image, hazecov=[50], clthresh=[18, 22, 1], filo=masks) # Remove the haze from both the multispectral and panchromatic bands hazerem(fili=ms_image, maskfili=masks, hazecov=[50], filo=hazefree_ms) # Calculate the slope, aspect, and skyview rasters in preparation for atmospheric correction tersetup(filedem=dem, terfile=ter_file) illumcast(fili=ter_file, filref=ms_image, filo=illum_file) # Calculate atmospheric correction for multispectral image. atcor(fili=hazefree_ms, maskfili=masks, terfile=ter_file, illufile=illum_file, atmdef="rural", atmcond="Fall", outunits="Percent_Reflectance", filo=atcor_ms)
Calculate Top-of-atmosphere (TOA) Reflectance image¶
This recipe performs a top-of-atmosphere (TOA) calculation for satellite imagery. The output image is a TOA reflectance image, where pixels will be provided a value between 0 and 100%.
from pci.dn2toa import dn2toa #Run Top of Atmosphere Reflectance computation raw_dn_image = r"D:\K3_20131003174133_07365_20171339_L1R_Bundle\K3_20131003174133_07365_20171339_L1R_Aux.xml-MS" channels = [1,2,3,4] toa_image = r"D:\K3\toa\kompsat3_toa.pix" dn2toa(fili=raw_dn_image, dbic=channels, outunits="Percent_Reflectance", filo=toa_image)