LC Mapping: Image (Error) Image.select: Pattern 'numObs' did not match any bands.
ericacinerea opened this issue · comments
Hi CCDC Team,
First, thank you very much for this resource; it´s very useful.
I am using the utilities 'users/parevalo_bu/gee-ccdc-tools:ccdcUtilities/api' to first detect changes and then get a classification of LandCover.
I have been able to run all the steps except the last one when I perform a Landcover classification for a specific date.
- I get the ccdc multi-dimensional array and convert it to a ccdImage correctly
- The training data is also created correctly
- The RandomFroest Classification also works, and I can export classification results for specific segments.
// Classification parameters
var classification = {
bandNames: ['BLUE','GREEN','RED','NIR','SWIR1','SWIR2'],
inputFeatures: ["INTP", "SLP","PHASE","RMSE"],
coefs: ["INTP", "SLP","COS", "SIN","RMSE","COS2","SIN2","COS3","SIN3"],
ancillaryFeatures: ["ELEVATION","ASPECT","DEM_SLOPE","RAINFALL","TEMPERATURE"],
resultFormat: 'SegCollection',
classProperty: 'id',
yearProperty: 'year',
classifier: ee.Classifier.smileRandomForest,
classifierParams: {
numberOfTrees: 150,
variablesPerSplit: null,
minLeafPopulation: 1,
bagFraction: 0.5,
maxNodes: null
},
segs: ["S1", "S2", "S3", "S4", "S5", "S6"],
};
// Get classifier with params
var classifier = classification.classifier(classification.classifierParams);
var results_class = utils.Classification.classifySegments(
ccdImage, classification.segs.length, classification.bandNames,
ancillary, classification.ancillaryFeatures,
trainingData, classifier, studyRegion, classification.classProperty,
classification.inputFeatures)
.clip(studyRegion);
It is now when printing and exporting the classification for a specific date, using the previous results "results_class" when I get the error: Image (Error) Image.select: Pattern 'numObs' did not match any bands.
var dateOfClassification = '2019-03-27';
var matchingDate = utils.Classification.getLcAtDate(results_class,
dateOfClassification);
print(matchingDate, 'matchingDate');
Do you know where my mistake could be?
Here you are a link to the code:
https://code.earthengine.google.com/?accept_repo=users/ericacinerea/public
Thank you very much in advance.
Hi
I just got the same error. I think there is a problem when filtering the ccdcCollection with a metadataFilter, inside the utils.Classification.getLcAtDate
function. The returned object is empty so I assume that the filter is not working as expected, in the following lines (thus, that is causing the 'numObs' error):
// Get CCDC coefficients
var ccdcCollectionFiltered = ccdcCollection
.filterMetadata('system:index', 'starts_with',metadataFilter)`
I created another function based on the previous one, that seems to solve the problem. Right now I wrote it in a fast and messy way, but can be a quick workaround:
function getLcAtDate2(date){
var segs = classificationStack;
var numberOfSegments = 6;
var bandNames = bands;//bandNames || ["BLUE","GREEN","RED","NIR","SWIR1","SWIR2","TEMP"]
var inputFeatures = ["INTP", "SLP","PHASE","AMPLITUDE","COS","SIN","COS2","SIN2"];//inputFeatures || ;
numberOfSegments = ee.Image(segs).bandNames().length();//numberOfSegments || ;
var behavior = 'after'//behavior || 'after'
// Commented these lines for now
//if (dateFormat === 0){
// dateFormat = 0
//} else if (dateFormat > 0) {
// dateFormat = dateFormat
//} else {
// dateFormat = 1
//}
// dateFormat = (dateFormat && dateFormat === 0) || 1
// Date passed as string 2020-01-01
var dateFormat = 1;
// CCDC Collection and 'system:index' metadata ftilter
//var ccdcCollection = ccdcResults;
var ccdcCollection = ee.Image('path/to/image/fromTemporalSegmentation.Ccdc');//ee.ImageCollection("projects/CCDC/" + ccdVersion)
//print('ccdcCollection', ccdcCollection);
// Get CCDC coefficients
//var ccdcCollectionFiltered = ccdcCollection;//.filterMetadata('system:index', 'starts_with',metadataFilter)
//print('ccdcCollectionFiltered', ccdcCollectionFiltered);
// CCDC mosaic image
var ccdc = ccdcCollection;//.mosaic()
//print('ccdc', ccdc);
// Turn array image into image
var specImage = utils.CCDC.buildCcdImage(ccdc, numberOfSegments, bandNames)//specImage ||
//print('specImage', specImage);
var tStarts = specImage.select('.*tStart')
var tEnds = specImage.select('.*tEnd')
var dateFormatted = utils.Dates.convertDate({
inputFormat: 3,
inputDate: date,
outputFormat: dateFormat
})
//print('tEnds',tEnds);
if (behavior == 'before') {
var dateMask = tStarts.lt(dateFormatted)
var matchingDate = segs.updateMask(dateMask).reduce(ee.Reducer.lastNonNull())
} else if (behavior == 'after') {
var dateMask = tEnds.gt(dateFormatted)
var matchingDate = segs.updateMask(dateMask).reduce(ee.Reducer.firstNonNull())
} else {
var dateMask = tStarts.lt(dateFormatted).and(tEnds.gt(dateFormatted))
var matchingDate = segs.updateMask(dateMask).reduce(ee.Reducer.firstNonNull())
}
return matchingDate;
};
var class2000 = getLcAtDate2('2000-01-01');
Hello, and thanks for your interest in this repo. I've been unable to work on this repo in a long time, but I just updated the getLcAtDate
source code on GEE, and it should work now. This change won't be reflected in the Github copy of the code, or in the documentation because I need to bring a bunch of things up to date for that to happen. In the meantime, this is how you can use the function right now.
var matchingDate = utils.Classification.getLcAtDate(
classificationStack, // Classified segments
dateOfClassification, // Date for which to retrieve the classification
params.Classification.segs.length, // # of segments
params.Classification.changeResults // the CCDC results
)
Thank you very much for your tutorial, but I used this function to extract two classifications that are years apart and the result is the same, what could be the reason?