2

I have a number of Landsat geotiff (*.TIF) file in a folder. The problem is simple, I need to search certain Landsat bands from that list and make a composite tif image. I am using Orfeo Toolbox's CLI utility. So far I have this

import os
dir = "C:\Documents and Settings\Landsat_image"
def fileList():
    for root, dirnames, filenames in os.walk(dir):
        for tifFile in filenames:
            for i in range(3):
                if tifFile.find('B' + str(i)) != -1 and tifFile.endswith('.TIF'):
                    inputImages = os.path.join(dir, tifFile)
                    outputImages = os.path.join(root, tifFile) + '_concat.tif'
                    process = os.system(
                    'otbcli_ConcatenateImages -il %s -out %s' % (inputImages, outputImages))
print fileList()

The otbcli_ConcatenateImages needs the inputs in following format

otbcli_ConcatenateImages -il GomaAvant.png GomaApres.png -out otbConcatenateImages.tif

But maybe it is getting multiple entries for out.

ERROR: Invalid number of value for: "out", invalid number of values 4

I know the problem is silly but I am still a noob.

4
  • 1
    Can you please explain what "concatenating" the bands does and which bands you combine? I'm guessing you are working in a folder containing the different bands of a single scene?
    – Kersten
    Oct 2, 2015 at 19:12
  • 1
    'Concatenating' is Orfeo's version of layer stacking. Yes the folder contains Landsat bands of same scene some of which I don't need.
    – blu_sr
    Oct 2, 2015 at 19:16
  • Is using GDAL an option? It is the most widely used Python API for such cases and also provides command line tools like gdalbuildvrt and gdal_merge (both with the -separate flag) that would do exactly what you are looking for.
    – Kersten
    Oct 3, 2015 at 6:37
  • I know OTB will eventually come back to GDAL at some point, but I am tempted to use Python's batch processing capability with it.
    – blu_sr
    Oct 3, 2015 at 6:45

3 Answers 3

2

I think the issue is in the following line:

outputImages = os.path.join(root, tifFile) + '_concat.tif'

which returns something like: path/to/the/tifFile.tif_concat.tif

Instead, you need to strip the extension from the original file:

outputImages = os.path.join(root, tifFile)[:-4] + '_concat.tif'

EDIT based on the comment: It looks you need to provide a list of input files and a single output file. In that case, change the code as following to create a list of input files in the loop but execute the command outside the loop:

import os
dir = "C:\Documents and Settings\Landsat_image"
def fileList():
    inputImages = []
    for root, dirnames, filenames in os.walk(dir):
        for tifFile in filenames:
            for i in range(3):
                if tifFile.find('B' + str(i)) != -1 and tifFile.endswith('.TIF'):
                    inputImages.append(os.path.join(dir, tifFile))
    outputImages = inputImages[0][:-4] + '_concat.tif'
    process = os.system(
    'otbcli_ConcatenateImages -il %s -out %s' % (inputImages, outputImages))
3
  • 3
    The canonical way to strip extensions is to use os.path.splitext(path)[0]. Hardcoding fails when the extension changes (see TIFF vs TIF, JPEG vs JPG, etc.)
    – Paul
    Oct 2, 2015 at 22:01
  • Thanks for the answer but the error still remains. How can I make one result for outputImages instead of many?
    – blu_sr
    Oct 3, 2015 at 5:13
  • @Paul - agreed, but in the above case in the if statement the extension was hardcoded ('.TIF') therefore stripping the last four characters was safe.
    – Matej
    Oct 4, 2015 at 12:48
1

If I understand you correctly you are trying to stack the first three bands of a Landsat scene into a single GeoTiff, as they are delivered as one file per band.

Here's an alternative to os.walk to get those files using glob. Since their filenames start with the band number we can just split the sorted list to the first 3 entries.

import os
import glob

landsat_dir = C:\Documents and Settings\Landsat_image'
file_list = sorted(glob.glob(os.path.join(landsat_dir, "*.tif")))[:3]

Now you can use GDAL to stack these into a single GeoTiff. One way would be to use the command line tools, gdal_merge.py in this case.

import subprocess

merge_cmd = ["gdal_merge.py", "-o", "stacked-output.tif", "-separate", file_list[0], file_list[1], file_list[2]]
subprocess.call(merge_cmd)
0

Thanks Kersten and Matej for you help. After deliberate attempt my code seem not to behave correctly. So I had to rewrite completely and came up with this,

import os
import glob

def concatLandsat(dir):
    band = 3  # The number of desired bands goes here
    inputTif = sorted(glob.glob(os.path.join(dir, "*.TIF")))[:band]
    # Here I had to separate each string with white-space and put double quote around each
    inputImages = ' '.join('"' + x + '"' for x in inputTif)
    # Took the first image name (LT51370432006355BKT00_B1.TIF) so that I know it later
    outputImages = os.path.join(dir, inputTif[0])[:-7] + "_concat.tif"

    os.system('otbcli_ConcatenateImages -il %s -out "%s"' % (inputImages, outputImages))
    return

folderName = r"C:\Documents and Settings\Landsat_image"
concatLandsat(folderName)
4
  • os.system is deprecated in favour of subprocess methods. subprocess.call for instance would solve your outputimages formating, since it takes a list and adds the spaces accordingly.
    – Kersten
    Oct 3, 2015 at 13:10
  • the link says it's old but still not deprecated. Replacement will not be a problem though.
    – blu_sr
    Oct 3, 2015 at 14:00
  • does that work as expected?
    – Matej
    Oct 4, 2015 at 12:33
  • yes it did. Now I am testing samilar code for other tools of OTB and RSGISLIB
    – blu_sr
    Oct 5, 2015 at 6:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.