SPLIT MULTISPECTRAL RASTER INTO SINGLE BAND RASTERS USING GDAL

Raster images may have a single band or multiple bands (multi-spectral). For example DEM files are always single band. True color satellite imageries are multi-spectral which general have red, green and blue bands. Some images may have thermal bands depending on the band of electromagnetic spectrum in which they are exposed. LandSat images more than 8 bands which can be used for different study area like foliage/vegetation/forest.

In this blog, I will share a java code for splitting the multi-spectral image into several single band images using gdal.

Multi-spectral raster
A multi-spectral image

The above image is a multi-spectral bluemarbel image which has red, green and blue bands. The following java code splits the above imagery and the result is as below:


package splitrasters;
import org.gdal.gdal.*;
import org.gdal.gdalconst.gdalconstConstants;

public class SplitBands {
    public static void main(String[] args) {
		//Register GDAL
        gdal.AllRegister();
		
		//Validate input raster and saving location arguments
        if(args.length<1 || args.length>2){
            System.out.println ("Please provide input image location as first argument and saving location as second argument/n"+
                    "eg: java -jar SplitBands.jar \"D:\\Area\\Clipped.tif\" \"D:\\OutputFolder\"");
            System.exit(1);
        }
		
        //Read Input raster
        Dataset dataset = gdal.Open(args[0], gdalconstConstants.GA_ReadOnly);
		
		//Copy Image Format
		String imgFormat = args[0].substring(args[0].lastIndexOf("."));
		
        if (dataset==null){
            System.out.println ("Could not open image file");
            System.exit(1);
        }
		
        //Count number of Raster Bands
        int cBand = dataset.GetRasterCount();
		
        //Create a BandMap as array
        int[] iBandMap = new int[cBand];
        for(int b=0; b<cBand;){
            iBandMap[b] = ++b;
        }
		
        //Count number of pixels along and width and height of raster
        int rows = dataset.GetRasterXSize();
        int cols = dataset.GetRasterYSize();
		
        //Count total number of input raster pixels
        int totalpixelperband = cols*rows;
		
        //Get raster projection
        String proj = dataset.GetProjection();
		
        //Create a float array for input raster pixel values
        byte[] regularArrayIn = new byte[cBand*totalpixelperband];
		
        //Create a 2-d float array to save the pixel values of each band of input ratser
        byte[][] regularArrayOut = new byte[cBand][totalpixelperband];
		
        //Read the input raster and save pixel values in float arrayregularArrayIn for all bands
        dataset.ReadRaster(0, 0, rows, cols, rows, cols, gdalconstConstants.GDT_Byte, regularArrayIn, iBandMap);
		
        // Save the input raster geo-information
        double[] geo = dataset.GetGeoTransform();

        //System.out.println("Input raster dimension : "+rows+" x "+cols+" = "+totalpixelperband);
        
       //Save pixel values of rasters from arrayregularArrayIn to each regularArrayOut array
        for(int i=0; i<regularArrayIn.length; i++){
            for (int j=0; j<cBand; j++){
                if(i>=(totalpixelperband*j) && i&th;(totalpixelperband*(j+1))){
                    regularArrayOut[j][i-(totalpixelperband*j)] = regularArrayIn[i];
                }
            }
        }
		
        // Get driver of input raster for creating output raster
        Driver driver = dataset.GetDriver();
		
        //for each regularArrayOut array, create a separate raster file using the above driver
        for(int x = 0; x<cBand; x++){
			
            //Create a blank single band raster with same dimension as input raster
            Dataset outDs = driver.Create(args[1]+"/Band"+x+imgFormat, rows, cols, 1,  gdalconstConstants.GDT_Byte);
			
            //provide same geo-information as the input raster
            outDs.SetGeoTransform(geo);
			
            //provide same projection as the input raster
            outDs.SetProjection(proj);
			
            //write pixel values from regularArrayOut array for each band
            outDs.WriteRaster(0, 0, rows, cols, rows, cols, gdalconstConstants.GDT_Byte, regularArrayOut[x], new int[]{1});
            outDs.FlushCache();
        }
     dataset.delete();
    }
}

Red Band
Red Band
Green Band
Green Band
Blue Band
Blue Band

The above code is valid for 8-bit raster image which has byte radiometry. for Int16/UInt16/Float32/Float64 radiometry use appropriate gdalconstConstants for reading and writing rasters.

QUICK LINKS
Coordinates

Earth Shape

Ellipsoid & Geoid

Datum

Projection

UTM

Rasters

Vectors
GDAL

GDAL Setup

GDAL Rasters

GDAL Vectors

GDAL Tools
WMS

MS4W

Spatial DB

Oracle Spatial

SDO_GEOMETRY

Geo-Crawler
Web Clients

Openlayers

OL3

Closest Distance Map

Openlayers v2.x

ThreeJS

Terrain Viewer

Bluemarble (250m tiff)

JS Tools

Geographiclib

JS2Shapefile

CSV2Shape


GeoSpatialEarth.in Copyright © All rights reserved.