In Google Earth Engine, is it possible to obtain the pixel values of an image?
The following code displays the details of the image and we can see that the image has 10980*10980 pixels for the bands 2,3 and 4. How can we obtain the pixel value of band 3 at the (x,y) pixel or a specific (lat,lon)?
var im1 = ee.Image('COPERNICUS/S2/20160422T084804_20160422T123809_T36TVK')
print(im1)
// Image
var im1 = ee.Image('COPERNICUS/S2/20160422T084804_20160422T123809_T36TVK')
// Point
var p = ee.Geometry.Point(32.3, 40.3)
// Extract the data
var data = im1
.select("B3")
.reduceRegion(ee.Reducer.first(),p,10)
.get("B3")
// Convert to Number for further use
var dataN = ee.Number(data)
// Show data
print(dataN)
// Add Layers
Map.centerObject(im1)
Map.addLayer(im1,{bands:["B4","B3","B2"],min:0,max:5000})
Map.addLayer(p)
You can also use the inspector tool, next to the console tab on the right upper area of the interface. After clicking on a location on the map you will see the values of each band for each map layer displayed for that pixel corresponding to that location.
Another note, if you need the value of a pixel for all images in an ImageCollection, for example, is that you can turn the ImageCollection into an image using:
image_with_bands = original_image_name.toBands()
Then when you do a reduceRegion and the .getInfo() (or .get() for Java), you get a list of all of the values for all of the bands, where the bands are named by the original band name with an _ and then the date! Another good tool for this kind of calculation is the geemap package, which has a lot of these tools ready to go.
Related
sorry for the basic question, I'm a GEE beginner.
Essentially, what I want to do it extract the value of a certain band in a pixel from each image in a collection, and put it into an array.
I understand how to do this if the output is to a chart, e.g.:
print(ui.Chart.image.series(with_ndvi.select("nd"),area));
Where with_ndvi is my image collection, "nd" is the band I'm interested in, and area is a point feature.
However, I need to get these values into an array, because I need to perform a calculation on each value.
Is there an easy funciton to map over a collection to extract the values as numbers to work with?
Thanks for any help.
In general, in order to get particular values out of an image, you use reduceRegion. Since you have a single point, there isn't exactly any reduction, but the same operation can be used to get the mean, median, maximum, etc. from an area and you need to choose a reducer to perform the operation. (ui.Chart.image.series defaults to the mean reducer if you don't specify otherwise).
I constructed this example from the images used in the Normalized Difference example script:
var imageCollection = ee.ImageCollection('MODIS/006/MOD09GA')
.filterDate('2019-01-01', '2019-01-31');
var ndviCollection = imageCollection.map(function (img) {
var ndImage = img.normalizedDifference(['sur_refl_b02', 'sur_refl_b01']);
return ee.Feature(area, ndImage.reduceRegion(ee.Reducer.mean(), area));
});
print(ndviCollection);
Runnable example link
Here, ndviCollection is a FeatureCollection where each feature has the original point as geometry (useful if you have multiple points of interest, but otherwise you could make it be null instead) and the NDVI at that point as a property named nd.
If you absolutely need a list of numbers rather than a feature collection, you can obtain that:
print(ndviCollection
.toList(100) // set this number to the maximum number of elements you expect
.map(function (feature) {
return ee.Feature(feature).get('nd');
}));
but you should not do this if you can avoid it as lists are always kept in memory as a whole rather than processed in a streaming fashion. Instead, perform your computations on the feature collection using map and/or reduceColumns.
I am using map bounds to display markers that fall within the current viewport. Upon zooming or panning the bounds are recalculated and the markers that fall within these bounds are redrawn, effectively hiding any not contained within the viewport.
I would like to do it so that the markers draw slightly out of the current viewport, however this would involve extending the bounds equally from all sides rather than using bounds.extend(point). Is this possible?
//I would like to extend this value in order to draw features that are slightly off the viewport
var bounds = map.getBounds()
//This is how I am currently extending the bounds, it works but I am unsure if it is the correct way.
bounds.b.b = bounds.b.b - 0.5
bounds.b.f = bounds.b.f + 0.5
bounds.f.b = bounds.f.b - 0.5
bounds.f.f = bounds.f.f + 0.5
//Determining whether the feature lies within the current viewport
var result = bounds.contains(Featurecenter)
center = null
//If the feature lies within the viewport
if (result) {
Feature.setMap(map) //Making the feature visible on the map
}
Don't use b, f and such, which are undocumented properties, instead use documented methods such as getNorthEast(), getSouthWest() then lat() and lng() when you need to extract coordinates from a bounds object.
I don't know of any other method to extend a bounds object than to pass new coordinates to it (see below).
The LatLngBounds object has an extend() method that you must use to achieve what you want.
We don't know of "how much" you need to extend the bounds; depending on that, and on the current zoom level when you want to extend your bounds, you will probably need to do some maths.
If you need to extend your bounds by a given (and constant) distance, whatever zoom level is currently set, I suggest you to read some other Q/A that explain how to do that. For example:
Google maps distance based on the zoom level
Google Maps V3 - How to calculate the zoom level for a given bounds
I am looking for a fairly simple image comparison method in AS3. I have taken an image from a web cam (with no subject) passed it in to bitmap data, then a second image is taken (this time with a subject) to compare this data, from these two images I would like to create a mask from the pixels that match on both bitmaps. I have been scratching my head for a while, and I am not really making any progress. Could any one point me in the right direction for pixel comparison method, something like getPixel32()
Cheers
Jono
use compare to create a difference between the two and then use treshold to extract the parts that interest you.
edit: actually it is pretty straight forward. the trick is to apply the threshold multiple times per channel using the mask parameter (otherwise the comparison only makes little sense, since 0x010000 (which is almost black) is consider greater than 0x0000FF (which is anything but black)). here's how:
var dif:BitmapData;//your original bitmapdata
var mask:BitmapData = new BitmapData(dif.width, dif.height, true, 0);
const threshold:uint = 0x20;
for (var i:int = 0; i < 3; i++)
mask.threshold(dif, dif.rect, new Point(), ">", threshold << (i * 8), 0xFF000000, 0xFF << (i * 8));
this creates a transparent mask. then the threshold is applied for all three channels, setting the alpha channel to fully opaque where the channels value exceeds the threshold value (you might wanna decrease it).
you can isolate the foreground object ("the guy in front of the webcam") by copying the alpha channel from the mask to the current video image.
one of the problems here is that you want to find if a pixel has ANY change to it, and if it does then to convert that pixel to another color (for masking). Unfortunately, a webcam's quality isn't great so even if your scene does not change at all the bitmapdata coming from the webcam will change slightly. Therefor, when your subject steps into frame...you will get pixel changes for the subject...but also noise in other areas due to lighting changes or camera quality. What you'll need to do is write a function that analyzes the result of a bitmapdaya.compare() for change in area's larger than _____ to determine if there is enough change to warrant an actual object being there. That will help remove noise and make your mask more accurate.
i have got center of map using map.getCenter(); and i got current zoom of google map using getZoom(); please tell me how can i calculate/get current show mils area in google map. i am using asp.net and javascript.
With GMap2.getBounds() you can get the visible rectangular region of the map view.
Then using these coordinates you can construct a GPolygon object and calculate the area in square meters using GPolygon.getArea() function. Then convert given area to mils (1 meter = 39 370.0787 mils).
the GLatLng object has a distanceFrom function that takes another GLatLng. The map has getBounds from which you'll be able to get the corners of interest, and check the distance between them.
This question already has an answer here:
Can I get vector data back out out of a Graphics object?
(1 answer)
Closed 9 years ago.
EDIT (for clarification):
I have a vector image with a simple contour, an irregular closed polygon.
I need to import it into Flash in a way that I can then programmatically access each of the segments that form the polygon.
Importing the vector image into the library as a MovieClip wasn't good because all I get is a shape from which I can take no geometry information at all.
My goal is being able to calculate the polygon's area and also calculating the intersection between the polygon and another polygon.
I guess I could write an Illustrator script that reads all the segments and writes a CSV files with their coordinates, but there has to be a simpler way, I mean, they're both vectorial, they should understand each other.
Thanks!
.
-- Old Post: --
I have a contour in vector graphics that I imported to the Flash library as a movieclip.
I Instanciate the movieclip and it has a Shape child which is the actual contour.
I need to be able to access the contour segments, i.e. the polygon's sides, to be able to get their starting and ending points, is there a way?
the Graphics class only allows to draw but what you draw, as with the Shape class, are not objects, it's not a polygon with sides or whatever.
Am I being clear?
Thanks
There is no way to read the data of a Graphics object (which is essentially what contains the information that you are after.) This applies to any vector graphics object that has already been drawn, either by the Graphics/drawing API itself, or in Flash CS3/CS4, or was embedded using the [Embed] meta-tag.
Your best bet if you need to calculate the algebraic area, or for some other reason retain the vectors in your algorithms, is definitely exporting an SVG or some single-purpose format (like a CSV of the points) from Illustrator, and parsing that in ActionScript.
Another option is to use a BitmapData, and draw the Shape object onto that, then counting the colored (opaque) pixels to numerically calculate it's area.
var bmp : BitmapData = new BitmapData(myShape.width, myShape.height, true, 0);
bmp.draw(myShape);
var i : uint;
var area : uint = 0;
var num_pixels : uint = bmp.width*bmp.height;
for (i=0; i<num_pixels; i++) {
var px : uint = bmp.getPixel32(i%bmp.width, Math.floor(i/bmp.height));
// Determine from px color/alpha whether it's part of the shape or not.
// This particular if statement should determine whether the alpha
// component (first 8 bits of the px integer) are greater than zero, i.e.
// not transparent.
if ((px >> 24) > 0)
area++;
}
trace('number of opaque pixels (area): '+area);
Depending on your application, you might also be able to use the BitmapData.hitTest() method for your collision detection.
I believe the best you can do is to retrieve a rectangular bounding box on the Shape object. Depending on how you imported it, you may or may not have direct access to the Shape object as an instance variable; however, if you do, you can call shapeVar.transform.getBounds() or shapeVar.transform.getRect() (bounds returns a rectangle inclusive of strokes on the shape, rect does not).
I'm curious, so I'm doing a bit of research on alternate means of getting some pixel bounds. I'll edit this further if I find something useful.