You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

222 lines
6.4 KiB
Python

# -*- coding: utf-8 -*-
"""
Created on Thu Mar 1 14:32:08 2018
@author: z5030440
Main code to extract shorelines from Landsat imagery
"""
# Preamble
import ee
from IPython import display
import math
import matplotlib.pyplot as plt
import numpy as np
import pdb
# image processing modules
import skimage.filters as filters
import skimage.exposure as exposure
import skimage.transform as transform
import sklearn.decomposition as decomposition
import skimage.morphology as morphology
import skimage.measure as measure
from shapely.geometry import Polygon
from osgeo import gdal
from osgeo import osr
import tempfile
import urllib
from urllib.request import urlretrieve
import zipfile
# my modules
from utils import *
# from sds import *
np.seterr(all='ignore') # raise/ignore divisions by 0 and nans
ee.Initialize()
plot_bool = True # if you want the plots
def download_tif(image, bandsId):
"""downloads tif image (region and bands) from the ee server and stores it in a temp file"""
url = ee.data.makeDownloadUrl(ee.data.getDownloadId({
'image': image.serialize(),
'bands': bandsId,
'filePerBand': 'false',
'name': 'data',
}))
local_zip, headers = urlretrieve(url)
with zipfile.ZipFile(local_zip) as local_zipfile:
return local_zipfile.extract('data.tif', tempfile.mkdtemp())
def load_image(image, bandsId):
"""loads an ee.Image() as a np.array. e.Image() is retrieved from the EE database."""
local_tif_filename = download_tif(image, bandsId)
dataset = gdal.Open(local_tif_filename, gdal.GA_ReadOnly)
bands = [dataset.GetRasterBand(i + 1).ReadAsArray() for i in range(dataset.RasterCount)]
return np.stack(bands, 2), dataset
im = ee.Image('LANDSAT/LC08/C01/T1_RT_TOA/LC08_089083_20130411')
lon = [151.2820816040039, 151.3425064086914]
lat = [-33.68206818063878, -33.74775138989556]
polygon = [[lon[0], lat[0]], [lon[1], lat[0]], [lon[1], lat[1]], [lon[0], lat[1]]];
# get image metadata into dictionnary
im_dic = im.getInfo()
im_bands = im_dic.get('bands')
# delete dimensions key from dictionnary, otherwise the entire image is extracted
#for i in range(len(im_bands)): del im_bands[i]['dimensions']
pan_band = [im_bands[7]]
ms_bands = [im_bands[1], im_bands[2], im_bands[3]]
im_full, dataset_full = load_image(im, ms_bands)
plt.figure()
plt.imshow(np.clip(im_full[:,:,[2,1,0]] * 3, 0, 1))
plt.show()
#%%
def download_tif(image, polygon, bandsId):
"""downloads tif image (region and bands) from the ee server and stores it in a temp file"""
url = ee.data.makeDownloadUrl(ee.data.getDownloadId({
'image': image.serialize(),
'region': polygon,
'bands': bandsId,
'filePerBand': 'false',
'name': 'data',
}))
local_zip, headers = urlretrieve(url)
with zipfile.ZipFile(local_zip) as local_zipfile:
return local_zipfile.extract('data.tif', tempfile.mkdtemp())
def load_image(image, polygon, bandsId):
"""
Loads an ee.Image() as a np.array. e.Image() is retrieved from the EE database.
The geographic area and bands to select can be specified
KV WRL 2018
Arguments:
-----------
image: ee.Image()
image objec from the EE database
polygon: list
coordinates of the points creating a polygon. Each point is a list with 2 values
bandsId: list
bands to select, each band is a dictionnary in the list containing the following keys:
crs, crs_transform, data_type and id. NOTE: you have to remove the key dimensions, otherwise
the entire image is retrieved.
Returns:
-----------
image_array : np.ndarray
An array containing the image (2D if one band, otherwise 3D)
"""
local_tif_filename = download_tif(image, polygon, bandsId)
dataset = gdal.Open(local_tif_filename, gdal.GA_ReadOnly)
bands = [dataset.GetRasterBand(i + 1).ReadAsArray() for i in range(dataset.RasterCount)]
return np.stack(bands, 2), dataset
for i in range(len(im_bands)): del im_bands[i]['dimensions']
ms_bands = [im_bands[1], im_bands[2], im_bands[3]]
im_cropped, dataset_cropped = load_image(im, polygon, ms_bands)
plt.figure()
plt.imshow(np.clip(im_cropped[:,:,[2,1,0]] * 3, 0, 1))
plt.show()
#%%
crs_full = dataset_full.GetGeoTransform()
crs_cropped = dataset_cropped.GetGeoTransform()
scale = crs_full[1]
ul_full = np.array([crs_full[0], crs_full[3]])
ul_cropped = np.array([crs_cropped[0], crs_cropped[3]])
delta = np.abs(ul_full - ul_cropped)/scale
u0 = delta[0].astype('int')
v0 = delta[1].astype('int')
im_full[v0,u0,:]
im_cropped[0,0,:]
lrx = ul_cropped[0] + (dataset_cropped.RasterXSize * scale)
lry = ul_cropped[1] + (dataset_cropped.RasterYSize * (-scale))
lr_cropped = np.array([lrx, lry])
delta = np.abs(ul_full - lr_cropped)/scale
u1 = delta[0].astype('int')
v1 = delta[1].astype('int')
im_cropped2 = im_full[v0:v1,u0:u1,:]
#%%
crs_full = dataset_full.GetGeoTransform()
source = osr.SpatialReference()
source.ImportFromWkt(dataset_full.GetProjection())
target = osr.SpatialReference()
target.ImportFromEPSG(4326)
transform = osr.CoordinateTransformation(source, target)
transform.TransformPoint(ulx, uly)
#%%
crs_cropped = dataset_cropped.GetGeoTransform()
ulx = crs_cropped[0]
uly = crs_cropped[3]
source = osr.SpatialReference()
source.ImportFromWkt(dataset_cropped.GetProjection())
target = osr.SpatialReference()
target.ImportFromEPSG(4326)
transform = osr.CoordinateTransformation(source, target)
transform.TransformPoint(lrx, lry)
#%%
source = osr.SpatialReference()
source.ImportFromEPSG(4326)
target = osr.SpatialReference()
target.ImportFromEPSG(32656)
coords = transform.TransformPoint(151.2820816040039, -33.68206818063878)
coords[0] - ulx
coords[1] - uly
#%%
x_ul_full = ms_bands[0]['crs_transform'][2]
y_ul_full = ms_bands[0]['crs_transform'][5]
scale = ms_bands[0]['crs_transform'][0]
x_ul_cropped = np.array([340756.105840223, 346357.851288875, 346474.839525944, 340877.362938763])
y_ul_cropped = np.array([-3728229.45372866, -3728137.91775723, -3735421.58347927, -3735513.20696522])
dx = abs(x_ul_full - x_ul_cropped)
dy = abs(y_ul_full - y_ul_cropped)
u_coord = np.round(dx/scale).astype('int')
v_coord = np.round(dy/scale).astype('int')
im_cropped2 = im_full[np.min(v_coord):np.max(v_coord), np.min(u_coord):np.max(u_coord),:]
plt.figure()
plt.imshow(np.clip(im_cropped2[:,:,[2,1,0]] * 3, 0, 1), cmap='gray')
plt.show()
sum(sum(sum(np.equal(im_cropped,im_cropped2).astype('int')-1)))