├── .gitattributes
├── .gitignore
├── License.md
├── OriginalImage.JPG
├── Readme.md
├── SatelliteClassification.java
├── SplitTrainingAndTesting.R
├── afterFilter.JPG
├── beforeFilter.JPG
├── ensemble_final.R
├── featureSelection.R
├── mlp.JPG
├── mlpf1.JPG
├── modeFilter.R
├── postProcessing_AllClasses.R
├── postProcessing_onlyWater.R
└── preprocessing_totalImage.R
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 |
7 | # Standard to msysgit
8 | *.doc diff=astextplain
9 | *.DOC diff=astextplain
10 | *.docx diff=astextplain
11 | *.DOCX diff=astextplain
12 | *.dot diff=astextplain
13 | *.DOT diff=astextplain
14 | *.pdf diff=astextplain
15 | *.PDF diff=astextplain
16 | *.rtf diff=astextplain
17 | *.RTF diff=astextplain
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Windows image file caches
2 | Thumbs.db
3 | ehthumbs.db
4 |
5 | # Folder config file
6 | Desktop.ini
7 |
8 | # Recycle Bin used on file shares
9 | $RECYCLE.BIN/
10 |
11 | # Windows Installer files
12 | *.cab
13 | *.msi
14 | *.msm
15 | *.msp
16 |
17 | # Windows shortcuts
18 | *.lnk
19 |
20 | # =========================
21 | # Operating System Files
22 | # =========================
23 |
24 | # OSX
25 | # =========================
26 |
27 | .DS_Store
28 | .AppleDouble
29 | .LSOverride
30 |
31 | # Thumbnails
32 | ._*
33 |
34 | # Files that might appear in the root of a volume
35 | .DocumentRevisions-V100
36 | .fseventsd
37 | .Spotlight-V100
38 | .TemporaryItems
39 | .Trashes
40 | .VolumeIcon.icns
41 |
42 | # Directories potentially created on remote AFP share
43 | .AppleDB
44 | .AppleDesktop
45 | Network Trash Folder
46 | Temporary Items
47 | .apdisk
48 |
--------------------------------------------------------------------------------
/License.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Krishna Karthik Gadiraju
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/OriginalImage.JPG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kkgadiraju/SatelliteImageClassification/2f5138bc85ab94cbe78d9aab16b8c3a810fce168/OriginalImage.JPG
--------------------------------------------------------------------------------
/Readme.md:
--------------------------------------------------------------------------------
1 | # SatelliteImageClassification
2 | Pixel based classification of satellite imagery
3 | - sample training and testing points generated using Point Sampling plugin in QGIS
4 | - feature generation using Orfeo Toolbox
5 | - feature selection using Learning Vector Quantization
6 | - CLassification using Decision Tree, Neural Networks, Random Forests, KNN and Naive Bayes Classifier
7 | - Ensemble classifier for Flood Inundation Mapping - classifies a pixel as water if 2 or more than 2 of the above classifiers classify a pixel as water
8 | - Mode filter used to remove individually wrongly classified pixels
9 | - Classification accuracy to measure goodness of each model
10 |
11 | Outcomes of the best classifier (Multi Layer Perceptron) are as shown below:
12 |
13 | To compile and run SatelliteClassification.java, you need weka.jar that you can download from the Weka website.
14 |
15 | ```
16 | Compile code: javac -cp weka.jar SatelliteClassification.java
17 | Run code: java -cp weka.jar:. SatelliteClassification "trainingFile" "testingFile" "classifiername"
18 | ```
19 |
20 | - order:
21 |
22 | |clouds: white |
23 | |roads: yellow |
24 | |shadow: black |
25 | |urban: pink |
26 | |vegetation: green |
27 | |water: blue |
28 |
29 |
30 |
31 |
32 | Original LANDSAT 8 Image during Flooding
33 | |
34 |
35 | Multi Layer Perceptron Classification
36 | |
37 |
38 |
39 |
40 |
41 | |
42 |
43 |
44 | |
45 |
46 |
47 | Ensemble Classifier: Water vs Everything, without filtering
48 | |
49 |
50 | Ensemble Classifier: Water vs Everything, after mode filtering
51 | |
52 |
53 |
54 |
55 |
56 | |
57 |
58 |
59 | |
60 |
61 |
62 |
63 |
64 |
65 | References:
66 | - LANDSAT-8 imagery(http://earthexplorer.usgs.gov/)
67 | - Image Preprocessing - QGIS (http://www.qgis.org/en/site/), ArcGIS (https://www.arcgis.com/features/index.html)
68 | - Feature selection performed using Orfeo Toolbox (https://www.orfeo-toolbox.org/)
69 | - Feature Selection: Vatsavai, Ranga Raju. "High-resolution urban image classification using extended features." In 2011 IEEE 11th International Conference on Data Mining Workshops, pp. 869-876. IEEE, 2011.
70 |
--------------------------------------------------------------------------------
/SatelliteClassification.java:
--------------------------------------------------------------------------------
1 | /*
2 | Krishna Karthik Gadiraju / kkgadiraju
3 | Classify satellite attributes using weka
4 | Source: Weka Home page and tutorials
5 |
6 | To compile this code: javac -cp path-to-your-weka.jar-file SatelliteClassification.java
7 | To run this code: java -cp weka.jar:. SatelliteClassification "may28-trainingTop10-AllBands-final.arff" "may28-testingTop10-AllBands-final.arff" "classifier-name"
8 |
9 | Tested java version: openjdk version "1.8.0_102"
10 | OpenJDK Runtime Environment (build 1.8.0_102-b14)
11 |
12 | Operating System: Red Hat Enterprise 7.2
13 |
14 | */
15 |
16 | import java.io.File;
17 | import java.io.FileNotFoundException;
18 | import weka.core.converters.CSVSaver;
19 | import weka.classifiers.Classifier;
20 | import weka.classifiers.Evaluation;
21 | import weka.classifiers.bayes.NaiveBayes;
22 | import weka.classifiers.trees.RandomForest;
23 | import weka.classifiers.trees.J48;
24 | import weka.classifiers.functions.MultilayerPerceptron;
25 | import weka.classifiers.lazy.IBk;
26 | import weka.core.Attribute;
27 | import weka.core.Instance;
28 | import weka.core.Instances;
29 | import weka.core.converters.ConverterUtils.DataSource;
30 |
31 |
32 |
33 | public class SatelliteClassification {
34 | public static void main(String[] args){
35 | DataSource training=null,testing=null;
36 | Instances trData=null, teData=null;
37 | if(args.length<3){
38 | System.out.println("Enter 2 paths and type of classifier (nBayes, j48, randomForest, knn or mlp) as command line arguments: training,testing");
39 | System.exit(0);
40 | }
41 | System.out.println("Training data source: "+args[0]);
42 | System.out.println("Testing data source: "+args[1]);
43 | System.out.println("Classifier type: "+args[2]);
44 | try {
45 | //link to files
46 | long startTime = System.nanoTime();
47 | training = new DataSource(args[0]);
48 | testing = new DataSource(args[1]);
49 | //read the file
50 | trData = training.getDataSet();
51 | teData = testing.getDataSet();
52 | System.out.println("Finished reading datasets.....");
53 | if(training!=null && testing!=null){
54 | System.out.println("Dataset structure.....");
55 | System.out.println(training.getStructure());
56 | System.out.println(testing.getStructure());
57 |
58 | //Set class attribute
59 | if (trData.classIndex() == -1)
60 | trData.setClassIndex(trData.numAttributes()-1);
61 | if (teData.classIndex() == -1)
62 | teData.setClassIndex(teData.numAttributes()-1);
63 | Classifier cModel;
64 | //Train classifiers
65 | switch(args[2]) {
66 | case "nbayes":
67 | cModel = (Classifier) new NaiveBayes();
68 | break;
69 | case "j48":
70 | cModel = (Classifier)new J48();
71 | break;
72 | case "randomForest":
73 | cModel = (Classifier)new RandomForest();
74 | break;
75 | case "mlp":
76 | cModel = (Classifier)new MultilayerPerceptron();
77 | break;
78 | case "knn":
79 | cModel = (Classifier)new IBk(10);
80 | break;
81 | default:
82 | System.out.println("Incompatible classifier name given, using Naive Bayes by default");
83 | cModel = (Classifier) new NaiveBayes(); //Set to naive bayes by default
84 |
85 | }
86 | cModel.buildClassifier(trData);
87 | // create copy
88 | Instances teResults = new Instances(teData);
89 | // label instances
90 | for (int i = 0; i < teResults.numInstances(); i++) {
91 | double clsLabel = cModel.classifyInstance(teData.instance(i));
92 | teResults.instance(i).setClassValue((int)clsLabel);
93 | }
94 |
95 | //write output to CSV
96 | CSVSaver outFile = new CSVSaver();
97 | outFile.setFile(new File(args[2]+".csv"));
98 | outFile.setInstances(teResults);
99 | outFile.writeBatch();
100 | long endTime = System.nanoTime();
101 | System.out.println("Finished execution in"+(endTime-startTime)/1000000+" seconds");
102 |
103 | }
104 | else{
105 | System.out.println("File read incorrectly.....");
106 | }
107 | } catch (Exception e) {
108 | // TODO Auto-generated catch block
109 | e.printStackTrace();
110 | }
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/SplitTrainingAndTesting.R:
--------------------------------------------------------------------------------
1 | ################################################
2 | ##Read extracted CSV, verify properties
3 | # split into training and test
4 | # Krishna Karthik Gadiraju/kgadira
5 | ################################################
6 |
7 |
8 |
9 |
10 | rm(list=ls(all=T))
11 | library(rgdal)
12 | library(rgeos)
13 | library(foreign)
14 |
15 | data.all <- read.csv('may28TrainingAllBandsFinal.csv') #contains all sampled points generated using
16 | #point sampling tool in QGIS
17 |
18 | x2 <- sample(1:nrow(data.all),nrow(data.all),replace=F)
19 | data.all <- data.all[x2,]
20 |
21 | #messed up the original id attribute in QGIS, redo it
22 | id <- seq.int(nrow(data.all))
23 | data.all$id <- id
24 |
25 |
26 | #Split data into training and testing - Assume 60,40 ratio
27 | colnames(data.all)[4] <- 'Class'
28 | data.all$Class <- as.factor(data.all$Class)
29 |
30 | data.all.split <- split(data.all,data.all$Class,drop=T)
31 | data.training<- data.frame()
32 | data.testing <- data.frame()
33 | #colnames(data.training) <- colnames(data.all)
34 |
35 | for( i in 1:6){
36 | current <- data.frame(data.all.split[i])
37 | colnames(current) <- colnames(data.all)
38 | noSamples <- nrow(current)
39 | noTraining <- ceiling(0.6*noSamples)
40 | x2 <- sample(1:nrow(current),noTraining,replace=F)
41 | data.training <- rbind(data.training,current[x2,])
42 | data.testing <- rbind(data.testing, current[-x2,])
43 | }
44 |
45 | #remove X,Y, id attribute - we don't use them
46 | data.training <- data.training[,-c(1:3)]
47 | data.testing <- data.testing[,-c(1:3)]
48 |
49 | #Write down CSV and/or arff files
50 | write.csv(x=data.training,'may28-training-AllBands-final.csv',row.names = F)
51 | write.arff(data.training,file='may28-training-AllBands-final.arff',relation='training')
52 |
53 | write.csv(x=data.testing,'may28-testing-AllBands-final.csv',row.names = F)
54 | write.arff(data.testing,file='may28-testing-AllBands-final.arff',relation='testing')
55 |
56 |
57 |
--------------------------------------------------------------------------------
/afterFilter.JPG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kkgadiraju/SatelliteImageClassification/2f5138bc85ab94cbe78d9aab16b8c3a810fce168/afterFilter.JPG
--------------------------------------------------------------------------------
/beforeFilter.JPG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kkgadiraju/SatelliteImageClassification/2f5138bc85ab94cbe78d9aab16b8c3a810fce168/beforeFilter.JPG
--------------------------------------------------------------------------------
/ensemble_final.R:
--------------------------------------------------------------------------------
1 | #Read outputs from other classifiers, convert into water vs everything else,
2 | # identify a pixel as water if atleast two classifiers have identified it as water
3 | # important to ensure that we don't miss any water pixels
4 |
5 | library(rgdal)
6 | library(rgeos)
7 | library(foreign)
8 |
9 |
10 | #read classified file
11 | classifiednb <- read.csv('nbpredict_10bands.csv')
12 | classifieddt <- read.csv('dtpredict_10bands.csv')
13 | classifiedrf <- read.csv('rfpredict_10bands.csv')
14 | classifiedmlp <- read.csv('mlppredict_10bands.csv')
15 | classifiedknn <- read.csv('knnpredict_10bands.csv')
16 |
17 | classifiednb[which(classifiednb$Class!=6),]$Class <-1 #not water
18 | classifiednb[which(classifiednb$Class==6),]$Class <-2 # water
19 |
20 | classifieddt[which(classifieddt$Class!=6),]$Class <-1
21 | classifieddt[which(classifieddt$Class==6),]$Class <-2
22 |
23 | classifiedrf[which(classifiedrf$Class!=6),]$Class <-1
24 | classifiedrf[which(classifiedrf$Class==6),]$Class <-2
25 |
26 | classifiedmlp[which(classifiedmlp$Class!=6),]$Class <-1
27 | classifiedmlp[which(classifiedmlp$Class==6),]$Class <-2
28 |
29 | classifiedknn[which(classifiedknn$Class!=6),]$Class <-1
30 | classifiedknn[which(classifiedknn$Class==6),]$Class <-2
31 |
32 |
33 | classifiednb$Class <- as.factor(classifiednb$Class)
34 | classifieddt$Class <- as.factor(classifieddt$Class)
35 | classifiedrf$Class <- as.factor(classifiedrf$Class)
36 | classifiedmlp$Class <- as.factor(classifiedmlp$Class)
37 | classifiedknn$Class <- as.factor(classifiedknn$Class)
38 |
39 | classifiedEnsemble <- data.frame()
40 |
41 |
42 | classifiedEnsemble<- classifiednb #copy the data over
43 |
44 |
45 | x <- cbind(classifiednb$Class,classifieddt$Class,classifiedrf$Class,classifiedmlp$Class,classifiedknn$Class)
46 | # identify a pixel as water if atleast two classifiers have identified it as water
47 | # important to ensure that we don't miss any water pixels
48 | getLabel <- function(i,x){
49 | sum(x[i,]==2)>=2
50 |
51 | }
52 |
53 | print('Begninning assigning labels')
54 |
55 | counts <- sapply(1:nrow(x),getLabel,x)
56 |
57 | classifiedEnsemble$Class <- 1
58 | classifiedEnsemble$Class[counts]<-2
59 |
60 | print('Finished assigning labels')
61 |
62 | myImg1 <- readGDAL('Clip-May28-Composite.TIF')
63 |
64 | col1 = matrix(0, nrow = 2, ncol = 3)
65 | col1[1, ] = c(255, 255, 255) # black everything else
66 | col1[2, ] = c(0, 0, 255) # blue water
67 |
68 |
69 |
70 | colorize1 <- function(d)
71 | {
72 | for(i in 1:3)
73 | {
74 | d[, i] <- rep(col1[d[1, 11], i], nrow(d))
75 | }
76 | d
77 | }
78 |
79 | print('Beginning to add colors')
80 | colnames(classifiedEnsemble) <- c('band4','band3','Aerosol','energy','band2','invDiffM','SWIR1','SWIR2','diffEntr','inertia','Class')
81 |
82 | print(colnames(classifiedEnsemble))
83 |
84 | classifiedEnsemble$ID <- seq.int(nrow(classifiedEnsemble)) #reorder slides to original order
85 |
86 | t1 <- split(classifiedEnsemble, classifiedEnsemble$Class, drop = T)
87 | t1 <- lapply(t1, FUN = colorize1)
88 | x1 <- do.call("rbind", t1)
89 | x1 <- x1[order(x1$ID), ]
90 |
91 | x1 <- x1[,-c(12)]
92 | #write.csv(x=x1,file='ensemblepredict_10bands.csv',row.names=F)
93 | x1 <- x1[, -c(4,5,6,7,8,9,10,11)]
94 | colnames(x1) <-c('band4','band3','band2')
95 |
96 | myImg1@data[,c('band4','band3','band2')]<-x1
97 |
98 | writeGDAL(myImg1, fname = "./Ensembletiff_OVO_10bands.tif")
99 | print('Write completed')
100 |
101 |
102 |
103 |
104 |
--------------------------------------------------------------------------------
/featureSelection.R:
--------------------------------------------------------------------------------
1 | ################################################
2 | #Feature selection using Learning Vector Quantization
3 | # Source: http://machinelearningmastery.com/feature-selection-with-the-caret-r-package/
4 | # Krishna Karthik Gadiraju/kgadira
5 | ################################################
6 |
7 |
8 | rm(list=ls())
9 |
10 |
11 | library('mlbench')
12 | library('caret')
13 | library('pROC')
14 |
15 | data.training <- read.csv('may28-training-AllBands-final.csv')
16 | data.testing <- read.csv('may28-testing-AllBands-final.csv')
17 | data.training$Class <- as.factor(data.training$Class) #Convert to factor
18 | data.testing$Class <- as.factor(data.testing$Class) #convert to factor
19 | control <- trainControl(method="repeatedcv", number=10, repeats=3) #we can explore more by changing these params
20 |
21 | model <- train(Class~., data=data.training, method="lvq", preProcess="scale", trControl=control)
22 | # estimate variable importance
23 | importance <- varImp(model, scale=FALSE)
24 | # summarize importance
25 | print(importance)
26 | # plot importance
27 | plot(importance)
28 |
29 | #Based on this, take top 10 most important variables and Class variable
30 | top10 <- c('R','G','Aerosol','energy','B','invDiffM','SWIR1','SWIR2','diffEntr','inertia','Class')
31 |
32 | data.training.final <- data.training[,top10]
33 | data.testing.final <- data.testing[,top10]
34 |
35 | #Write down CSV and/or arff files to use for prediction
36 | #write.csv(x=data.training.final,'may28-trainingTop10-AllBands-final.csv',row.names = F)
37 | write.arff(data.training.final,file='may28-trainingTop10-AllBands-final.arff',relation='training')
38 |
39 | #write.csv(x=data.testing.final,'may28-testingTop10-AllBands-final.csv',row.names = F)
40 | write.arff(data.testing.final,file='may28-testingTop10-AllBands-final.arff',relation='testing')
41 |
--------------------------------------------------------------------------------
/mlp.JPG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kkgadiraju/SatelliteImageClassification/2f5138bc85ab94cbe78d9aab16b8c3a810fce168/mlp.JPG
--------------------------------------------------------------------------------
/mlpf1.JPG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kkgadiraju/SatelliteImageClassification/2f5138bc85ab94cbe78d9aab16b8c3a810fce168/mlpf1.JPG
--------------------------------------------------------------------------------
/modeFilter.R:
--------------------------------------------------------------------------------
1 | #Mode filter, takes 5*5 neighborhood, removes noisy classified pixels.
2 | # considers a 5*5 neighborhood, pixel value of middle pixel is equal to water if there are atleast 12 water pixels
3 | # classified as not water otherwise
4 |
5 | library(rgdal)
6 | library(rgeos)
7 | library(foreign)
8 |
9 |
10 | infile.name.noExt <- 'ensemblepredict_10bands'
11 | infile.name <- paste(infile.name.noExt,'.csv',sep='')
12 |
13 | outfile.csv <- paste(infile.name.noExt,'_relaxedIterative_10bands_All.csv',sep='')
14 | outfile.tif <- paste(infile.name.noExt,'_relaxedIterative_10bands_All.tif',sep='')
15 |
16 |
17 | #read classified file
18 | labelled.data <- read.csv(infile.name)
19 | colnames(labelled.data) <- c('band4','band3','Aerosol','energy','band2','invDiffM','SWIR1','SWIR2','diffEntr','inertia','Class')
20 |
21 | labelled.data$Class <- as.factor(labelled.data$Class)
22 |
23 |
24 | ExtractNeighbors <- function(i,class.list){
25 | #Assuming we are doing a 3 by 3 neighborhood i.e., 9 values
26 | nbrs <- matrix(-1,5,5)
27 | #print(i)
28 | #Mange edge conditions left and right borders
29 | if(i%%4218 ==0){#right most border
30 | nbrs[1,1] <- class.list[i-8436]
31 | nbrs[2,1] <- class.list[i-4219]
32 | nbrs[3,1] <- class.list[i-2]
33 | nbrs[4,1] <- class.list[i+4215]
34 | nbrs[5,1] <- class.list[i+8432]
35 | nbrs[1,2] <- class.list[i-8435]
36 | nbrs[2,2] <- class.list[i-4218]
37 | nbrs[3,2] <- class.list[i-1]
38 | nbrs[4,2] <- class.list[i+4216]
39 | nbrs[5,2] <- class.list[i+8433]
40 | nbrs[1,3] <- class.list[i-8434]
41 | nbrs[2,3] <- class.list[i-4217]
42 | #nbrs[3,3] <- class.list[i]
43 | nbrs[4,3] <- class.list[i+4217]
44 | nbrs[5,3] <- class.list[i+8434]
45 |
46 | }else if(i%%4218 ==4217){#one beside right border
47 | nbrs[1,1] <- class.list[i-8436]
48 | nbrs[2,1] <- class.list[i-4219]
49 | nbrs[3,1] <- class.list[i-2]
50 | nbrs[4,1] <- class.list[i+4215]
51 | nbrs[5,1] <- class.list[i+8432]
52 | nbrs[1,2] <- class.list[i-8435]
53 | nbrs[2,2] <- class.list[i-4218]
54 | nbrs[3,2] <- class.list[i-1]
55 | nbrs[4,2] <- class.list[i+4216]
56 | nbrs[5,2] <- class.list[i+8433]
57 | nbrs[1,3] <- class.list[i-8434]
58 | nbrs[2,3] <- class.list[i-4217]
59 | #nbrs[3,3] <- class.list[i]
60 | nbrs[4,3] <- class.list[i+4217]
61 | nbrs[5,3] <- class.list[i+8434]
62 | nbrs[1,4] <- class.list[i-8433]
63 | nbrs[2,4] <- class.list[i-4216]
64 | nbrs[3,4] <- class.list[i+1]
65 | nbrs[4,4] <- class.list[i+4218]
66 | nbrs[5,4] <- class.list[i+8435]
67 |
68 | }else if(i%%4218==1){ # left most border
69 | nbrs[1,3] <- class.list[i-8434]
70 | nbrs[2,3] <- class.list[i-4217]
71 | #nbrs[3,3] <- class.list[i]
72 | nbrs[4,3] <- class.list[i+4217]
73 | nbrs[5,3] <- class.list[i+8434]
74 | nbrs[1,4] <- class.list[i-8433]
75 | nbrs[2,4] <- class.list[i-4216]
76 | nbrs[3,4] <- class.list[i+1]
77 | nbrs[4,4] <- class.list[i+4218]
78 | nbrs[5,4] <- class.list[i+8435]
79 | nbrs[1,5] <- class.list[i-8432]
80 | nbrs[2,5] <- class.list[i-4215]
81 | nbrs[3,5] <- class.list[i+2]
82 | nbrs[4,5] <- class.list[i+4219]
83 | nbrs[5,5] <- class.list[i+8436]
84 |
85 | }else if(i%%4218==2) {# second to left most border
86 | nbrs[1,2] <- class.list[i-8435]
87 | nbrs[2,2] <- class.list[i-4218]
88 | nbrs[3,2] <- class.list[i-1]
89 | nbrs[4,2] <- class.list[i+4216]
90 | nbrs[5,2] <- class.list[i+8433]
91 | nbrs[1,3] <- class.list[i-8434]
92 | nbrs[2,3] <- class.list[i-4217]
93 | #nbrs[3,3] <- class.list[i]
94 | nbrs[4,3] <- class.list[i+4217]
95 | nbrs[5,3] <- class.list[i+8434]
96 | nbrs[1,4] <- class.list[i-8433]
97 | nbrs[2,4] <- class.list[i-4216]
98 | nbrs[3,4] <- class.list[i+1]
99 | nbrs[4,4] <- class.list[i+4218]
100 | nbrs[5,4] <- class.list[i+8435]
101 | nbrs[1,5] <- class.list[i-8432]
102 | nbrs[2,5] <- class.list[i-4215]
103 | nbrs[3,5] <- class.list[i+2]
104 | nbrs[4,5] <- class.list[i+4219]
105 | nbrs[5,5] <- class.list[i+8436]
106 |
107 | } else{
108 | nbrs[1,1] <- class.list[i-8436]
109 | nbrs[2,1] <- class.list[i-4219]
110 | nbrs[3,1] <- class.list[i-2]
111 | nbrs[4,1] <- class.list[i+4215]
112 | nbrs[5,1] <- class.list[i+8432]
113 | nbrs[1,2] <- class.list[i-8435]
114 | nbrs[2,2] <- class.list[i-4218]
115 | nbrs[3,2] <- class.list[i-1]
116 | nbrs[4,2] <- class.list[i+4216]
117 | nbrs[5,2] <- class.list[i+8433]
118 | nbrs[1,3] <- class.list[i-8434]
119 | nbrs[2,3] <- class.list[i-4217]
120 | #nbrs[3,3] <- class.list[i]
121 | nbrs[4,3] <- class.list[i+4217]
122 | nbrs[5,3] <- class.list[i+8434]
123 | nbrs[1,4] <- class.list[i-8433]
124 | nbrs[2,4] <- class.list[i-4216]
125 | nbrs[3,4] <- class.list[i+1]
126 | nbrs[4,4] <- class.list[i+4218]
127 | nbrs[5,4] <- class.list[i+8435]
128 | nbrs[1,5] <- class.list[i-8432]
129 | nbrs[2,5] <- class.list[i-4215]
130 | nbrs[3,5] <- class.list[i+2]
131 | nbrs[4,5] <- class.list[i+4219]
132 | nbrs[5,5] <- class.list[i+8436]
133 |
134 | }
135 | return(nbrs)
136 |
137 | }
138 |
139 | LabelRelaxation <- function(i,class.list){
140 | #first extract neighbors
141 | nbrs <- ExtractNeighbors(i,class.list)
142 | count <- sum(nbrs==2)
143 | if(count>=13){ #more than half, change to water
144 | return(2)
145 | } else if(count == 12){ # exactly half, remains same
146 | return(class.list[i])
147 | }else
148 | return(1)
149 | }
150 |
151 | ModeFilter <- function(){
152 |
153 | print('Beginning assigning labels')
154 | label <- rep(1,nrow(labelled.data))
155 | min <- 8437
156 | max <- nrow(labelled.data)-2*4218
157 | label[min:max] <- sapply(min:max,LabelRelaxation,labelled.data$Class)
158 | labelOld = labelled.data$Class
159 | labelled.data$Class <<- as.factor(label)
160 | countDifference <- sum(labelOld!=label)
161 | cat('Difference in labels = ',countDifference,'\n')
162 |
163 | }
164 |
165 | currentTime <- proc.time()
166 | ModeFilter()
167 | print('Finished assigning labels')
168 | cat('Execution time = ',proc.time()-currentTime,'\n')
169 | myImg1 <- readGDAL('Clip-May28-Composite.TIF')
170 |
171 | col1 = matrix(0, nrow = 2, ncol = 3)
172 | col1[1, ] = c(255, 255, 255) # black everything else
173 | col1[2, ] = c(0, 0, 255) # blue water
174 |
175 |
176 |
177 | colorize1 <- function(d)
178 | {
179 | for(i in 1:3)
180 | {
181 | d[, i] <- rep(col1[d[1, 11], i], nrow(d))
182 | }
183 | d
184 | }
185 |
186 | print('Beginning to add colors')
187 |
188 | labelled.data$ID <- seq.int(nrow(labelled.data))
189 | t1 <- split(labelled.data, labelled.data$Class, drop = T)
190 | t1 <- lapply(t1, FUN = colorize1)
191 | print('Colorized completed')
192 |
193 | x1 <- do.call("rbind", t1)
194 | x1 <- x1[order(x1$ID), ]
195 | x1 <- x1[,-12]
196 | write.csv(x=x1,file=outfile.csv,row.names=F)
197 | x1 <- x1[, -c(4,5,6,7,8,9,10,11)]
198 | colnames(x1) <- c('band4','band3','band2')
199 | myImg1@data[,c('band4','band3','band2')]<-x1
200 | writeGDAL(myImg1, fname = outfile.tif)
201 |
202 | print('Write completed')
203 |
204 |
205 |
206 |
207 |
--------------------------------------------------------------------------------
/postProcessing_AllClasses.R:
--------------------------------------------------------------------------------
1 | ################################################
2 | # Get classified samples from Weka, visualize it as geotiff
3 | # 6 colors - (Clouds, Roads, Shadow, Urban, Vegetation, Water) - (white, yellow, black, pink, green, blue)
4 | # Krishna Karthik Gadiraju/kgadira
5 | # Bharathkumar Ramachandra/tnybny
6 | ################################################
7 |
8 | library(rgdal)
9 | library(rgeos)
10 | library(foreign)
11 |
12 |
13 | #read original image
14 | myImg<-readGDAL('path_to_original_image')
15 |
16 | #read classified file
17 | classified <- read.csv('predicted-csv-file')
18 |
19 | #column names of features - top 10 features selected using feature selection + Class Label
20 | colnames(classified) <- c('band4','band3','Aerosol','energy','band2','invDiffM',
21 | 'SWIR1','SWIR2','diffEntr','inertia','Class')
22 | print(colnames(classified))
23 | print(summary(classified))
24 |
25 | # Convert class variable to factor
26 | classified$Class <-as.factor(classified$Class)
27 | print('all classes summary')
28 | print(summary(classified))
29 |
30 | #Assign colors: Source: Visualization work done by BharathKumar Ramachandra/tnybny
31 | col = matrix(0, nrow = 6, ncol = 3)
32 | col[1, ] = c(255, 255, 255) # red clouds
33 | col[2, ] = c(255, 255, 0) # yellow roads
34 | col[3, ] = c(0, 0, 0) # black shadow
35 | col[4, ] = c(255, 105, 180) # hot pink for urban
36 | col[5, ] = c(0, 255,0 ) # green vegetation
37 | col[6, ] = c(0, 0, 255) # blue water
38 |
39 |
40 | colorize <- function(d)
41 | {
42 | for(i in 1:3)
43 | {
44 | d[, i] <- rep(col[d[1, 11], i], nrow(d))
45 | }
46 | d
47 | }
48 |
49 |
50 |
51 | print('Beginning to add colors')
52 | classified$ID <- seq.int(nrow(classified))
53 |
54 |
55 | t <- split(classified, classified$Class, drop = T) #split by class
56 | t <- lapply(t, FUN = colorize) #Appl color to each class
57 |
58 |
59 | print('Colorized completed')
60 | x <- do.call("rbind", t)
61 |
62 |
63 | x <- x[order(x$ID), ] #Reorder data in original order
64 |
65 |
66 | x <- x[, -c(4:12)] #Remove unnecessary columns
67 | colnames(x) <-c('band4','band3','band2') #Rename first three bands to ba
68 | myImg@data[,c('band4','band3','band2')]<-x #Copy R,G,B bands
69 | writeGDAL(myImg, fname = "./KNNtiff_10bands.tif") #write GDAL file
70 |
71 | print('Write completed')
72 |
--------------------------------------------------------------------------------
/postProcessing_onlyWater.R:
--------------------------------------------------------------------------------
1 | ################################################
2 | # Get classified samples from Weka, visualize it as geotiff
3 | # Krishna Karthik Gadiraju/kgadira
4 | # Bharathkumar Ramachandra/tnybny
5 | ################################################
6 |
7 | library(rgdal)
8 | library(rgeos)
9 | library(foreign)
10 |
11 | #read original image
12 | myImg1 <- readGDAL('Clip-May28-Composite.TIF')
13 |
14 | #read classified file
15 | classified <- read.csv('predicted-csv-file')
16 |
17 | #column names of features - top 10 features selected using feature selection + Class Label
18 | colnames(classified) <- c('band4','band3','Aerosol','energy','band2','invDiffM',
19 | 'SWIR1','SWIR2','diffEntr','inertia','Class')
20 | print(colnames(classified))
21 | print(summary(classified))
22 |
23 | classified[which(classified$Class!=6),]$Class <-1
24 | classified[which(classified$Class==6),]$Class <-2
25 |
26 | # Convert class variable to factor
27 | classified$Class <-as.factor(classified$Class)
28 | print('classes summary')
29 | print(summary(classified))
30 |
31 | #Assign colors: Source: Visualization work done by BharathKumar Ramachandra/tnybny
32 | col1 = matrix(0, nrow = 2, ncol = 3)
33 | col1[1, ] = c(255, 255, 255) # white everything else
34 | col1[2, ] = c(0, 0, 255) # blue water
35 |
36 | #Function that assigns colors
37 | colorize <- function(d)
38 | {
39 | for(i in 1:3)
40 | {
41 | d[, i] <- rep(col1[d[1, 11], i], nrow(d))
42 | }
43 | d
44 | }
45 |
46 | print('Beginning to add colors')
47 | classified$ID <- seq.int(nrow(classified))
48 |
49 | t <- split(classified, classified$Class, drop = T)
50 | t <- lapply(t, FUN = colorize1)
51 |
52 | print('Colorized completed')
53 | x <- do.call("rbind", t)
54 |
55 | x <- x[order(x$ID), ] #Reorder data in original order
56 |
57 |
58 | x <- x[, -c(4:12)] #Remove unnecessary columns
59 | colnames(x) <-c('band4','band3','band2') #Rename first three bands to ba
60 | myImg@data[,c('band4','band3','band2')]<-x #Copy R,G,B bands
61 | writeGDAL(myImg, fname = "./KNNtiff_10bands.tif") #write GDAL file
62 |
63 | print('Write completed')
64 |
65 |
66 |
--------------------------------------------------------------------------------
/preprocessing_totalImage.R:
--------------------------------------------------------------------------------
1 | #convert geotiff to csv/arff format to be used in Weka classifiers
2 | #Krishna Karthik Gadiraju/kkgadiraju
3 | rm(list=ls())
4 |
5 | library(rgdal)
6 | library(rgeos)
7 | library(foreign)
8 |
9 |
10 | myImg<-readGDAL('Clip-May28-Composite.TIF')
11 | simpleImg <- readGDAL('May28-SimpleFinal.tif')
12 | advancedImg <- readGDAL('May28-AdvancedFinal.tif')
13 | myImgData <- myImg@data
14 | simpleImgData <- simpleImg@data
15 | advancedImgData <- advancedImg@data
16 | colnames(myImgData) <- c("Aerosol","B","G","R","NIR","SWIR1","SWIR2","Cirrus")
17 | colnames(simpleImgData) <- c("energy","entropy","corr","invDiffM","inertia","clusShade","clusProm","hCorr")
18 | colnames(advancedImgData) <- c("mean","variance","dissim","sumAvg","sumVar","sumEntr","diffEntr","diffVar","IC1","IC2")
19 | allData <- cbind(myImgData,simpleImgData,advancedImgData)
20 | x2 <- sample(1:6,nrow(allData),replace=T)
21 | allData$Class <-x2
22 | top10 <- c('R','G','Aerosol','energy','B','invDiffM','SWIR1','SWIR2','diffEntr','inertia','Class')
23 |
24 | outputData <- allData[,top10]
25 |
26 | outputData$Class <- as.factor(outputData$Class)
27 |
28 | #write.csv(x=outputData,file = 'may28-allImage-top10.csv',row.names = F)
29 | write.arff(outputData,file='may28-allImage-top10.arff',relation='testing')
30 |
31 |
--------------------------------------------------------------------------------