unmixing in earth engine and generate classification map - classification

hello I apply unmixing on sentinel image based on the spectral signatures I provided
here is the code:
var SentinelColl = ee.ImageCollection("COPERNICUS/S2_SR")
.filterBounds(geometry)
.filterMetadata('CLOUDY_PIXEL_PERCENTAGE', 'less_than', 5)
.filterMetadata('SNOW_ICE_PERCENTAGE','less_than',5)
.filterDate('2020-01-01', '2022-01-01')
.sort('system:index',false)
.select('B2', 'B3', 'B4', 'B5', 'B6', 'B7', 'B8','B8A','B11','B12')
.median()
var classNames = Urban.merge(Water).merge(Forest).merge(AgricultureWet).merge(AgricultureDry).merge(MinesNew)
//.merge(shadow).merge(barren)//.merge(roadL1).merge(roadL2);
var bands = Sentinel.bandNames();
var training = Sentinel.sampleRegions({
collection: classNames,
properties: ['landcover'],
scale: 10
});
var fractions = Sentinel.clip(geometry).unmix([mineSP, agrWSP,agrDSP,waterSP,forsSP,urbSP],true,true);
but how can I generate final classification map so that each pixel assigned and coded as the endmember with the max fraction?
like in ENVI: max rule classifier
I want to generate a map which each pixel assigned to one class based on the aboundance /fraction values of them
finally I will calculate the number of pixels that assigned to each class

Related

Linear x axis for bar chart chartjs

I am using chartjs 2.9.3. I want to have linear scale for x axis for bar plots. It should work just like any linear scale of line plots representing negative, decimal, positive values.
I have managed to create almost similar scale here using this options.
scales: {
xAxes: [
{
type: "time",
time: {
parser: "Y",
unit: "year",
displayFormats: {
year: "Y"
}
},
}
]
},
But it is not working for decimal values, when dataset has negative x values, it is just rounding off to integer and placing the bar at that position.
How can represent decimal values as well?
Chartjs >=3.0.0 has introduced linear scale for bar plots. But this version has some other bugs in it so I am stuck with 2.9.3 version
I don't recommend to change the axis type to time, as this will introduce several other issues given that there are not "fractional times". And adding support for it is not that easy.
The best bet is to create your own labels with a custom function. For example:
const f = () => {
let a = [];
for (let n = -30; n <= 30; n++) {
a.push(n / 100 + "");
}
return a;
};
To generate from -3.00 to +3.00 (zeros representing decimal places). The bigger the numbers 30 and 100 the bigger the "resolution" of your linear scale.
Demo: https://codesandbox.io/s/react-chartjs-2-example-forked-26bbx?file=/src/index.js

How to show only one of the clusters in Goole Earth Engine unsupervised classification

Suppose we have the following codes for unsupervised classification. My goal is to identify the water bodies across the area. How can I mask out other classes (clusters) and only map one of the clusters (water bodies)in my results:
// Load a pre-computed Landsat composite for input
var input = ee.Image('LANDSAT/LE7_TOA_1YEAR/2001');
// Define a region in which to generate a sample of the input.
var region = ee.Geometry.Rectangle(29.7, 30, 32.5, 31.7);
// Display the sample region.
Map.setCenter(31.5, 31.0, 8);
Map.addLayer(ee.Image().paint(region, 0, 2), {}, 'region');
// Make the training dataset.
var training = input.sample({
region: region,
scale: 30,
numPixels: 5000
});
// Instantiate the clusterer and train it.
var clusterer = ee.Clusterer.wekaKMeans(5).train(training);
// Cluster the input using the trained clusterer.
var result = input.cluster(clusterer);
// Display the clusters with random colors.
Map.addLayer(result.randomVisualizer(), {}, 'clusters');
I only need the cluster (0) so I could mask the rest of the classes using the codes below:
// showing only one cluster.
var subset = result.select("cluster").eq(0).selfMask();

Leaflet meters to pixels per zoom level

I'm creating an app using Leaflet library
I have a field radius that contains distance in meters (m).
const radius = 1000;
I would need to convert this field to pixels, but on different zoom levels
For zoom levels, I get values from 8 till 18
I have this function that converts successfully on the current zoom level
function disToPixeldistance(distance){
var l2 = L.GeometryUtil.destination(map.getCenter(),90,distance);
var p1 = map.latLngToContainerPoint(map.getCenter())
var p2 = map.latLngToContainerPoint(l2)
return p1.distanceTo(p2)
}
But I would need to pass different zoom levels as an additional parameter and then convert them from meters to pixels
Like:
function disToPixeldistance(distance, zoomLevel)
Does anyone knows how could I achieve this ? Thank you in advance :)
Change the map.latlngToContainerPoint(latlng) to map.project(latlng,zoom)
function disToPixeldistance(distance, zoom){
zoom = zoom || map.getZoom();
var l2 = L.GeometryUtil.destination(map.getCenter(),90,distance);
var p1 = map.project(map.getCenter(), zoom)
var p2 = map.project(l2,zoom)
return p1.distanceTo(p2)
}

