最近突然发现哨兵二号的QA60波段,在2022年7月多按照mask掩膜去云的效果不好,可能是因为云量太高等原因。想到了之前见过的代码,于是按照云量分数和SVM进行了去云。可以在上面继续改进。
var imageCollection = ee.ImageCollection("COPERNICUS/S2")
var geometry = ee.Geometry.Polygon(
[[[116.1703785888879, 40.06062269716839],
[116.1703785888879, 39.7065494906677],
[116.67437639162227, 39.7065494906677],
[116.67437639162227, 40.06062269716839]]], null, false);
// Cloud Detection of Sentinel-2 Image Coupled with SVM and Cloud Scoring Algorithm
// Sample image
var StartDate = '2018-10-10';
var EndDate = '2019-10-10';
var img = ee.ImageCollection("COPERNICUS/S2").filterBounds(geometry)
.filterDate(StartDate,EndDate)
.first();
Map.addLayer(img, {bands:['B4','B3','B2'],min:0,max:3000}, 'Original Image');
Map.centerObject(geometry,11);
// QA60 band cloud detection
function QA60_cloud (img){
var qa60 = img.select('QA60').neq(0);
return img.updateMask(qa60).select('QA60');
}
Map.addLayer(QA60_cloud(img), {palette:['orange']}, 'QA60_band Result');
// Cloud Scoring Algorithm
var _cloudScore = function(img) {
var rescale = function(img, exp, thresholds) {
return img.expression(exp, {img: img})
.subtract(thresholds[0]).divide(thresholds[1] - thresholds[0]);
};
var score = ee.Image.constant(1.0);
score = score.min(rescale(img, 'img.blue', [0.1, 0.3]));
score = score.min(rescale(img, 'img.red + img.green + img.blue', [0.2, 0.8]));
score = score.min(rescale(img, 'img.nir + img.swir1 + img.swir2', [0.3, 0.8]));
var ndsi = img.normalizedDifference(['green', 'swir1']);
return score.min(rescale(ndsi, 'img', [0.8, 0.6]));
};
function rmCloudByScore(image, thread) {
var preBands = ["B2","B3","B4","B8","B11","B12"];
var newBands = ['blue','green','red','nir','swir1','swir2'];
var score = _cloudScore(image.select(preBands, newBands));
score = score.multiply(100).byte().rename('cloud');
return image.addBands(score)
//.updateMask(score.gte(thread));
}
function scaleImage(image) {
var time_start = image.get("system:time_start");
image = image.divide(10000);
image = image.set("system:time_start", time_start);
return image;
}
// SVM_CloudScore cloud detection
function SVM_Class (img) {
var cloud_sample = img.select('cloud').gte(60.0).multiply(1.0).rename('cloud_sample');
img = img.addBands(cloud_sample);
print('Image Information',img)
var training = img.stratifiedSample({
numPoints: 30,
classBand: "cloud_sample",
region:geometry,
scale: 30,
geometries: true
});
Map.addLayer(training,{},'SVM Train Sample');
var SVM_classifier = ee.Classifier.libsvm({
kernelType: 'RBF',
gamma: 0.5,
cost: 10
});
var classifier = SVM_classifier.train(training, "cloud_sample");
var svm_cloud = img.classify(classifier).rename('SVM_Cloud_');
img = img.addBands(svm_cloud);
return img.select('SVM_Cloud_').updateMask(img.select('SVM_Cloud_'));
}
// main function
function main() {
var img_Scale = scaleImage(img);
var img_CloudScore_ = rmCloudByScore(img_Scale, 60);
Map.addLayer(img_CloudScore_.updateMask(img_CloudScore_.select('cloud').gt(50.0)).select('cloud'), {palette:['orange']}, "Cloud Score Result");
Map.addLayer(SVM_Class(img_CloudScore_),{palette:['orange']},'SVMcloud Result');
}
main();
去云效果图