Friday, November 22, 2013

Image Classification with Numpy and GDAL

Editor's Note:  This post is published with permission from Packt Publishing and originally published in my book. 

Automated Remote Sensing ( ARS ) is rarely ever done in the visible spectrum. The most commonly available wavelengths outside of the visible spectrum are infrared and near-infrared. The following scene is a thermal image (band 10) from a fairly recent Landsat 8 flyover of the US Gulf Coast from New Orleans, Louisiana to Mobile, Alabama. Major natural features in the image are labeled so you can orient yourself:

Because every pixel in that image has a reflectance value, it is information. Python can "see" those values and pick out features the same way we intuitively do by grouping related pixel values. We can colorize pixels based on their relation to each other to simplify the image and view related features. This technique is called classification. Classifying can range from fairly simple groupings based only on some value distribution algorithm derived from the histogram to complex methods involving training data sets and even computer learning and artificial intelligence. The simplest forms are called unsupervised classifications, whereas methods involving some sort of training data to guide the computer are called supervised. It should be noted that classification techniques are used across many fields, from medical doctors trying to spot cancerous cells in a patient's body scan, to casinos using facial-recognition software on security videos to automatically spot known con-artists at blackjack tables.
To introduce remote sensing classification we'll just use the histogram to group pixels with similar colors and intensities and see what we get. First you'll need to download the Landsat 8 scene here:
Instead of our histogram() function from previous examples, we'll use the version included with NumPy that allows you to easily specify a number of bins and returns two arrays with the frequency as well as the ranges of the bin values. We'll use the second array with the ranges as our class definitions for the image. The lut or look-up table is an arbitrary color palette used to assign colors to classes. You can use any colors you want.
Note: In the following code we use the gdalnumeric module which allows Numpy and GDAL to work together.  GDAL reads compatible image/data formats and converts them to Numpy arrays.  The Numpy module was formerly called Numeric. 
import gdalnumeric

# Input file name (thermal image)
src = "thermal.tif"

# Output file name
tgt = "classified.jpg"

# Load the image into numpy using gdal
srcArr = gdalnumeric.LoadFile(src)

# Split the histogram into 20 bins as our classes
classes = gdalnumeric.numpy.histogram(srcArr, bins=20)[1]

# Color look-up table (LUT) - must be len(classes)+1.
# Specified as R,G,B tuples 
lut = [[255,0,0],[191,48,48],[166,0,0],[255,64,64],
\ [0,133,0],[57,230,57],[103,230,103],[184,138,0]]

# Starting value for classification
start = 1

# Set up the RGB color JPEG output image
rgb = gdalnumeric.numpy.zeros((3, srcArr.shape[0],
srcArr.shape[1],), gdalnumeric.numpy.float32)
# Process all classes and assign colors
for i in range(len(classes)):
    mask = gdalnumeric.numpy.logical_and(start <= \
 srcArr, srcArr <= classes[i])
    for j in range(len(lut[i])):
      rgb[j] = gdalnumeric.numpy.choose(mask, (rgb[j], \ 
    start = classes[i]+1 

# Save the image    
gdalnumeric.SaveArray(rgb.astype(gdalnumeric.numpy.uint8), \
tgt, format="JPEG")

The following image is our classification output, which we just saved as a JPEG. We didn't specify the prototype argument when saving as an image, so it has no georeferencing information:

This result isn't bad for a very simple unsupervised classification. The islands and coastal flats show up as different shades of green. The clouds were isolated as shades of orange and dark blues. We did have some confusion inland where the land features were colored the same as the Gulf of Mexico. We could further refine this process by defining the class ranges manually instead of just using the histogram.


  1. Thank you both for sharing Holy Mass with us each day FNAF Sister Location Juegos Friv Friv 2018 to make yourselves available Friv Twizl Jeux De Twizl Juegos De FNAF Sister Location when we were called out late at night and any other time and for your support and encouragement in every respect. Juegos Friv 2021 Juegos Twizl Juegos Yepi 2017

  2. Danke, dafur dass Ihr jeden Tag mit uns die Hl. Messe gefeiert habt, fur all die Reparaturen im ganzen Haus Jeux De Friv Jogos Friv Jogos Friv fur Euere Bereitschaft Juegos Friv Juegos Friv Juegos De Friv immer zur Verfugung zu stehen Juegos Geometry Dash Juegos Twizl Twizy Twizl Danke, dass Sie Ihr Muhen um den Aufbau des Leibes Christi mit uns teilten.

  3. A todos que partilham e trabalham sob estas mesmas convicções e princípios Friv Friv 360 Friv4school 2020 Senhor Deputado Cashman, agradeço-lhe a informação. Jeux De Friv 2018 Juegos De Roblox Juegos De Zoxy Mais uma vez, obrigada ao Parlamento por comungar da visão que informa a nova política dos consumidores Juegos Kizi 2017 Juegos Yepi 2017 Twizl 3 Zoxy 2 assente no mercado - a visão de um mercado de consumidores informados e capacitados que procuram e usufruem, com confiança,

  4. Very nice. Posts shared useful information and meaningful life, I'm glad to be reading this article and hope to soon learn the next article. thank you
    a10 games
    g9g games
    4223 games
    yoob games
    hopy games
    huz 10 games
    kizi hot
    kizi new games
    yepi games

  5. Wir danken Ihnen Friv4school 2018 Gry Friv 2 Gry Friv 5 dass Sie diese Hoffnung mit uns teilen und diesen Schritt auf dem Pilgerweg des Vertrauens Gry Friv Juegos Friv 100 Juegos Friv 1000 mit uns gegangen sind. Juegos Friv 5 Juegos De Friv 2 Juegos Friv 250 Juegos Yepi wir danken Ihnen für das Interesse an unseren Produkten und hoffe