How can I find all the lakes in a region (bounded by polgon) in earth engine?

The problem statement is that a region of interest is given.
I need to find all the lakes in a polygon bounded region using the NDWI index for water bodies, which are at a height of more than 1500m. Then display the changes in the area of lake's surface water starting from the year 1984 till 2018 on a 2-year interval in a table like structure in Google Earth Engine. I have used Landsat 5 and 7 data.
I have created the following code:
Earth Engine Code
Now I need to display the results in the polygon marked region in a table sort of structure in the following format:-
Rows - (Lake 1, Lake 2, Lake 3... Lake n)
Columns - (Surface Area in 1984, Surface Area in 1986, ....2018)
How should I go about doing it?
I answer this question in regard of the code posted in the comments, hopefully the question is updated with the code posted in the comments.
Filtering: ok.
Just a comment, I wouldn't name an image collection variable with name img, it's just confusing to me, but variables names are up to you.
var mf = ee.Filter.calendarRange(10, 12, 'month');
var img1 = ee.ImageCollection(l5
.filterDate('1984-01-01','1999-12-31')
.filterBounds(roi)
.filter(mf));
var img2 = ee.ImageCollection(l7
.filterDate('2000-01-01','2018-12-31')
.filterBounds(roi)
.filter(mf));
add NDWI: This is your code:
var addNDWI = function(image){
var ndwi = image.normalizedDifference(['B2', 'B4']).rename('NDWI');
var ndwiMask = ndwi.gte(0.3);
return image.addBands(ndwi);
};
var image1 = img1.map(addNDWI);
var image2 = img2.map(addNDWI);
you are not saving ndwiMask, so you won't be able to use it outside of this function. Again, I wouldn't name them image as they are not images but image collections.
elevation mask: you have to select the elevation band:
var elevMask = elevation.select('elevation').gt(1500)
This mask image will have ones where elevation is greater than 1500 and zeros where not.
applying masks: in this part you have to remember that Earth Engine uses functional programming, so objects are not mutable, this means that you cannot update the state of an object using a method, you have to catch the output of the method you are calling. Here you need ndwi mask, so you have to compute it with NDWI band.
var mask = function(image){
var ndwiMask = image.select('NDWI').gt(0.3)
var ndwi_masked = image.updateMask(ndwiMask);
return ndwi_masked.updateMask(elevMask);
};
var maskedImg = image1.map(mask); // ImageCollection!
var maskedImg2 = image2.map(mask); // ImageCollection!
Visualizing: As the results are ImageCollection, when you add it to the map EE makes a mosaic and that is what you would see. Keep that in mind for further processing.
var ndwiViz = {bands: ['NDWI'], min: 0.5, max: 1, palette: ['00FFFF', '0000FF']};
Map.addLayer(maskedImg, ndwiViz, 'Landsat 5 masked collection');

In caffe, py-faster-rcnn, "scores" return a large matrix, why?

I use the py-faster-rcnn demo to build further of my project with 20 classes.
However, I am trying to gain the softmax, last layer probability of my classes.
For example:
# Load the demo image
im_file = os.path.join(cfg.DATA_DIR, 'demo', image_name)
im = cv2.imread(im_file)
# Detect all object classes and regress object bounds
timer = Timer()
timer.tic()
scores, boxes = im_detect(net, im)
timer.toc()
print ('Detection took {:.3f}s for '
'{:d} object proposals').format(timer.total_time, boxes.shape[0])
# Visualize detections for each class
CONF_THRESH = 0.8
NMS_THRESH = 0.3
for cls_ind, cls in enumerate(CLASSES[1:]):
cls_ind += 1 # because we skipped background
cls_boxes = boxes[:, 4*cls_ind:4*(cls_ind + 1)]
cls_scores = scores[:, cls_ind]
dets = np.hstack((cls_boxes,
cls_scores[:, np.newaxis])).astype(np.float32)
keep = nms(dets, NMS_THRESH)
dets = dets[keep, :]
vis_detections(im, cls, dets, thresh=CONF_THRESH)
print scores
While I do the print scores, it gives me a very large matrix output,
instead of 1 x 20 . I am not sure why, and how can I get the last probability matrix?
Thanks
The raw scores the detector outputs include overlapping detections and very low score detections as well.
Note that only after applying non-maximal suppression (aka "nms") with NMS_THRESH=0.3 the function vis_detection only displays detections with confidence larger than CONF_THRESH=0.8.
So, if you want to look at the "true" objects, you need to check inside vis_detection and check only the detections it renders on the image.