├── .gitattributes ├── GEEWebInterface .ipynb ├── GEE_automatic_data_load.ipynb ├── GEE_basic_visualisation.ipynb ├── GEE_data_load.ipynb ├── GEE_feature_extraction.ipynb ├── GEE_histograms.ipynb ├── GEE_image_algebra.ipynb ├── GEE_image_classification.ipynb ├── GEE_installation.ipynb ├── GEE_linear_filters.ipynb ├── GEE_nonlinear_filters.ipynb ├── GEE_subset_export.ipynb ├── GEE_tutorial.ipynb ├── GEE_tutorial2.ipynb ├── GEE_tutorial3.ipynb ├── README.md ├── imageMulticlassification.ipynb ├── imageclass1.ipynb ├── images ├── GEE_overview.png ├── create_folder_gee.png ├── create_folder_gee2.png ├── filter_mean.png ├── filter_window.png ├── headerlogo.png ├── insert_image.png ├── kernel_definition.png ├── kernel_textures.png ├── kernel_textures_2.png ├── laplacian.png ├── laplacian2.png ├── legend_ndvi.png ├── out_test_install_gee.png ├── step1_inst.png ├── step2_inst.png ├── step4_inst.png ├── step5_inst.png ├── step6_inst.png ├── step7_inst.png ├── step8_inst.png ├── step9_inst.png ├── step_3_inst.png └── view_image_asset.png └── index.ipynb /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto -------------------------------------------------------------------------------- /GEEWebInterface .ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Overview of GEE web interface" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "Although we will use the python API of GEE, it is good to take a look to the GEE Javascript playground.\n", 15 | "We ca distinguish 4 main areas as the image below shows. \n", 16 | "1. Left panel. Here we have three tabs: scripts, asset and docs. \n", 17 | "2. Middle panel. A script editor.\n", 18 | "3. Right panel. It consist of three tabs: Inspector, console and tasks. \n", 19 | "4. Map area. We can add visualize data it in this section or edit features.
\n", 20 | "![alt text](/files/images/GEE_overview.png \"Create a folder in GEE\")" 21 | ] 22 | }, 23 | { 24 | "cell_type": "markdown", 25 | "metadata": {}, 26 | "source": [ 27 | "### Data Visualization" 28 | ] 29 | }, 30 | { 31 | "cell_type": "markdown", 32 | "metadata": {}, 33 | "source": [ 34 | "GEE has a large amount of Earth data free available for researchers. However, sometimes we need to process our own data." 35 | ] 36 | }, 37 | { 38 | "cell_type": "markdown", 39 | "metadata": {}, 40 | "source": [ 41 | "To add our data in GEE. We will create a new folder Tutorial \n", 42 | "![alt text](/files/images/create_folder_gee2.png \"Create a folder in GEE\")" 43 | ] 44 | }, 45 | { 46 | "cell_type": "markdown", 47 | "metadata": {}, 48 | "source": [ 49 | "We will load the image subset.tif . This is a subset of a Worldview-2 image and it was acquired in 2014.\n", 50 | "Load the image in your GEE asset as we see in the image below. For now, keep the default options.\n", 51 | "![alt text](/files/images/insert_image.png \"Insert image in the tutorial folder\")\n" 52 | ] 53 | }, 54 | { 55 | "cell_type": "markdown", 56 | "metadata": {}, 57 | "source": [ 58 | "Now that we can visualize the image loaded.\n", 59 | "To do this, we will execute the commands below" 60 | ] 61 | }, 62 | { 63 | "cell_type": "code", 64 | "execution_count": 1, 65 | "metadata": { 66 | "collapsed": true 67 | }, 68 | "outputs": [], 69 | "source": [ 70 | "import ee \n", 71 | "ee.Initialize() \n", 72 | "from IPython.display import Image # To display image thumbnails." 73 | ] 74 | }, 75 | { 76 | "cell_type": "code", 77 | "execution_count": 2, 78 | "metadata": { 79 | "collapsed": false 80 | }, 81 | "outputs": [ 82 | { 83 | "data": { 84 | "text/html": [ 85 | "" 86 | ], 87 | "text/plain": [ 88 | "" 89 | ] 90 | }, 91 | "execution_count": 2, 92 | "metadata": {}, 93 | "output_type": "execute_result" 94 | } 95 | ], 96 | "source": [ 97 | "# load our image \n", 98 | "image = ee.Image(\"users/rosamaguilar/tutorial/subset\")\n", 99 | "# display the image, The maximun pixel value is 2048 because it has 11-bit per pixel \n", 100 | "# the visualization in GEE is 8-bits. Then, min and max values are used to stretch \n", 101 | "Image(url=image.getThumbUrl({'min':0, 'max':2048})) " 102 | ] 103 | }, 104 | { 105 | "cell_type": "markdown", 106 | "metadata": {}, 107 | "source": [ 108 | "Above we have an image but there is no clue about which bands are displayed and their order. \n", 109 | "We can specify those parameters." 110 | ] 111 | }, 112 | { 113 | "cell_type": "code", 114 | "execution_count": 3, 115 | "metadata": { 116 | "collapsed": false 117 | }, 118 | "outputs": [ 119 | { 120 | "data": { 121 | "text/html": [ 122 | "" 123 | ], 124 | "text/plain": [ 125 | "" 126 | ] 127 | }, 128 | "execution_count": 3, 129 | "metadata": {}, 130 | "output_type": "execute_result" 131 | } 132 | ], 133 | "source": [ 134 | "# set band order RGB natural color composite\n", 135 | "# gamma corrections factors (one per band)\n", 136 | "Image(url=image.getThumbUrl({'min': 0, 'max': 2048,'bands': 'b5,b3,b2', 'gamma': '0.95, 1.1, 1'}))" 137 | ] 138 | }, 139 | { 140 | "cell_type": "markdown", 141 | "metadata": {}, 142 | "source": [ 143 | "You may try other band combinations and gamma factors." 144 | ] 145 | }, 146 | { 147 | "cell_type": "markdown", 148 | "metadata": {}, 149 | "source": [ 150 | "#### Visualize vector data" 151 | ] 152 | }, 153 | { 154 | "cell_type": "markdown", 155 | "metadata": {}, 156 | "source": [ 157 | "Assuming we have a kml file with our vector data, namely parcels\n", 158 | "We need to create a fusion table (ft) with that file. \n", 159 | "Afterward, we can use the id of the ft to create a GEE feature collection . " 160 | ] 161 | }, 162 | { 163 | "cell_type": "code", 164 | "execution_count": 5, 165 | "metadata": { 166 | "collapsed": true 167 | }, 168 | "outputs": [], 169 | "source": [ 170 | "# create the feature collection from the fusion table\n", 171 | "fc = ee.FeatureCollection ('ft:1K41m-umQ1K8Ys-9bVTqoEYzwKD6xEzIVTPELdVkK')" 172 | ] 173 | }, 174 | { 175 | "cell_type": "code", 176 | "execution_count": 6, 177 | "metadata": { 178 | "collapsed": false 179 | }, 180 | "outputs": [ 181 | { 182 | "name": "stdout", 183 | "output_type": "stream", 184 | "text": [ 185 | "['name', 'description', 'id', 'class', 'system:index']\n" 186 | ] 187 | } 188 | ], 189 | "source": [ 190 | "# listing the fields in the feature collection\n", 191 | "print(fc.first().propertyNames().getInfo())" 192 | ] 193 | }, 194 | { 195 | "cell_type": "code", 196 | "execution_count": 7, 197 | "metadata": { 198 | "collapsed": false 199 | }, 200 | "outputs": [ 201 | { 202 | "name": "stdout", 203 | "output_type": "stream", 204 | "text": [ 205 | "{'geo_column': 'geometry', 'type': 'FeatureCollection', 'columns': {'class': 'Number', 'description': 'String', 'name': 'String', 'id': 'Number'}, 'features': [{'id': '2', 'type': 'Feature', 'geometry': {'geodesic': True, 'type': 'Polygon', 'coordinates': [[[-5.199613999999999, 12.165225000000001], [-5.1990310000000015, 12.165136], [-5.198975, 12.165533], [-5.199543, 12.165571], [-5.199613999999999, 12.165225000000001]]]}, 'properties': {'class': 5.0, 'description': '', 'name': '', 'id': 1.0}}, {'id': '3', 'type': 'Feature', 'geometry': {'geodesic': True, 'type': 'Polygon', 'coordinates': [[[-5.201773, 12.16407], [-5.200976999999998, 12.164202999999999], [-5.201564, 12.164885], [-5.201773, 12.16407]]]}, 'properties': {'class': 2.0, 'description': '', 'name': '', 'id': 2.0}}, {'id': '4', 'type': 'Feature', 'geometry': {'geodesic': True, 'type': 'Polygon', 'coordinates': [[[-5.1967729999999985, 12.167687000000004], [-5.196262, 12.167743999999997], [-5.196262, 12.168028], [-5.196488999999999, 12.168256], [-5.1967729999999985, 12.168198999999996], [-5.1967729999999985, 12.167687000000004]]]}, 'properties': {'class': 4.0, 'description': '', 'name': '', 'id': 4.0}}, {'id': '5', 'type': 'Feature', 'geometry': {'geodesic': True, 'type': 'Polygon', 'coordinates': [[[-5.191319, 12.16193], [-5.191149, 12.161627], [-5.191149000000002, 12.161608], [-5.190921, 12.161874], [-5.191072999999999, 12.162120000000002], [-5.191186999999999, 12.162366000000002], [-5.191319, 12.16193]]]}, 'properties': {'class': 1.0, 'description': '', 'name': '', 'id': 5.0}}, {'id': '6', 'type': 'Feature', 'geometry': {'geodesic': True, 'type': 'Polygon', 'coordinates': [[[-5.197701, 12.169183], [-5.197038000000002, 12.169297000000006], [-5.197171, 12.169600000000003], [-5.197777, 12.169562], [-5.197701, 12.169183]]]}, 'properties': {'class': 5.0, 'description': '', 'name': '', 'id': 5.0}}, {'id': '7', 'type': 'Feature', 'geometry': {'geodesic': True, 'type': 'Polygon', 'coordinates': [[[-5.191678999999998, 12.166437000000004], [-5.191414, 12.166456], [-5.191452, 12.166665], [-5.191755, 12.166627], [-5.191678999999998, 12.166437000000004]]]}, 'properties': {'class': 1.0, 'description': '', 'name': '', 'id': 6.0}}, {'id': '8', 'type': 'Feature', 'geometry': {'geodesic': True, 'type': 'Polygon', 'coordinates': [[[-5.197019000000002, 12.165907], [-5.196754, 12.165888000000002], [-5.196696999999999, 12.166059000000002], [-5.196640999999999, 12.166059000000002], [-5.196564999999998, 12.166228999999998], [-5.197038000000002, 12.166153], [-5.197019000000002, 12.165907]]]}, 'properties': {'class': 3.0, 'description': '', 'name': '', 'id': 7.0}}, {'id': '9', 'type': 'Feature', 'geometry': {'geodesic': True, 'type': 'Polygon', 'coordinates': [[[-5.194178999999998, 12.160018000000003], [-5.194273, 12.160169000000003], [-5.194348999999999, 12.160377], [-5.194614, 12.160226], [-5.194178999999998, 12.160018000000003]]]}, 'properties': {'class': 4.0, 'description': '', 'name': '', 'id': 8.0}}, {'id': '10', 'type': 'Feature', 'geometry': {'geodesic': True, 'type': 'Polygon', 'coordinates': [[[-5.192569, 12.161523000000004], [-5.192304000000002, 12.161485], [-5.192304, 12.161694000000006], [-5.1926070000000015, 12.161750000000003], [-5.192569, 12.161523000000004]]]}, 'properties': {'class': 2.0, 'description': '', 'name': '', 'id': 9.0}}, {'id': '11', 'type': 'Feature', 'geometry': {'geodesic': True, 'type': 'Polygon', 'coordinates': [[[-5.198533999999999, 12.162147999999993], [-5.198724000000001, 12.161730999999996], [-5.198174, 12.161656], [-5.198023, 12.162053000000004], [-5.198533999999999, 12.162147999999993]]]}, 'properties': {'class': 3.0, 'description': '', 'name': '', 'id': 10.0}}, {'id': '12', 'type': 'Feature', 'geometry': {'geodesic': True, 'type': 'Polygon', 'coordinates': [[[-5.193653000000002, 12.16407], [-5.193397, 12.164189], [-5.1933880000000014, 12.164255], [-5.193691, 12.164193], [-5.193653000000002, 12.16407]]]}, 'properties': {'class': 3.0, 'description': '', 'name': '', 'id': 11.0}}, {'id': '13', 'type': 'Feature', 'geometry': {'geodesic': True, 'type': 'Polygon', 'coordinates': [[[-5.199652000000002, 12.167493], [-5.199652000000002, 12.167383999999997], [-5.199608999999998, 12.167313], [-5.1995, 12.167298999999998], [-5.199400999999998, 12.167331999999998], [-5.199396000000001, 12.167346999999994], [-5.199396000000001, 12.167441], [-5.199391, 12.167498], [-5.199348999999999, 12.167526], [-5.199254000000002, 12.167616], [-5.1995520000000015, 12.167640000000004], [-5.199652000000002, 12.167493]]]}, 'properties': {'class': 1.0, 'description': '', 'name': '', 'id': 12.0}}], 'id': 'ft:1K41m-umQ1K8Ys-9bVTqoEYzwKD6xEzIVTPELdVkK', 'properties': {'DocID': '1K41m-umQ1K8Ys-9bVTqoEYzwKD6xEzIVTPELdVkK', 'name': 'parcel'}}\n" 206 | ] 207 | } 208 | ], 209 | "source": [ 210 | "# getting information about the Feature collection\n", 211 | "print(fc.getInfo())" 212 | ] 213 | }, 214 | { 215 | "cell_type": "code", 216 | "execution_count": 8, 217 | "metadata": { 218 | "collapsed": false 219 | }, 220 | "outputs": [ 221 | { 222 | "name": "stdout", 223 | "output_type": "stream", 224 | "text": [ 225 | "{'id': '2', 'type': 'Feature', 'geometry': {'geodesic': True, 'type': 'Polygon', 'coordinates': [[[-5.199613999999999, 12.165225000000001], [-5.1990310000000015, 12.165136], [-5.198975, 12.165533], [-5.199543, 12.165571], [-5.199613999999999, 12.165225000000001]]]}, 'properties': {'class': 5.0, 'description': '', 'name': '', 'id': 1.0}}\n" 226 | ] 227 | } 228 | ], 229 | "source": [ 230 | "# getting information about one feature (the first)\n", 231 | "print(fc.first().getInfo())" 232 | ] 233 | }, 234 | { 235 | "cell_type": "code", 236 | "execution_count": 9, 237 | "metadata": { 238 | "collapsed": false 239 | }, 240 | "outputs": [ 241 | { 242 | "name": "stdout", 243 | "output_type": "stream", 244 | "text": [ 245 | "12\n" 246 | ] 247 | } 248 | ], 249 | "source": [ 250 | "# counting the number of features in the collection\n", 251 | "print(ee.Number(fc.aggregate_count('.all')).getInfo())" 252 | ] 253 | }, 254 | { 255 | "cell_type": "code", 256 | "execution_count": null, 257 | "metadata": { 258 | "collapsed": true 259 | }, 260 | "outputs": [], 261 | "source": [] 262 | } 263 | ], 264 | "metadata": { 265 | "kernelspec": { 266 | "display_name": "Python 3", 267 | "language": "python", 268 | "name": "python3" 269 | }, 270 | "language_info": { 271 | "codemirror_mode": { 272 | "name": "ipython", 273 | "version": 3 274 | }, 275 | "file_extension": ".py", 276 | "mimetype": "text/x-python", 277 | "name": "python", 278 | "nbconvert_exporter": "python", 279 | "pygments_lexer": "ipython3", 280 | "version": "3.5.1" 281 | } 282 | }, 283 | "nbformat": 4, 284 | "nbformat_minor": 2 285 | } 286 | -------------------------------------------------------------------------------- /GEE_automatic_data_load.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "collapsed": true 7 | }, 8 | "source": [ 9 | "______\n", 10 | "\n", 11 | "## Google Earth Engine Tutorial\n", 12 | "### Automatic data load\n", 13 | "_____" 14 | ] 15 | }, 16 | { 17 | "cell_type": "markdown", 18 | "metadata": {}, 19 | "source": [ 20 | "In a previous notebook data were load to a GEE asset using the Javascript interface. In this section, a script will be used to upload several images contained in a folder. " 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": 5, 26 | "metadata": { 27 | "collapsed": false 28 | }, 29 | "outputs": [ 30 | { 31 | "ename": "NameError", 32 | "evalue": "name 'username' is not defined", 33 | "output_type": "error", 34 | "traceback": [ 35 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 36 | "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", 37 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 122\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m 123\u001b[0m \u001b[1;31m#----------Main Section\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m--> 124\u001b[0;31m \u001b[0mgoogle\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mgoogle_authenticate\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0musername\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mpassword\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 125\u001b[0m \u001b[0mprint\u001b[0m \u001b[1;33m(\u001b[0m\u001b[1;34m'Authenticated'\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m 126\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", 38 | "\u001b[0;31mNameError\u001b[0m: name 'username' is not defined" 39 | ] 40 | } 41 | ], 42 | "source": [ 43 | "__author__ = 'yang'\n", 44 | "__maintainer__ = 'Raul Zurita-Milla' , 'Rosa Aguilar'\n", 45 | "__email__ = \"r.zurita-milla@utwente.nl\", \"rosamaguilar@gmail.com\"\n", 46 | "\n", 47 | "# -------------------------------------------------------------------------------\n", 48 | "# Name: gee_upload_asset_v3loop_v6\n", 49 | "# Purpose: Load Images to assets in GEE\n", 50 | "# \n", 51 | "# -------------------------------------------------------------------------------\n", 52 | "\n", 53 | "#----------IMPORTS & INITS\n", 54 | "import glob\n", 55 | "import requests\n", 56 | "from urllib import parse\n", 57 | "import os\n", 58 | "from os import path\n", 59 | "import ee\n", 60 | "from requests_toolbelt.multipart import encoder\n", 61 | "import logging\n", 62 | "import sys\n", 63 | "import ast\n", 64 | "from bs4 import BeautifulSoup\n", 65 | "\n", 66 | "os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'\n", 67 | "ee.Initialize()\n", 68 | "\n", 69 | "\n", 70 | "#--------------------Parameters-------------------------------------\n", 71 | "username = # your gmail account\n", 72 | "password = # your password\n", 73 | "\n", 74 | "\n", 75 | "\n", 76 | "# # ASSET folder or collection name and ASSET name:\n", 77 | "# your asset id\n", 78 | "asset_dir = \n", 79 | "# your local directory\n", 80 | "img_dir = \n", 81 | "# suffix for the file description that will be created for each image. This file will contain the assetid of the image in GEE \n", 82 | "name = \"_desc.txt\" # suffix\n", 83 | "\n", 84 | "\n", 85 | "\n", 86 | "#---------- Define URLs---------------------------------------------------\n", 87 | "google_accounts_url = 'https://accounts.google.com'\n", 88 | "authentication_url = 'https://accounts.google.com/ServiceLoginAuth'\n", 89 | "appspot_url = 'https://ee-api.appspot.com/assets/upload/geturl?'\n", 90 | "\n", 91 | "def google_authenticate(username, password):\n", 92 | " session = requests.session()\n", 93 | "\n", 94 | " login_html = session.get(google_accounts_url)\n", 95 | " soup_login = BeautifulSoup(login_html.content, 'html.parser').find('form').find_all('input')\n", 96 | " payload = {}\n", 97 | " for u in soup_login:\n", 98 | " if u.has_attr('value'):\n", 99 | " payload[u['name']] = u['value']\n", 100 | "\n", 101 | " payload['Email'] = username\n", 102 | " payload['Passwd'] = password\n", 103 | "\n", 104 | " auto = login_html.headers.get('X-Auto-Login')\n", 105 | " follow_up = parse.unquote(parse.unquote(auto)).split('continue=')[-1]\n", 106 | " galx = login_html.cookies['GALX']\n", 107 | "\n", 108 | " payload['continue'] = follow_up\n", 109 | " payload['GALX'] = galx\n", 110 | "\n", 111 | " session.post(authentication_url, data=payload)\n", 112 | " return session\n", 113 | "\n", 114 | "\n", 115 | "def get_uploadUrl(session):\n", 116 | " '''\n", 117 | " get the GEE asset upload url\n", 118 | " '''\n", 119 | " _ = session.get('https://ee-api.appspot.com/assets/upload/geturl?')\n", 120 | " r = session.get('https://ee-api.appspot.com/assets/upload/geturl?')\n", 121 | " if r.text.startswith('\\n'):\n", 122 | " logging.error('Incorrect credentials. Probably. If you are sure the credentials are OK, refresh the authentication token. '\n", 123 | " 'If it did not work report a problem. They might have changed something in the Matrix.')\n", 124 | " sys.exit(1)\n", 125 | " d = ast.literal_eval(r.text)\n", 126 | "\n", 127 | " return d['url']\n", 128 | "\n", 129 | "\n", 130 | "def upload_file(session, file_path, asset_name, use_multipart, properties=None, nodata=None):\n", 131 | "\n", 132 | " with open(file_path, 'rb') as f:\n", 133 | " upload_url = get_uploadUrl(session)\n", 134 | "\n", 135 | " if use_multipart:\n", 136 | " form = encoder.MultipartEncoder({\n", 137 | " \"documents\": (file_path, f, \"application/octet-stream\"),\n", 138 | " \"composite\": \"NONE\",\n", 139 | " })\n", 140 | " headers = {\"Prefer\": \"respond-async\", \"Content-Type\": form.content_type}\n", 141 | " resp = session.post(upload_url, headers=headers, data=form)\n", 142 | " else:\n", 143 | " files = {'file': f}\n", 144 | " resp = session.post(upload_url, files=files)\n", 145 | "\n", 146 | " gsid = resp.json()[0]\n", 147 | " asset_data = {\"id\": asset_name,\n", 148 | " \"tilesets\": [\n", 149 | " {\"sources\": [\n", 150 | " {\"primaryPath\": gsid,\n", 151 | " \"additionalPaths\": []\n", 152 | " }\n", 153 | " ]}\n", 154 | " ],\n", 155 | " \"bands\": [],\n", 156 | " \"properties\": properties,\n", 157 | " \"missingData\": {\"value\": 255}\n", 158 | " }\n", 159 | " return asset_data\n", 160 | "\n", 161 | "\n", 162 | "\n", 163 | "#----------Main Section\n", 164 | "username = ''\n", 165 | "password = ''\n", 166 | "\n", 167 | "google = google_authenticate(username, password)\n", 168 | "print ('Authenticated')\n", 169 | "\n", 170 | "# # ASSET folder or collection name and ASSET name:\n", 171 | "asset_dir = 'users/rosamaguilar/tutorial/'\n", 172 | "img_dir = 'E:/itc-stars/tutorial/uploadimages/'\n", 173 | "name = \"_Multi.txt\" # suffix\n", 174 | "os.chdir(img_dir)\n", 175 | "files = glob.glob('*.tif')\n", 176 | "# LOOP all TIF images in a given folder\n", 177 | "for n in range(0,len(files)):\n", 178 | " im = files[n]\n", 179 | " asset_name = asset_dir + files[n][:-4]\n", 180 | " print (\"asset\", n, asset_name)\n", 181 | " #Local file path\n", 182 | " img = img_dir + im #+'/'+ files[n]\n", 183 | " print (img)\n", 184 | " textFileName = img_dir + im[:-4] + name\n", 185 | " if os.path.isfile (textFileName):\n", 186 | " print (textFileName)\n", 187 | " print ('file already in GEE')\n", 188 | "\n", 189 | " else:\n", 190 | " print ('uploading file')\n", 191 | " asset_request = upload_file(google, img, asset_name, False)\n", 192 | " taskid = ee.data.newTaskId(1)[0]\n", 193 | " print ('ingesting...', taskid)\n", 194 | " ret = ee.data.startIngestion(taskid, asset_request)\n", 195 | " print ('ingesting...', ret)\n", 196 | " asset_request = 0\n", 197 | "\n", 198 | " with open(textFileName, \"w\") as text_file:\n", 199 | " text_file.write(str.format(asset_name))\n" 200 | ] 201 | }, 202 | { 203 | "cell_type": "code", 204 | "execution_count": null, 205 | "metadata": { 206 | "collapsed": true 207 | }, 208 | "outputs": [], 209 | "source": [] 210 | } 211 | ], 212 | "metadata": { 213 | "kernelspec": { 214 | "display_name": "Python 3", 215 | "language": "python", 216 | "name": "python3" 217 | }, 218 | "language_info": { 219 | "codemirror_mode": { 220 | "name": "ipython", 221 | "version": 3 222 | }, 223 | "file_extension": ".py", 224 | "mimetype": "text/x-python", 225 | "name": "python", 226 | "nbconvert_exporter": "python", 227 | "pygments_lexer": "ipython3", 228 | "version": "3.5.1" 229 | } 230 | }, 231 | "nbformat": 4, 232 | "nbformat_minor": 2 233 | } 234 | -------------------------------------------------------------------------------- /GEE_basic_visualisation.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "slideshow": { 7 | "slide_type": "slide" 8 | } 9 | }, 10 | "source": [ 11 | "______\n", 12 | "\n", 13 | "## Google Earth Engine Tutorial\n", 14 | "### Basic visualisation\n", 15 | "_____" 16 | ] 17 | }, 18 | { 19 | "cell_type": "markdown", 20 | "metadata": {}, 21 | "source": [ 22 | "To visualize an image, the following options, related to the image, can be specified:\n", 23 | " \n", 24 | "+ *bands*: \tList of three band names to be display in the RGB channels. This is relevant for multiband images.
\n", 25 | "+ *palette*:\tColor palette in a list of hexadecimal code strings. Apply to single-band images.
\n", 26 | "+ *opacity*: \tThe transparency of the layer (0.0 is fully transparent and 1.0 is fully opaque).
\n", 27 | "\n", 28 | "Besides, the following visualisation parameters can be specified:
\n", 29 | "+ *min*:\tValue(s) to map to 0.
\n", 30 | "+ *max*: \tValue(s) to map to 255.
\n", 31 | "+ *gain*: \tValue(s) by which to multiply each pixel value.
\n", 32 | "+ *bias*: \tValue(s) to add to each pixel value.
\n", 33 | "+ *gamma*: \tGamma correction factor(s).
\n", 34 | "\n", 35 | "The above parameters are applied per image band. When a multiband image is being displayed, using a single number means that it will be applied to the three bands. Otherwise, a list of three numbers, one for each band can be set.\n", 36 | "\n", 37 | "In GEE playground, an image can be displayed using the function *Map.addLayer* with parameters listed above. In this tutorial we will use the function *getThumbUrl* that generates a thumbnail url of the image preview. This preview will be open using *Image* from the package Ipython.display. \n", 38 | "\n", 39 | "Parameters for the thumbnail can be specified to generate the image. For example, it can be specified bands to display and additional parameters as follows:
\n", 40 | "+ *dimensions:* a pair of number specifying the maximum *Width*x*Height* dimensions of the thumbnail. If only one value is given, it is used as the maximum and the other dimension is computed proportionally.
\n", 41 | "+ *region:* region of the image to produce the thumbnail given as GeoJSON or coordinates.
\n", 42 | "+ *format:* format of the output given as a string ('png' or 'jpg').
\n", 43 | "\n", 44 | "In the following code we will visualize an image using *getThumbUrl*, later on we will apply the *folium* library. " 45 | ] 46 | }, 47 | { 48 | "cell_type": "code", 49 | "execution_count": 1, 50 | "metadata": { 51 | "collapsed": false 52 | }, 53 | "outputs": [], 54 | "source": [ 55 | "# import ee python package\n", 56 | "import ee \n", 57 | "ee.Initialize() \n", 58 | "# import Ipython.display for visualisation\n", 59 | "from IPython.display import Image " 60 | ] 61 | }, 62 | { 63 | "cell_type": "code", 64 | "execution_count": 2, 65 | "metadata": { 66 | "collapsed": false 67 | }, 68 | "outputs": [ 69 | { 70 | "name": "stdout", 71 | "output_type": "stream", 72 | "text": [ 73 | "https://earthengine.googleapis.com/api/thumb?thumbid=f8d71d599bc69699cf15fea443c10690&token=eac5fc716765cae9a7d144aea1753c62\n" 74 | ] 75 | }, 76 | { 77 | "data": { 78 | "text/html": [ 79 | "" 80 | ], 81 | "text/plain": [ 82 | "" 83 | ] 84 | }, 85 | "execution_count": 2, 86 | "metadata": {}, 87 | "output_type": "execute_result" 88 | } 89 | ], 90 | "source": [ 91 | "# load the image \n", 92 | "image = ee.Image(\"users/rosamaguilar/tutorial/subset\")\n", 93 | "# the maximun pixel value is 2048 because the image has 11-bit per pixel but we are \n", 94 | "# making an 8-bit display image, then the pixel values need to be stretch to fit in the range (0,255). \n", 95 | "url = image.getThumbUrl({'min':0, 'max':2048})\n", 96 | "# you could copy and paste this url in a browser to see the image \n", 97 | "print(url)\n", 98 | "# display image thumbnails.\n", 99 | "Image(url=url)" 100 | ] 101 | }, 102 | { 103 | "cell_type": "code", 104 | "execution_count": 3, 105 | "metadata": { 106 | "collapsed": false 107 | }, 108 | "outputs": [ 109 | { 110 | "name": "stdout", 111 | "output_type": "stream", 112 | "text": [ 113 | "['b1', 'b2', 'b3', 'b4', 'b5', 'b6', 'b7', 'b8']\n" 114 | ] 115 | } 116 | ], 117 | "source": [ 118 | "# We can specify the bands to make a RGB composite.\n", 119 | "# First, get the band names of the image\n", 120 | "names = image.bandNames();\n", 121 | "print(names.getInfo())" 122 | ] 123 | }, 124 | { 125 | "cell_type": "code", 126 | "execution_count": 4, 127 | "metadata": { 128 | "collapsed": false, 129 | "scrolled": true 130 | }, 131 | "outputs": [ 132 | { 133 | "data": { 134 | "text/html": [ 135 | "" 136 | ], 137 | "text/plain": [ 138 | "" 139 | ] 140 | }, 141 | "execution_count": 4, 142 | "metadata": {}, 143 | "output_type": "execute_result" 144 | } 145 | ], 146 | "source": [ 147 | "# As you may observe the image has 8 bands because is a World-view2 image.\n", 148 | "# We may want to select only the band in the visible range, this mean bands blue, green and red (bands: b2, b3,b5) \n", 149 | "# To display a RGB natural color composite, the band order must be set to [b5,b3,b2] \n", 150 | "# gamma corrections factors (one per band)\n", 151 | "Image(url=image.getThumbUrl({'min': 0, 'max': 2048,'bands': 'b5,b3,b2', 'gamma': '0.95, 1.1, 1'}))" 152 | ] 153 | }, 154 | { 155 | "cell_type": "code", 156 | "execution_count": 5, 157 | "metadata": { 158 | "collapsed": false 159 | }, 160 | "outputs": [ 161 | { 162 | "data": { 163 | "text/html": [ 164 | "" 165 | ], 166 | "text/plain": [ 167 | "" 168 | ] 169 | }, 170 | "execution_count": 5, 171 | "metadata": {}, 172 | "output_type": "execute_result" 173 | } 174 | ], 175 | "source": [ 176 | "# Apply \"false color\" composite\n", 177 | "Image(url=image.getThumbUrl({'min': 0, 'max': 2048,'bands': 'b7,b5,b3', 'gamma': '1, 1, 1'}))" 178 | ] 179 | }, 180 | { 181 | "cell_type": "markdown", 182 | "metadata": {}, 183 | "source": [ 184 | "You may try other band combinations and gamma factors." 185 | ] 186 | }, 187 | { 188 | "cell_type": "code", 189 | "execution_count": 6, 190 | "metadata": { 191 | "collapsed": false 192 | }, 193 | "outputs": [ 194 | { 195 | "name": "stdout", 196 | "output_type": "stream", 197 | "text": [ 198 | "['Red', 'Green', 'Blue']\n" 199 | ] 200 | } 201 | ], 202 | "source": [ 203 | "# We may want to create an image with a selected of bands. Also, we can rename band names \n", 204 | "# as can be seen as follows:\n", 205 | "#\n", 206 | "visimage = image.select( \n", 207 | " ['b5','b3','b2'], # current band names\n", 208 | " ['Red', 'Green', 'Blue'] # new band names\n", 209 | ")\n", 210 | "# print the new names \n", 211 | "print(visimage.bandNames().getInfo()) " 212 | ] 213 | }, 214 | { 215 | "cell_type": "markdown", 216 | "metadata": {}, 217 | "source": [ 218 | "#### Visualization using Folium" 219 | ] 220 | }, 221 | { 222 | "cell_type": "markdown", 223 | "metadata": {}, 224 | "source": [ 225 | "The function *getThumbUrl* is useful to display a preview of an image. But it is not possible to have any kind of interaction (zoom in, zoom out, etc). Besides, there is not an equivalent function to display vector layers (feature collections). To perform this tasks, we will used the [folium library](https://github.com/python-visualization/folium).\n", 226 | "\n", 227 | "A function based on folium to interact with GEE are available in https://github.com/python-visualization/folium_contrib/blob/master/GoogleEarthEngine_layer.ipynb\n", 228 | "\n", 229 | "For more information about folium, visit: https://github.com/python-visualization/folium\n" 230 | ] 231 | }, 232 | { 233 | "cell_type": "code", 234 | "execution_count": 7, 235 | "metadata": { 236 | "collapsed": true 237 | }, 238 | "outputs": [], 239 | "source": [ 240 | "# import GEE and foliumn\n", 241 | "import ee\n", 242 | "import folium\n", 243 | "ee.Initialize()" 244 | ] 245 | }, 246 | { 247 | "cell_type": "code", 248 | "execution_count": 8, 249 | "metadata": { 250 | "collapsed": true 251 | }, 252 | "outputs": [], 253 | "source": [ 254 | "# define a function to interact with GEE\n", 255 | "# from https://github.com/python-visualization/folium_contrib/blob/master/GoogleEarthEngine_layer.ipynb\n", 256 | "def folium_gee_layer(folium_map,image,vis_params=None,folium_kwargs={}):\n", 257 | " \"\"\" Function to add Google Earch Engine tile layer as a Folium layer.\n", 258 | " \n", 259 | " Parameters\n", 260 | " ----------\n", 261 | " folium_map : Folium map to add tile to.\n", 262 | " image : Google Earth Engine Image.\n", 263 | " vis_params : Dict with visualization parameters.\n", 264 | " folium_kwargs : Keyword args for Folium Map.\n", 265 | " \"\"\"\n", 266 | " # Get the MapID and Token after applying parameters\n", 267 | " image_info = image.getMapId(vis_params)\n", 268 | " mapid = image_info['mapid']\n", 269 | " token = image_info['token']\n", 270 | " print(folium_kwargs['overlay'])\n", 271 | " folium_kwargs['attr'] = ('Map Data © Google Earth Engine ')\n", 272 | " folium_kwargs['tiles'] = \"https://earthengine.googleapis.com/map/%s/{z}/{x}/{y}?token=%s\"%(mapid,token)\n", 273 | " \n", 274 | " layer = folium.TileLayer(**folium_kwargs)\n", 275 | " layer.add_to(folium_map)" 276 | ] 277 | }, 278 | { 279 | "cell_type": "markdown", 280 | "metadata": {}, 281 | "source": [ 282 | "\n", 283 | "In a previous step we upload an image to a GEE asset and a vector layer to a google drive as a feature table. \n", 284 | "We will visualize this layer using folium. First, the feature collection is retrieved in a GeoJson format. Later, it will be display in the folium map. \n" 285 | ] 286 | }, 287 | { 288 | "cell_type": "code", 289 | "execution_count": 9, 290 | "metadata": { 291 | "collapsed": false 292 | }, 293 | "outputs": [], 294 | "source": [ 295 | "# load the fusion table into a feature collection\n", 296 | "fc = ee.FeatureCollection ('ft:1K41m-umQ1K8Ys-9bVTqoEYzwKD6xEzIVTPELdVkK')\n", 297 | "geojs = fc.getDownloadURL(\"json\")\n", 298 | "\n", 299 | "# retrieve the fc as a json to display in the map\n", 300 | "import urllib\n", 301 | "with urllib.request.urlopen(geojs) as url:\n", 302 | " fcjs = url.read()\n", 303 | "fcjs = str(fcjs, 'utf-8') \n" 304 | ] 305 | }, 306 | { 307 | "cell_type": "code", 308 | "execution_count": 10, 309 | "metadata": { 310 | "collapsed": false 311 | }, 312 | "outputs": [ 313 | { 314 | "name": "stdout", 315 | "output_type": "stream", 316 | "text": [ 317 | "True\n" 318 | ] 319 | }, 320 | { 321 | "data": { 322 | "text/html": [ 323 | "
" 324 | ], 325 | "text/plain": [ 326 | "" 327 | ] 328 | }, 329 | "execution_count": 10, 330 | "metadata": {}, 331 | "output_type": "execute_result" 332 | } 333 | ], 334 | "source": [ 335 | "# create a folium map\n", 336 | "m1 = folium.Map([12.1724,-5.1874], zoom_start=14)\n", 337 | "# draw the vector layer \n", 338 | "folium.GeoJson(\n", 339 | " fcjs,\n", 340 | " name='Parcels',\n", 341 | " style_function=lambda feature: {\n", 342 | " 'fillColor': '#ff0000',\n", 343 | " 'color': 'black',\n", 344 | " 'weight': 1,\n", 345 | " 'fillOpacity': 0.7,\n", 346 | " }\n", 347 | ").add_to(m1)\n", 348 | "\n", 349 | "# load the image\n", 350 | "image = ee.Image(\"users/rosamaguilar/tutorial/subset\") \n", 351 | "\n", 352 | "# specify visualization parameters\n", 353 | "vis_params = {'min': 0, 'max':2048, 'bands':'b5,b3,b2'}\n", 354 | "\n", 355 | "# add the image \"subset\" using the function previoulsy defined\n", 356 | "folium_gee_layer(m1,image,vis_params,folium_kwargs={'overlay':True,'name':'Subset'})\n", 357 | "\n", 358 | "# add a control layer to the map\n", 359 | "m1.add_child(folium.LayerControl())\n", 360 | "\n", 361 | "# shows the map\n", 362 | "m1" 363 | ] 364 | } 365 | ], 366 | "metadata": { 367 | "kernelspec": { 368 | "display_name": "Python 3", 369 | "language": "python", 370 | "name": "python3" 371 | }, 372 | "language_info": { 373 | "codemirror_mode": { 374 | "name": "ipython", 375 | "version": 3 376 | }, 377 | "file_extension": ".py", 378 | "mimetype": "text/x-python", 379 | "name": "python", 380 | "nbconvert_exporter": "python", 381 | "pygments_lexer": "ipython3", 382 | "version": "3.5.1" 383 | } 384 | }, 385 | "nbformat": 4, 386 | "nbformat_minor": 2 387 | } 388 | -------------------------------------------------------------------------------- /GEE_data_load.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "______\n", 8 | "\n", 9 | "## Google Earth Engine Tutorial\n", 10 | "### Data loading\n", 11 | "_____" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": {}, 17 | "source": [ 18 | "GEE provides a playground or javascript interface where users can manage their assets, create scripts and visualize results. This interface is available in https://code.earthengine.google.com/. Although we will use the python API of GEE, in this part of the tutorial we will use the javascript interface to load data. Later on, we will learn how to do it programatically. \n" 19 | ] 20 | }, 21 | { 22 | "cell_type": "markdown", 23 | "metadata": {}, 24 | "source": [ 25 | "#### Overview of GEE web interface" 26 | ] 27 | }, 28 | { 29 | "cell_type": "markdown", 30 | "metadata": {}, 31 | "source": [ 32 | "We can distinguish 4 main areas as the image below shows. \n", 33 | "1. Left panel. Here we have three tabs: scripts, asset and docs. \n", 34 | "2. Middle panel. A script editor.\n", 35 | "3. Right panel. It consist of three tabs: Inspector, console and tasks. \n", 36 | "4. Map area. We can add visualize data it in this section or edit features.
\n", 37 | "![alt text](./images/GEE_overview.png \"Create a folder in GEE\")" 38 | ] 39 | }, 40 | { 41 | "cell_type": "markdown", 42 | "metadata": {}, 43 | "source": [ 44 | "#### Loading an image" 45 | ] 46 | }, 47 | { 48 | "cell_type": "markdown", 49 | "metadata": {}, 50 | "source": [ 51 | "GEE has a large amount of Earth data free available for researchers. However, sometimes we need to process our own data.To add our images in GEE. We will create a new folder **tutorial**.\n", 52 | "![alt text](./images/create_folder_gee2.png \"Create a folder in GEE\")" 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "execution_count": null, 58 | "metadata": { 59 | "collapsed": true 60 | }, 61 | "outputs": [], 62 | "source": [ 63 | "We will load the image *subset.tif* that is a subset of a Worldview-2 image and it was acquired in 2014.\n", 64 | "Load the image in your GEE asset as can be seen in the image below. For now, keep the default options.\n", 65 | "![alt text](./images/insert_image.png \"Insert image in the tutorial folder\")\n" 66 | ] 67 | }, 68 | { 69 | "cell_type": "markdown", 70 | "metadata": {}, 71 | "source": [ 72 | "Now that we can see the image loaded in the asset manager and look at its preview by clicking over it.
\n", 73 | "![alt text](./images/view_image_asset.png \"Insert image in the tutorial folder\")" 74 | ] 75 | }, 76 | { 77 | "cell_type": "markdown", 78 | "metadata": { 79 | "collapsed": true 80 | }, 81 | "source": [ 82 | "Besides of the preview, the window displays name, id, date, size, date of last modification and properties, if any, of the image. Per each band, we can observe the correspoding index, name, data type and dimensions in pixels. A more comprehensive metadata information can be obtained by using *getInfo()* as we can see in the following example:" 83 | ] 84 | }, 85 | { 86 | "cell_type": "code", 87 | "execution_count": 1, 88 | "metadata": { 89 | "collapsed": false 90 | }, 91 | "outputs": [ 92 | { 93 | "name": "stdout", 94 | "output_type": "stream", 95 | "text": [ 96 | "{'bands': [{'crs': 'EPSG:32630',\n", 97 | " 'crs_transform': [2.0009777545928955, 0.0, 260323.03819620793, 0.0,\n", 98 | " -2.0009777545928955, 1346325.1740949643],\n", 99 | " 'data_type': {'max': 65535,\n", 100 | " 'min': 0,\n", 101 | " 'precision': 'int',\n", 102 | " 'type': 'PixelType'},\n", 103 | " 'dimensions': [686, 563],\n", 104 | " 'id': 'b1'},\n", 105 | " {'crs': 'EPSG:32630',\n", 106 | " 'crs_transform': [2.0009777545928955, 0.0, 260323.03819620793, 0.0,\n", 107 | " -2.0009777545928955, 1346325.1740949643],\n", 108 | " 'data_type': {'max': 65535,\n", 109 | " 'min': 0,\n", 110 | " 'precision': 'int',\n", 111 | " 'type': 'PixelType'},\n", 112 | " 'dimensions': [686, 563],\n", 113 | " 'id': 'b2'},\n", 114 | " {'crs': 'EPSG:32630',\n", 115 | " 'crs_transform': [2.0009777545928955, 0.0, 260323.03819620793, 0.0,\n", 116 | " -2.0009777545928955, 1346325.1740949643],\n", 117 | " 'data_type': {'max': 65535,\n", 118 | " 'min': 0,\n", 119 | " 'precision': 'int',\n", 120 | " 'type': 'PixelType'},\n", 121 | " 'dimensions': [686, 563],\n", 122 | " 'id': 'b3'},\n", 123 | " {'crs': 'EPSG:32630',\n", 124 | " 'crs_transform': [2.0009777545928955, 0.0, 260323.03819620793, 0.0,\n", 125 | " -2.0009777545928955, 1346325.1740949643],\n", 126 | " 'data_type': {'max': 65535,\n", 127 | " 'min': 0,\n", 128 | " 'precision': 'int',\n", 129 | " 'type': 'PixelType'},\n", 130 | " 'dimensions': [686, 563],\n", 131 | " 'id': 'b4'},\n", 132 | " {'crs': 'EPSG:32630',\n", 133 | " 'crs_transform': [2.0009777545928955, 0.0, 260323.03819620793, 0.0,\n", 134 | " -2.0009777545928955, 1346325.1740949643],\n", 135 | " 'data_type': {'max': 65535,\n", 136 | " 'min': 0,\n", 137 | " 'precision': 'int',\n", 138 | " 'type': 'PixelType'},\n", 139 | " 'dimensions': [686, 563],\n", 140 | " 'id': 'b5'},\n", 141 | " {'crs': 'EPSG:32630',\n", 142 | " 'crs_transform': [2.0009777545928955, 0.0, 260323.03819620793, 0.0,\n", 143 | " -2.0009777545928955, 1346325.1740949643],\n", 144 | " 'data_type': {'max': 65535,\n", 145 | " 'min': 0,\n", 146 | " 'precision': 'int',\n", 147 | " 'type': 'PixelType'},\n", 148 | " 'dimensions': [686, 563],\n", 149 | " 'id': 'b6'},\n", 150 | " {'crs': 'EPSG:32630',\n", 151 | " 'crs_transform': [2.0009777545928955, 0.0, 260323.03819620793, 0.0,\n", 152 | " -2.0009777545928955, 1346325.1740949643],\n", 153 | " 'data_type': {'max': 65535,\n", 154 | " 'min': 0,\n", 155 | " 'precision': 'int',\n", 156 | " 'type': 'PixelType'},\n", 157 | " 'dimensions': [686, 563],\n", 158 | " 'id': 'b7'},\n", 159 | " {'crs': 'EPSG:32630',\n", 160 | " 'crs_transform': [2.0009777545928955, 0.0, 260323.03819620793, 0.0,\n", 161 | " -2.0009777545928955, 1346325.1740949643],\n", 162 | " 'data_type': {'max': 65535,\n", 163 | " 'min': 0,\n", 164 | " 'precision': 'int',\n", 165 | " 'type': 'PixelType'},\n", 166 | " 'dimensions': [686, 563],\n", 167 | " 'id': 'b8'}],\n", 168 | "'id': 'users/rosamaguilar/tutorial/subset',\n", 169 | "'properties': {'system:asset_size': 5839050,\n", 170 | " 'system:footprint': {'coordinates': [[-5.2025191570512765,\n", 171 | " 12.159825582803961],\n", 172 | " [-5.202516851635505,\n", 173 | " 12.159825459718073],\n", 174 | " [-5.189927460512273,\n", 175 | " 12.15992551735162],\n", 176 | " [-5.189919034443333,\n", 177 | " 12.159932901288647],\n", 178 | " [-5.189909729639849,\n", 179 | " 12.159939196772044],\n", 180 | " [-5.189909178271649,\n", 181 | " 12.159942159884043],\n", 182 | " [-5.189992426450091,\n", 183 | " 12.170105809735732],\n", 184 | " [-5.189999980265262,\n", 185 | " 12.17011404853716],\n", 186 | " [-5.190006422302447,\n", 187 | " 12.170123145052345],\n", 188 | " [-5.190008690214821,\n", 189 | " 12.17012354831131],\n", 190 | " [-5.190010995831953,\n", 191 | " 12.170123671499278],\n", 192 | " [-5.202600866228118,\n", 193 | " 12.170023527763393],\n", 194 | " [-5.202609292178024,\n", 195 | " 12.170016143418682],\n", 196 | " [-5.202618596995535,\n", 197 | " 12.170009847540083],\n", 198 | " [-5.20261914824336,\n", 199 | " 12.170006884346753],\n", 200 | " [-5.2025354210176005,\n", 201 | " 12.159843320651753],\n", 202 | " [-5.202527867137842,\n", 203 | " 12.159835082220859],\n", 204 | " [-5.202521425008991,\n", 205 | " 12.159825985989212],\n", 206 | " [-5.2025191570512765,\n", 207 | " 12.159825582803961]],\n", 208 | " 'type': 'LinearRing'}},\n", 209 | "'type': 'Image',\n", 210 | "'version': 1494355520584000}\n" 211 | ] 212 | } 213 | ], 214 | "source": [ 215 | "# import pretty print package\n", 216 | "import pprint\n", 217 | "# import earth engine (ee) python package\n", 218 | "import ee \n", 219 | "# Initialize the Earth Engine object, using the authentication credentials.\n", 220 | "ee.Initialize() \n", 221 | "# load the image \n", 222 | "image = ee.Image(\"users/rosamaguilar/tutorial/subset\")\n", 223 | "# print metadata\n", 224 | "pprint.pprint(image.getInfo(), indent = 0.2, compact = True )\n", 225 | "# please note that we should use getInfo to retrieve the value of a variable or object. " 226 | ] 227 | }, 228 | { 229 | "cell_type": "code", 230 | "execution_count": 2, 231 | "metadata": { 232 | "collapsed": false 233 | }, 234 | "outputs": [ 235 | { 236 | "name": "stdout", 237 | "output_type": "stream", 238 | "text": [ 239 | "['b1', 'b2', 'b3', 'b4', 'b5', 'b6', 'b7', 'b8']\n" 240 | ] 241 | } 242 | ], 243 | "source": [ 244 | "#List name of bands\n", 245 | "print(image.bandNames().getInfo())" 246 | ] 247 | }, 248 | { 249 | "cell_type": "code", 250 | "execution_count": 3, 251 | "metadata": { 252 | "collapsed": false 253 | }, 254 | "outputs": [ 255 | { 256 | "name": "stdout", 257 | "output_type": "stream", 258 | "text": [ 259 | "{'crs': 'EPSG:32630',\n", 260 | " 'transform': [2.0009777545928955,\n", 261 | " 0.0,\n", 262 | " 260323.03819620793,\n", 263 | " 0.0,\n", 264 | " -2.0009777545928955,\n", 265 | " 1346325.1740949643],\n", 266 | " 'type': 'Projection'}\n", 267 | "Image scale: 2.0009777545928955\n" 268 | ] 269 | } 270 | ], 271 | "source": [ 272 | "# print CRS information of the image \n", 273 | "pprint.pprint(image.projection().getInfo())\n", 274 | "# Retrieve scale of the image from its projecton\n", 275 | "imScale = image.projection().nominalScale()\n", 276 | "print('Image scale: ', imScale.getInfo())\n", 277 | "# for more information about scale in GEE, see the document: https://developers.google.com/earth-engine/scale" 278 | ] 279 | }, 280 | { 281 | "cell_type": "markdown", 282 | "metadata": {}, 283 | "source": [ 284 | "We will use this image later on for visualisation and other operations. " 285 | ] 286 | }, 287 | { 288 | "cell_type": "markdown", 289 | "metadata": {}, 290 | "source": [ 291 | "#### Loading vector data " 292 | ] 293 | }, 294 | { 295 | "cell_type": "markdown", 296 | "metadata": {}, 297 | "source": [ 298 | "A *feature* is defined in GEE as a [GeoJSON feature object](https://tools.ietf.org/html/rfc7946#section-3.2). This means that a feature is spatially bounded with *geometry* (can be null), *properties* and *id*. A *feature collection* in GEE is used to group a collection of related features. A *feature collection* may contain features, properties and other collections. \n", 299 | "\n", 300 | "There are several ways to create a feature collection. In this example we will load a data table [fusion table (ft)](fusiontables.google.com) into a feature collection. A ft can be created from CSV, KML files, spreadsheets (.xls, .xlsx, .ods and google), and other text-delimited files. After creating a fusion table we can use its id to create a GEE feature collection as can be see below. Shapefiles can also be uploaded to GEE
" 301 | ] 302 | }, 303 | { 304 | "cell_type": "code", 305 | "execution_count": 4, 306 | "metadata": { 307 | "collapsed": true 308 | }, 309 | "outputs": [], 310 | "source": [ 311 | "# Load feature collection from the fusion table \n", 312 | "fc = ee.FeatureCollection ('ft:1K41m-umQ1K8Ys-9bVTqoEYzwKD6xEzIVTPELdVkK')" 313 | ] 314 | }, 315 | { 316 | "cell_type": "code", 317 | "execution_count": 5, 318 | "metadata": { 319 | "collapsed": false 320 | }, 321 | "outputs": [ 322 | { 323 | "name": "stdout", 324 | "output_type": "stream", 325 | "text": [ 326 | "{'columns': {'class': 'Number',\n", 327 | " 'description': 'String',\n", 328 | " 'id': 'Number',\n", 329 | " 'name': 'String'},\n", 330 | " 'features': [{'geometry': {'coordinates': [[[-5.199613999999999,\n", 331 | " 12.165225000000001],\n", 332 | " [-5.1990310000000015, 12.165136],\n", 333 | " [-5.198975, 12.165533],\n", 334 | " [-5.199543, 12.165571],\n", 335 | " [-5.199613999999999,\n", 336 | " 12.165225000000001]]],\n", 337 | " 'geodesic': True,\n", 338 | " 'type': 'Polygon'},\n", 339 | " 'id': '2',\n", 340 | " 'properties': {'class': 5.0,\n", 341 | " 'description': '',\n", 342 | " 'id': 1.0,\n", 343 | " 'name': ''},\n", 344 | " 'type': 'Feature'},\n", 345 | " {'geometry': {'coordinates': [[[-5.201773, 12.16407],\n", 346 | " [-5.200976999999998,\n", 347 | " 12.164202999999999],\n", 348 | " [-5.201564, 12.164885],\n", 349 | " [-5.201773, 12.16407]]],\n", 350 | " 'geodesic': True,\n", 351 | " 'type': 'Polygon'},\n", 352 | " 'id': '3',\n", 353 | " 'properties': {'class': 2.0,\n", 354 | " 'description': '',\n", 355 | " 'id': 2.0,\n", 356 | " 'name': ''},\n", 357 | " 'type': 'Feature'},\n", 358 | " {'geometry': {'coordinates': [[[-5.1967729999999985,\n", 359 | " 12.167687000000004],\n", 360 | " [-5.196262, 12.167743999999997],\n", 361 | " [-5.196262, 12.168028],\n", 362 | " [-5.196488999999999, 12.168256],\n", 363 | " [-5.1967729999999985,\n", 364 | " 12.168198999999996],\n", 365 | " [-5.1967729999999985,\n", 366 | " 12.167687000000004]]],\n", 367 | " 'geodesic': True,\n", 368 | " 'type': 'Polygon'},\n", 369 | " 'id': '4',\n", 370 | " 'properties': {'class': 4.0,\n", 371 | " 'description': '',\n", 372 | " 'id': 4.0,\n", 373 | " 'name': ''},\n", 374 | " 'type': 'Feature'},\n", 375 | " {'geometry': {'coordinates': [[[-5.191319, 12.16193],\n", 376 | " [-5.191149, 12.161627],\n", 377 | " [-5.191149000000002, 12.161608],\n", 378 | " [-5.190921, 12.161874],\n", 379 | " [-5.191072999999999,\n", 380 | " 12.162120000000002],\n", 381 | " [-5.191186999999999,\n", 382 | " 12.162366000000002],\n", 383 | " [-5.191319, 12.16193]]],\n", 384 | " 'geodesic': True,\n", 385 | " 'type': 'Polygon'},\n", 386 | " 'id': '5',\n", 387 | " 'properties': {'class': 1.0,\n", 388 | " 'description': '',\n", 389 | " 'id': 5.0,\n", 390 | " 'name': ''},\n", 391 | " 'type': 'Feature'},\n", 392 | " {'geometry': {'coordinates': [[[-5.197701, 12.169183],\n", 393 | " [-5.197038000000002,\n", 394 | " 12.169297000000006],\n", 395 | " [-5.197171, 12.169600000000003],\n", 396 | " [-5.197777, 12.169562],\n", 397 | " [-5.197701, 12.169183]]],\n", 398 | " 'geodesic': True,\n", 399 | " 'type': 'Polygon'},\n", 400 | " 'id': '6',\n", 401 | " 'properties': {'class': 5.0,\n", 402 | " 'description': '',\n", 403 | " 'id': 5.0,\n", 404 | " 'name': ''},\n", 405 | " 'type': 'Feature'},\n", 406 | " {'geometry': {'coordinates': [[[-5.191678999999998,\n", 407 | " 12.166437000000004],\n", 408 | " [-5.191414, 12.166456],\n", 409 | " [-5.191452, 12.166665],\n", 410 | " [-5.191755, 12.166627],\n", 411 | " [-5.191678999999998,\n", 412 | " 12.166437000000004]]],\n", 413 | " 'geodesic': True,\n", 414 | " 'type': 'Polygon'},\n", 415 | " 'id': '7',\n", 416 | " 'properties': {'class': 1.0,\n", 417 | " 'description': '',\n", 418 | " 'id': 6.0,\n", 419 | " 'name': ''},\n", 420 | " 'type': 'Feature'},\n", 421 | " {'geometry': {'coordinates': [[[-5.197019000000002, 12.165907],\n", 422 | " [-5.196754, 12.165888000000002],\n", 423 | " [-5.196696999999999,\n", 424 | " 12.166059000000002],\n", 425 | " [-5.196640999999999,\n", 426 | " 12.166059000000002],\n", 427 | " [-5.196564999999998,\n", 428 | " 12.166228999999998],\n", 429 | " [-5.197038000000002, 12.166153],\n", 430 | " [-5.197019000000002, 12.165907]]],\n", 431 | " 'geodesic': True,\n", 432 | " 'type': 'Polygon'},\n", 433 | " 'id': '8',\n", 434 | " 'properties': {'class': 3.0,\n", 435 | " 'description': '',\n", 436 | " 'id': 7.0,\n", 437 | " 'name': ''},\n", 438 | " 'type': 'Feature'},\n", 439 | " {'geometry': {'coordinates': [[[-5.194178999999998,\n", 440 | " 12.160018000000003],\n", 441 | " [-5.194273, 12.160169000000003],\n", 442 | " [-5.194348999999999, 12.160377],\n", 443 | " [-5.194614, 12.160226],\n", 444 | " [-5.194178999999998,\n", 445 | " 12.160018000000003]]],\n", 446 | " 'geodesic': True,\n", 447 | " 'type': 'Polygon'},\n", 448 | " 'id': '9',\n", 449 | " 'properties': {'class': 4.0,\n", 450 | " 'description': '',\n", 451 | " 'id': 8.0,\n", 452 | " 'name': ''},\n", 453 | " 'type': 'Feature'},\n", 454 | " {'geometry': {'coordinates': [[[-5.192569, 12.161523000000004],\n", 455 | " [-5.192304000000002, 12.161485],\n", 456 | " [-5.192304, 12.161694000000006],\n", 457 | " [-5.1926070000000015,\n", 458 | " 12.161750000000003],\n", 459 | " [-5.192569, 12.161523000000004]]],\n", 460 | " 'geodesic': True,\n", 461 | " 'type': 'Polygon'},\n", 462 | " 'id': '10',\n", 463 | " 'properties': {'class': 2.0,\n", 464 | " 'description': '',\n", 465 | " 'id': 9.0,\n", 466 | " 'name': ''},\n", 467 | " 'type': 'Feature'},\n", 468 | " {'geometry': {'coordinates': [[[-5.198533999999999,\n", 469 | " 12.162147999999993],\n", 470 | " [-5.198724000000001,\n", 471 | " 12.161730999999996],\n", 472 | " [-5.198174, 12.161656],\n", 473 | " [-5.198023, 12.162053000000004],\n", 474 | " [-5.198533999999999,\n", 475 | " 12.162147999999993]]],\n", 476 | " 'geodesic': True,\n", 477 | " 'type': 'Polygon'},\n", 478 | " 'id': '11',\n", 479 | " 'properties': {'class': 3.0,\n", 480 | " 'description': '',\n", 481 | " 'id': 10.0,\n", 482 | " 'name': ''},\n", 483 | " 'type': 'Feature'},\n", 484 | " {'geometry': {'coordinates': [[[-5.193653000000002, 12.16407],\n", 485 | " [-5.193397, 12.164189],\n", 486 | " [-5.1933880000000014, 12.164255],\n", 487 | " [-5.193691, 12.164193],\n", 488 | " [-5.193653000000002, 12.16407]]],\n", 489 | " 'geodesic': True,\n", 490 | " 'type': 'Polygon'},\n", 491 | " 'id': '12',\n", 492 | " 'properties': {'class': 3.0,\n", 493 | " 'description': '',\n", 494 | " 'id': 11.0,\n", 495 | " 'name': ''},\n", 496 | " 'type': 'Feature'},\n", 497 | " {'geometry': {'coordinates': [[[-5.199652000000002, 12.167493],\n", 498 | " [-5.199652000000002,\n", 499 | " 12.167383999999997],\n", 500 | " [-5.199608999999998, 12.167313],\n", 501 | " [-5.1995, 12.167298999999998],\n", 502 | " [-5.199400999999998,\n", 503 | " 12.167331999999998],\n", 504 | " [-5.199396000000001,\n", 505 | " 12.167346999999994],\n", 506 | " [-5.199396000000001, 12.167441],\n", 507 | " [-5.199391, 12.167498],\n", 508 | " [-5.199348999999999, 12.167526],\n", 509 | " [-5.199254000000002, 12.167616],\n", 510 | " [-5.1995520000000015,\n", 511 | " 12.167640000000004],\n", 512 | " [-5.199652000000002, 12.167493]]],\n", 513 | " 'geodesic': True,\n", 514 | " 'type': 'Polygon'},\n", 515 | " 'id': '13',\n", 516 | " 'properties': {'class': 1.0,\n", 517 | " 'description': '',\n", 518 | " 'id': 12.0,\n", 519 | " 'name': ''},\n", 520 | " 'type': 'Feature'}],\n", 521 | " 'geo_column': 'geometry',\n", 522 | " 'id': 'ft:1K41m-umQ1K8Ys-9bVTqoEYzwKD6xEzIVTPELdVkK',\n", 523 | " 'properties': {'DocID': '1K41m-umQ1K8Ys-9bVTqoEYzwKD6xEzIVTPELdVkK',\n", 524 | " 'name': 'parcel'},\n", 525 | " 'type': 'FeatureCollection'}\n" 526 | ] 527 | } 528 | ], 529 | "source": [ 530 | "# getting information about the Feature collection\n", 531 | "pprint.pprint(fc.getInfo())" 532 | ] 533 | }, 534 | { 535 | "cell_type": "code", 536 | "execution_count": 6, 537 | "metadata": { 538 | "collapsed": false 539 | }, 540 | "outputs": [ 541 | { 542 | "name": "stdout", 543 | "output_type": "stream", 544 | "text": [ 545 | "['name', 'description', 'id', 'class', 'system:index']\n" 546 | ] 547 | } 548 | ], 549 | "source": [ 550 | "# listing the attributes in the feature collection\n", 551 | "print(fc.first().propertyNames().getInfo())" 552 | ] 553 | }, 554 | { 555 | "cell_type": "code", 556 | "execution_count": 7, 557 | "metadata": { 558 | "collapsed": false 559 | }, 560 | "outputs": [ 561 | { 562 | "name": "stdout", 563 | "output_type": "stream", 564 | "text": [ 565 | "{'geometry': {'coordinates': [[[-5.199613999999999, 12.165225000000001],\n", 566 | " [-5.1990310000000015, 12.165136],\n", 567 | " [-5.198975, 12.165533],\n", 568 | " [-5.199543, 12.165571],\n", 569 | " [-5.199613999999999, 12.165225000000001]]],\n", 570 | " 'geodesic': True,\n", 571 | " 'type': 'Polygon'},\n", 572 | " 'id': '2',\n", 573 | " 'properties': {'class': 5.0, 'description': '', 'id': 1.0, 'name': ''},\n", 574 | " 'type': 'Feature'}\n" 575 | ] 576 | } 577 | ], 578 | "source": [ 579 | "# getting information about one feature (the first)\n", 580 | "pprint.pprint(fc.first().getInfo())" 581 | ] 582 | }, 583 | { 584 | "cell_type": "markdown", 585 | "metadata": {}, 586 | "source": [ 587 | "This feature collection will be used in following sections. More details about size and file types in fusion tables can be found [here] (https://support.google.com/fusiontables/answer/171181)" 588 | ] 589 | } 590 | ], 591 | "metadata": { 592 | "kernelspec": { 593 | "display_name": "Python 3", 594 | "language": "python", 595 | "name": "python3" 596 | }, 597 | "language_info": { 598 | "codemirror_mode": { 599 | "name": "ipython", 600 | "version": 3 601 | }, 602 | "file_extension": ".py", 603 | "mimetype": "text/x-python", 604 | "name": "python", 605 | "nbconvert_exporter": "python", 606 | "pygments_lexer": "ipython3", 607 | "version": "3.5.1" 608 | } 609 | }, 610 | "nbformat": 4, 611 | "nbformat_minor": 2 612 | } 613 | -------------------------------------------------------------------------------- /GEE_feature_extraction.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "______\n", 8 | "\n", 9 | "## Google Earth Engine (GEE) Tutorial\n", 10 | "\n", 11 | "### Feature Extraction\n", 12 | "_____" 13 | ] 14 | }, 15 | { 16 | "cell_type": "markdown", 17 | "metadata": { 18 | "collapsed": true 19 | }, 20 | "source": [ 21 | "Extracting spectral or spatial information is not a uncommon task during processing of remotely sensed images because these information may improve classification results capturing additional information than spectral bands.
\n", 22 | "In the following lines of code, we will extract vegetation indices and textural features. " 23 | ] 24 | }, 25 | { 26 | "cell_type": "markdown", 27 | "metadata": {}, 28 | "source": [ 29 | "#### Vegetation indices" 30 | ] 31 | }, 32 | { 33 | "cell_type": "markdown", 34 | "metadata": {}, 35 | "source": [ 36 | "GEE has implemented a *normalizedDifference* function to compute the normalized difference between two bands. This function is used to compute the normalized vegetation index - [NDVI] (https://en.wikipedia.org/wiki/Normalized_Difference_Vegetation_Index). Given *b1* and *b2*, \n", 37 | "\n", 38 | "*normalizedDifference(b1,b2)* calculates *(b1 − b2 / (b1 + b2)*. " 39 | ] 40 | }, 41 | { 42 | "cell_type": "code", 43 | "execution_count": 10, 44 | "metadata": { 45 | "collapsed": false 46 | }, 47 | "outputs": [ 48 | { 49 | "data": { 50 | "text/html": [ 51 | "" 52 | ], 53 | "text/plain": [ 54 | "" 55 | ] 56 | }, 57 | "metadata": {}, 58 | "output_type": "display_data" 59 | }, 60 | { 61 | "data": { 62 | "image/png": "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\nAABJRU5ErkJggg==\n", 63 | "text/plain": [ 64 | "" 65 | ] 66 | }, 67 | "metadata": {}, 68 | "output_type": "display_data" 69 | } 70 | ], 71 | "source": [ 72 | "import ee\n", 73 | "import numpy as np\n", 74 | "from IPython.display import Image\n", 75 | "from IPython.display import display\n", 76 | "import pprint\n", 77 | "\n", 78 | "import matplotlib.pyplot as plt\n", 79 | "from matplotlib.colors import LinearSegmentedColormap\n", 80 | "from matplotlib import cm, colorbar\n", 81 | "from matplotlib import colors as mcolors\n", 82 | "\n", 83 | "ee.Initialize()\n", 84 | "image = ee.Image('users/rosamaguilar/tutorial/subset')\n", 85 | "# compute the normalized vegetation index using Infrared and red bands\n", 86 | "# NDVI = (NIR - red) / (NIR + red)\n", 87 | "\n", 88 | "ndvi = image.normalizedDifference(['b7', 'b5']).rename(['NDVI'])\n", 89 | "# ndvi.getInfo() will give a generic min and max of a normalized index datatype but not the real min and max for this image\n", 90 | "# A reducer will give those values\n", 91 | "mymax = ndvi.reduceRegion(\n", 92 | " reducer = ee.Reducer.minMax(),\n", 93 | " geometry = ndvi.geometry(),\n", 94 | " scale = 2,\n", 95 | " maxPixels = 10000000).getInfo()\n", 96 | "#print(mymax)\n", 97 | "\n", 98 | "# define a palette for visualization, greenest color imply higher values\n", 99 | "palette =','.join(['d7191c','fdae61','ffffbf','a6d96a','1a9641'])\n", 100 | "\n", 101 | "img1 = Image(url=ndvi.getThumbUrl({'min':mymax['NDVI_min'], 'max': mymax['NDVI_max'], 'palette':palette}))\n", 102 | "display(img1)\n", 103 | "\n", 104 | "# create the color bar\n", 105 | "\n", 106 | "# format the pallete \n", 107 | "palette = palette.split(',')\n", 108 | "color_list = list(map(lambda x: '#'+x.strip(), palette))\n", 109 | "# create a linear segmented colormap with the specified name from a given sequence of colors \n", 110 | "cmap_obj = LinearSegmentedColormap.from_list('palette', color_list)\n", 111 | "# apply a linear normalization to the palette using min and max\n", 112 | "cnorm = mcolors.Normalize(vmin=mymax['NDVI_min'], vmax=mymax['NDVI_max']) \n", 113 | "# draw a bar\n", 114 | "fig = plt.figure(figsize=(5, 0.5))\n", 115 | "ax = plt.subplot(111)\n", 116 | "cbar = colorbar.ColorbarBase(ax, norm=cnorm, orientation='horizontal', cmap=cmap_obj)\n", 117 | "plt.show();" 118 | ] 119 | }, 120 | { 121 | "cell_type": "markdown", 122 | "metadata": { 123 | "collapsed": true 124 | }, 125 | "source": [ 126 | "Other vegetation indices may involve additional computation rather than a normalized difference.
\n", 127 | "For those cases, GEE includes the *expression* function. The following example calculate the *Soild Adjusted Vegetation Index - SAVI*" 128 | ] 129 | }, 130 | { 131 | "cell_type": "code", 132 | "execution_count": 11, 133 | "metadata": { 134 | "collapsed": false 135 | }, 136 | "outputs": [ 137 | { 138 | "name": "stdout", 139 | "output_type": "stream", 140 | "text": [ 141 | "{'bands': [{'crs': 'EPSG:32630',\n", 142 | " 'crs_transform': [2.0009777545928955,\n", 143 | " 0.0,\n", 144 | " 260323.03819620793,\n", 145 | " 0.0,\n", 146 | " -2.0009777545928955,\n", 147 | " 1346325.1740949643],\n", 148 | " 'data_type': {'max': 196605.0,\n", 149 | " 'min': -196605.0,\n", 150 | " 'precision': 'double',\n", 151 | " 'type': 'PixelType'},\n", 152 | " 'dimensions': [686, 563],\n", 153 | " 'id': 'SAVI'}],\n", 154 | " 'type': 'Image'}\n", 155 | "{'SAVI_max': 1.4998188186979104, 'SAVI_min': -0.49665749115218244}\n" 156 | ] 157 | }, 158 | { 159 | "data": { 160 | "text/html": [ 161 | "" 162 | ], 163 | "text/plain": [ 164 | "" 165 | ] 166 | }, 167 | "metadata": {}, 168 | "output_type": "display_data" 169 | }, 170 | { 171 | "data": { 172 | "image/png": "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\nbAAAAABJRU5ErkJggg==\n", 173 | "text/plain": [ 174 | "" 175 | ] 176 | }, 177 | "metadata": {}, 178 | "output_type": "display_data" 179 | } 180 | ], 181 | "source": [ 182 | "# SAVI veg_index <- (1+L)*(y[,nir] - y[,red])/(y[,nir] + y[,red] + L)\n", 183 | "# L=0.5\n", 184 | "image = ee.Image('users/rosamaguilar/tutorial/subset')\n", 185 | "savi = image.expression (\n", 186 | " '( 1.5)* (NIR -R)/(NIR + R + 0.5)', {\n", 187 | " 'NIR': image.select('b7'),\n", 188 | " 'R': image.select('b5'), \n", 189 | " }).rename(['SAVI'])\n", 190 | "\n", 191 | "pprint.pprint(savi.getInfo())\n", 192 | "palette =','.join(['d7191c','fdae61','ffffbf','a6d96a','1a9641'])\n", 193 | "# A reducer to get minimum and maximum values\n", 194 | "mymax = savi.reduceRegion(reducer = ee.Reducer.minMax(),geometry = savi.geometry(),scale = 2, maxPixels = 10000000).getInfo()\n", 195 | "print(mymax)\n", 196 | "img1 = Image(url=savi.getThumbUrl({'min':mymax['SAVI_min'], 'max': mymax['SAVI_max'], 'palette':palette}))\n", 197 | "display(img1)\n", 198 | "\n", 199 | "# create the color bar\n", 200 | "palette = palette.split(',')\n", 201 | "color_list = list(map(lambda x: '#'+x.strip(), palette))\n", 202 | "cmap_obj = LinearSegmentedColormap.from_list('palette', color_list)\n", 203 | "cnorm = mcolors.Normalize(vmin=mymax['SAVI_min'], vmax=mymax['SAVI_max']) \n", 204 | "fig = plt.figure(figsize=(5, 0.5))\n", 205 | "ax = plt.subplot(111)\n", 206 | "cbar = colorbar.ColorbarBase(ax, norm=cnorm, orientation='horizontal', cmap=cmap_obj)\n", 207 | "plt.show();\n" 208 | ] 209 | }, 210 | { 211 | "cell_type": "markdown", 212 | "metadata": {}, 213 | "source": [ 214 | "You may try to compute the *TCARI - Transformed Chlorophyll Absorption in Reflectance Index*
\n", 215 | "Its formula is: TCARI = 3*((red_edge-red)-0.2*(red_edge-green)*(red_edge/red))\n" 216 | ] 217 | }, 218 | { 219 | "cell_type": "markdown", 220 | "metadata": {}, 221 | "source": [ 222 | "#### Textural Features \n" 223 | ] 224 | }, 225 | { 226 | "cell_type": "markdown", 227 | "metadata": {}, 228 | "source": [ 229 | "Textural features provide information about the spatial distribution of the spectral information in an image band. One of the most common methods to compute textural features uses the [*Gray Level Co-occurrence Matrix (GLCM)*](http://haralick.org/journals/TexturalFeatures.pdf). Textural features may be not intuitive to the human eye but several studies have showed their contribution in image classification.
\n", 230 | "\n", 231 | "In GEE the function *glcm* compute 18 textural features per band image.
\n", 232 | "The following parameters can be specified: \n", 233 | "\n", 234 | "+ *size*: the inter-pixel distance to used in the calculation. Defaul value is 1.\n", 235 | "+ *kernel*: defines the offsets to use in the calculation. The default value is a 3x3 square kernel with four directions offsets: (-1, -1), (0, -1), (1, -1) and (-1, 0). Figure below illustrate the default kernel.\n", 236 | "+ *average*:
indicates if the bands resulting of the four direction calculations will be averaged. Default values is True.\n", 237 | "![alt text](./images/kernel_textures_2.png)\n", 238 | "\n", 239 | " \n", 240 | "\n" 241 | ] 242 | }, 243 | { 244 | "cell_type": "code", 245 | "execution_count": 12, 246 | "metadata": { 247 | "collapsed": false, 248 | "scrolled": false 249 | }, 250 | "outputs": [ 251 | { 252 | "name": "stdout", 253 | "output_type": "stream", 254 | "text": [ 255 | "['b1_asm', 'b1_contrast', 'b1_corr', 'b1_var', 'b1_idm', 'b1_savg', 'b1_svar', 'b1_sent', 'b1_ent', 'b1_dvar', 'b1_dent', 'b1_imcorr1', 'b1_imcorr2', 'b1_maxcorr', 'b1_diss', 'b1_inertia', 'b1_shade', 'b1_prom', 'b2_asm', 'b2_contrast', 'b2_corr', 'b2_var', 'b2_idm', 'b2_savg', 'b2_svar', 'b2_sent', 'b2_ent', 'b2_dvar', 'b2_dent', 'b2_imcorr1', 'b2_imcorr2', 'b2_maxcorr', 'b2_diss', 'b2_inertia', 'b2_shade', 'b2_prom', 'b3_asm', 'b3_contrast', 'b3_corr', 'b3_var', 'b3_idm', 'b3_savg', 'b3_svar', 'b3_sent', 'b3_ent', 'b3_dvar', 'b3_dent', 'b3_imcorr1', 'b3_imcorr2', 'b3_maxcorr', 'b3_diss', 'b3_inertia', 'b3_shade', 'b3_prom', 'b4_asm', 'b4_contrast', 'b4_corr', 'b4_var', 'b4_idm', 'b4_savg', 'b4_svar', 'b4_sent', 'b4_ent', 'b4_dvar', 'b4_dent', 'b4_imcorr1', 'b4_imcorr2', 'b4_maxcorr', 'b4_diss', 'b4_inertia', 'b4_shade', 'b4_prom', 'b5_asm', 'b5_contrast', 'b5_corr', 'b5_var', 'b5_idm', 'b5_savg', 'b5_svar', 'b5_sent', 'b5_ent', 'b5_dvar', 'b5_dent', 'b5_imcorr1', 'b5_imcorr2', 'b5_maxcorr', 'b5_diss', 'b5_inertia', 'b5_shade', 'b5_prom', 'b6_asm', 'b6_contrast', 'b6_corr', 'b6_var', 'b6_idm', 'b6_savg', 'b6_svar', 'b6_sent', 'b6_ent', 'b6_dvar', 'b6_dent', 'b6_imcorr1', 'b6_imcorr2', 'b6_maxcorr', 'b6_diss', 'b6_inertia', 'b6_shade', 'b6_prom', 'b7_asm', 'b7_contrast', 'b7_corr', 'b7_var', 'b7_idm', 'b7_savg', 'b7_svar', 'b7_sent', 'b7_ent', 'b7_dvar', 'b7_dent', 'b7_imcorr1', 'b7_imcorr2', 'b7_maxcorr', 'b7_diss', 'b7_inertia', 'b7_shade', 'b7_prom', 'b8_asm', 'b8_contrast', 'b8_corr', 'b8_var', 'b8_idm', 'b8_savg', 'b8_svar', 'b8_sent', 'b8_ent', 'b8_dvar', 'b8_dent', 'b8_imcorr1', 'b8_imcorr2', 'b8_maxcorr', 'b8_diss', 'b8_inertia', 'b8_shade', 'b8_prom']\n" 256 | ] 257 | } 258 | ], 259 | "source": [ 260 | "glcm = image.glcmTexture()\n", 261 | "# print the band names\n", 262 | "print(glcm.bandNames().getInfo())" 263 | ] 264 | }, 265 | { 266 | "cell_type": "markdown", 267 | "metadata": {}, 268 | "source": [ 269 | "Visualize textural features \n", 270 | "\n", 271 | "Minimun and maximum values of each band must be explored to set the visualization parameters.
\n", 272 | "To find those values we will apply a reducer over the whole image.
\n" 273 | ] 274 | }, 275 | { 276 | "cell_type": "code", 277 | "execution_count": 13, 278 | "metadata": { 279 | "collapsed": false 280 | }, 281 | "outputs": [ 282 | { 283 | "name": "stdout", 284 | "output_type": "stream", 285 | "text": [ 286 | "{'b5_corr_min': -0.8908995196420346, 'b5_corr_max': 0.4371934208813961}\n" 287 | ] 288 | } 289 | ], 290 | "source": [ 291 | "# Compute min and max of b5 correlation \n", 292 | "print(glcm.select('b5_corr').reduceRegion(ee.Reducer.minMax()).getInfo())" 293 | ] 294 | }, 295 | { 296 | "cell_type": "code", 297 | "execution_count": 14, 298 | "metadata": { 299 | "collapsed": false 300 | }, 301 | "outputs": [ 302 | { 303 | "data": { 304 | "text/html": [ 305 | "" 306 | ], 307 | "text/plain": [ 308 | "" 309 | ] 310 | }, 311 | "execution_count": 14, 312 | "metadata": {}, 313 | "output_type": "execute_result" 314 | } 315 | ], 316 | "source": [ 317 | "# lets define a new palette:\n", 318 | "#palette =','.join(['d7191c','5120b2'])\n", 319 | "palette =','.join(['d7191c','ffffbf'])\n", 320 | "Image(url=glcm.select('b5_corr').getThumbUrl({'min':-0.9, 'max': 0.43, 'palette':palette}))" 321 | ] 322 | }, 323 | { 324 | "cell_type": "code", 325 | "execution_count": 15, 326 | "metadata": { 327 | "collapsed": false 328 | }, 329 | "outputs": [ 330 | { 331 | "name": "stdout", 332 | "output_type": "stream", 333 | "text": [ 334 | "{'b7_ent_max': 2.2821740957339185, 'b7_ent_min': 1.0397207708399179}\n" 335 | ] 336 | }, 337 | { 338 | "data": { 339 | "text/html": [ 340 | "" 341 | ], 342 | "text/plain": [ 343 | "" 344 | ] 345 | }, 346 | "execution_count": 15, 347 | "metadata": {}, 348 | "output_type": "execute_result" 349 | } 350 | ], 351 | "source": [ 352 | "# Visualize Entropy of the Infrared band (b7):\n", 353 | "min_max = glcm.select('b7_ent').reduceRegion(ee.Reducer.minMax()).getInfo()\n", 354 | "print(glcm.select('b7_ent').reduceRegion(ee.Reducer.minMax()).getInfo())\n", 355 | "min = min_max['b7_ent_min']\n", 356 | "max = min_max['b7_ent_max']\n", 357 | "Image(url=glcm.select('b7_ent').getThumbUrl({'min': min, 'max': max, 'palette':palette}))" 358 | ] 359 | }, 360 | { 361 | "cell_type": "code", 362 | "execution_count": 16, 363 | "metadata": { 364 | "collapsed": false 365 | }, 366 | "outputs": [ 367 | { 368 | "name": "stdout", 369 | "output_type": "stream", 370 | "text": [ 371 | "{'b3_idm_max': 0.3987935532418258, 'b3_idm_min': 6.894451501972257e-07}\n" 372 | ] 373 | }, 374 | { 375 | "data": { 376 | "text/html": [ 377 | "" 378 | ], 379 | "text/plain": [ 380 | "" 381 | ] 382 | }, 383 | "execution_count": 16, 384 | "metadata": {}, 385 | "output_type": "execute_result" 386 | } 387 | ], 388 | "source": [ 389 | "# Visualize Homogeneity (Inverse Different Moment) of the green band (b3):\n", 390 | "palette =','.join(['d7191c','ffffbf'])\n", 391 | "min_max = glcm.select('b3_idm').reduceRegion(ee.Reducer.minMax()).getInfo()\n", 392 | "print(glcm.select('b3_idm').reduceRegion(ee.Reducer.minMax()).getInfo())\n", 393 | "min = min_max['b3_idm_min']\n", 394 | "max = min_max['b3_idm_max']\n", 395 | "Image(url=glcm.select('b3_idm').getThumbUrl({'min': min, 'max': max, 'palette':palette}))" 396 | ] 397 | }, 398 | { 399 | "cell_type": "code", 400 | "execution_count": null, 401 | "metadata": { 402 | "collapsed": true 403 | }, 404 | "outputs": [], 405 | "source": [] 406 | } 407 | ], 408 | "metadata": { 409 | "kernelspec": { 410 | "display_name": "Python 3", 411 | "language": "python", 412 | "name": "python3" 413 | }, 414 | "language_info": { 415 | "codemirror_mode": { 416 | "name": "ipython", 417 | "version": 3 418 | }, 419 | "file_extension": ".py", 420 | "mimetype": "text/x-python", 421 | "name": "python", 422 | "nbconvert_exporter": "python", 423 | "pygments_lexer": "ipython3", 424 | "version": "3.5.1" 425 | } 426 | }, 427 | "nbformat": 4, 428 | "nbformat_minor": 2 429 | } 430 | -------------------------------------------------------------------------------- /GEE_image_algebra.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "______\n", 8 | "\n", 9 | "## Google Earth Engine Tutorial\n", 10 | "### Image Algebra\n", 11 | "_____" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": {}, 17 | "source": [ 18 | "In this notebook image algebra will be illustrated by calculating losses on NDVIs given two images acquired in different dates over the same study area. First, NDVIs will be extracted. Second, these indices will be filtered to keep only the positive values (vegetation presence). Third, the difference between positive indices is calculated and again is filtered to keep only the losses. Finally, a mask will be created to expose areas where the NDVI had losses. " 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 8, 24 | "metadata": { 25 | "collapsed": false 26 | }, 27 | "outputs": [ 28 | { 29 | "data": { 30 | "text/html": [ 31 | "" 32 | ], 33 | "text/plain": [ 34 | "" 35 | ] 36 | }, 37 | "metadata": {}, 38 | "output_type": "display_data" 39 | }, 40 | { 41 | "data": { 42 | "text/html": [ 43 | "" 44 | ], 45 | "text/plain": [ 46 | "" 47 | ] 48 | }, 49 | "metadata": {}, 50 | "output_type": "display_data" 51 | }, 52 | { 53 | "data": { 54 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAa0AAABOCAYAAACT8UmvAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAAPYQAAD2EBqD+naQAADDVJREFUeJzt3XusHGUZx/HvU1qqhYCJBWqClYIWWgMFQQTDxVCwoBEC\nKBiDNuCtgQQJIjcVFIxaQzBivOAfoICiEREpGglQsUWKkqZQrK2F0tILLVhKL/S09LKPf7zvOfvu\n7GzP2e1sZyf8Pslpz5l9Z+Y37/ueeXZn55xj7o6IiEgVDCs7gIiIyFCpaImISGWoaImISGWoaImI\nSGWoaImISGWoaImISGWoaImISGWoaImISGUM78ZGzWwsMLob2xYRkcpY6+7Li9ygFf0bMcxs7KhR\nb3upr29rodsVEZHK6QMmFFm4uvFKa3Rf31buvud6JhwxFgDHyZbGUCw9Pg64N7d1Br5K/yVp46HR\nwKMDjyTF2En25eSu27Dnpv3mbCeTub4smzB+5fU2jftJDpacNvjAoTQkasiYbMUzfe05bZJjbd5m\nfubssubl6XHnHUe6G2/KnM2YHl+2TX6C5F9vPtpM87C0aaw8mTbZkcmZe8kcDl837TEuy597ufPc\noZbmzJnb2XmWtql5fp76NuoPphkb9tPmPtM5Uctpk6ya2X7yvetQS/qgvl4mZ4v8ALWcdQfbZ3+b\n2pD2mRxHtv9y+rhp7Fv0TS2nb3LnjOfPmRq07Je8MU7ncGOf5Y9r09inuXPnTdjOjjWbWf/LhaMI\nV916umgBMGHCWD5wzHig+SQF/QOQdkrOSSnbJuekFCZhOmE8WTdp0zAJPFm33ia/aKUngdaZd3kc\ntCpag2dsnEi7OI6cjP1fD3ocOf2azbzL4xhCxmybdjJm27TO2OI4kjz1lrsuWk3F15M2bWRsGKeh\nnPQ8/8SfPYnknQCdetHKthl0/0nbWpv7TNt0nN0bi1brfspfDmH9dveZFq2hjE2rNvnZM+sWPWbt\nZs/Zf1q02h2z2hDadINuxBARkcpQ0RIRkcpQ0RIRkcpQ0RIRkcpQ0RIRkcpQ0RIRkcpQ0RIRkcpQ\n0RIRkcpQ0RIRkcpQ0RIRkcpQ0RIRkcpQ0RIRkcpQ0RIRkcpQ0RIRkcpQ0RIRkcpQ0RIRkcpQ0RIR\nkcpQ0RIRkcpQ0RIRkcpQ0RIRkcpQ0RIRkcpQ0RIRkcpQ0RIRkcpQ0RIRkcpQ0RIRkcpQ0RIRkcpQ\n0RIRkcpQ0RIRkcpQ0RIRkcp4yxWtP/xudtkRcs24759lR2jp4T/OKztCS4//aUHZEVp68qHny46Q\na95fl5QdoaXFjy0rO0JLK2atKDtCS6/NebnsCHvMW65o3f/73ixaD/Vw0Xqkl4vWjP+UHaGlOT1a\ntJ55+MWyI7S0eObysiO0tHL2yrIjtLRuzuqyI+wxb7miJSIi1aWiJSIilaGiJSIilTG8WxteuHA5\nePjc8f5PB7g7/Q08LGhu6wx8lf5L0sZDo4FHBx7x+h6d+r42bOjj2XkvNq3bsOem/TZvJ5u5viyb\nMH7l9TaN+wk2bdzCgmdeam6DDxxKQ6KGjMmxeqavPadNcqzN22zOvGnjVhbNX9mwrLFv0oyNfdSQ\npmE+NGbOZkyPL9sm3e/mjVt54d9rGo/Gm482EzgsbRorT6ZN43FmZlySKc3YuMe+TW+ydMH/klyN\nMzh3njvU0pw5czs7z9I2Nc/PU98GbH1jG6sWrU2OI7OfNveZzolaTptk1cz2k+9dhxrOm5u38eri\ndcl63pgzObh0OUAt+bzpuFvss79NLbNe3j63b97O+iXr4/Jsm8Y+rudKxr5F39Ry+iZ3znj+nKkB\nO/u2s3nZhqZ+yRvjdA439ln+uDaNfZo7d96E7exYs5lusHTCFbJBs7HAYmBkoRsWEZGqeRMY7+6F\n3WFTeNGCgcI1uvANi4hIlawtsmBBl4qWiIhIN+hGDBERqQwVLRERqQwVLRERqQwVLRERqYyOipaZ\nXWZmS81si5k9ZWYfHKT9p8xsYWz/rJmd1VncYrOZ2UQzuy+2r5nZ5T2S6wtmNsvM1sWPRwbr4z2Y\n7Vwze9rMXjezN8xsnpld1AvZMut9Oo7p/b2Qzcymxjw74/81M+srO1dsv7+Z/cTMXjazrWa2yMzO\nLDubmf0t6av0Y0bZ2WL7K2Jf9ZnZcjO71cy68qM+bfbbcDO7wcxeiO3nmdmULmQ62cweNLNVcVzO\nHsI6HzGzuXGeLTazqW3v2N3b+gAuBLYCnwOOAG4H1gGjW7T/MLAduBI4HLiJcO/+xHb33YVsxwHT\ngQuAVcDlRWfqMNfdwDTgKGA8cAfwOvCuHsh2CnBOHMtxwOVxfM8oO1uy3iHACuBx4P4eGdOpcQwP\nAA6MHwf0QK4RwNPADOAEYCxwMnBkD2R7R9JXBwIT41z7bA9k+wywJa43Fjg9nkNu6YFs0+P8nxK/\nF6YBfcCkgnOdSTifnwPsBM4epP0hwBvAD+L547JOzh2dBH0K+FHytQErgatbtP8t8GBm2Rzgp10Y\n3LayZdZdSveKVse5YvthwAbgol7LFteZC3y7F7LFvnoCuBi4k+4VrXa/D6YC67qRZTdzTQOeB/bq\ntWw5618BrAfeXnY24MfAI5lltwCzeiDbKmBaZtl9wF1dHNvaEIrWdGB+Ztm9wF/a2VdblwfNbARw\nLPBY/zIPe34UOLHFaifGx1MP76J9RzrM1nUF5dqH8Ix43WAN93Q2M5tMeDX49x7JdiPwirvfWWSe\ngrLta2bL4qWkB8xsYg/k+gTxSaSZrTGz58zsOjMr9P3ugr4PLgHudfctPZDtSeDY/st0ZnYo8DHg\nzz2QbSThalZqC3BSkdk6cAIF1IJ2f/fgaGAv4JXM8lcIL/fyjGnRfkyb+x5MJ9n2hCJyTSc8e8oO\n+O7qKJuZ7RfzjAR2AJe6+8yys5nZSYRXWJMKzpLVSb/9l3DSnQ/sD3wNeNLMJrp7UX/Br5NchwKn\nAfcAZwHvBX5GODfcXFCuTrMNMLPjgfcTxrdobWdz93vNbDTwhJlZXP/n7j697GyEQnClmc0GlhAu\nXZ5H+TfetaoF+5nZSHfPFtpcXfuFuVIMM7uW8J7bqe6+rew80SZCYdgXmAz80MxedPdZZQUys32B\nu4AvuvvrZeVoxd2fIlzmAcDM5gALgS8TXh2WZRjhxPGl+Ax+npkdDFxFsUVrd30eeM7d55YdBMIN\nBcD1hMur/yIU+9vMbLW7f6fMbMBXgF8AiwiX7ZYQ3he/pMxQRWm3aK0lvOF2UGb5QcCaFuusabN9\npzrJtid0nMvMrgKuBia7ezf+rnxH2eLJrf/P386Pl7muA4osWu1mOwx4DzAjPvOF+MzSzLYBh7v7\n0pKyNXH3HWY2j3CyK0onuVYD2+KY9lsIjDGz4e6+o8RsAJjZKMLNCN8oKEtWJ9luIrxH1H8ZekF8\n4nQ7UGTRajubu68FzjOzvYF3uvtqM/s+9e/ZsrSqBRuH+ioL2ny56O7bCW+6T+5fFk8QkwnXePPM\nSdtHZ8TlhekwW9d1msvMrga+Dkxx9678vfsC+2wYBf9W/w6yLQSOBI4mvAqcBDwIzIyfrygxW5P4\nntGRhKJRZq5/0Fw4DwdWF1iwdrfPLgD2Bn5dVJ4Cso2i/ldF+tWSdcvM1r/utliwRgDnAw8UlatD\nebXgo7RbCzq4S+QCwu2T6e2XrxFv3yVcovlu0v5EwpuC/be8f4tw+2Y3bnlvN9sIwgntaMJ7NNPj\n14eVnOua2EfnEp6J9H/s0wN9di3hGvm42P6rcXwvLjtbzvrdvHuw3X77JuHJ2jjgGMJdU5uBI0rO\ndTDhjrzbgPcBHyc8I7627D5L1psN/KYb47gb/XZj7LcLCbdyn0G4C7PwnB1kOz6eO8YRfnzhUeAF\nYL+Cc+1D/fxZI9zdOQl4d3z8e8CvkvaHEN5amE6oBZcC24DT29pvh2EvBZYR7kiZAxyXPDYTuCPT\n/nzC9dUthDeip3Rx8g05G+FyUo3w8jv9mFlyrqU5mXYCN/RAn91MuKlgM+HSxRPAJ3thPHPW7VrR\n6qDfbo3jugV4mfBzUUeVnSsu+xDhWXsf4cR7DfEvQPRAtvFx7p/WrXHscDyHEZ6ILI7fC8sIhb/Q\nwtBhtlOABXE8X43fB2O6kOlU8s+fd8TH7yRzLo3Z5sbjeJ4OfuZOf5pEREQqo+xbIEVERIZMRUtE\nRCpDRUtERCpDRUtERCpDRUtERCpDRUtERCpDRUtERCpDRUtERCpDRUtERCpDRUtERCpDRUtERCpD\nRUtERCrj/9WotWZgGHLyAAAAAElFTkSuQmCC\n", 55 | "text/plain": [ 56 | "" 57 | ] 58 | }, 59 | "metadata": {}, 60 | "output_type": "display_data" 61 | } 62 | ], 63 | "source": [ 64 | "# Now we will like to dismiss the gaining vegetation and only take into account the losses\n", 65 | "# Losses mean than vegetation index in jul was higher than vegetation index in nov\n", 66 | "import ee\n", 67 | "ee.Initialize()\n", 68 | "from IPython.display import Image\n", 69 | "from IPython.display import display\n", 70 | "\n", 71 | "imgjuls = ee.Image('users/rosamaguilar/tutorial/imgjul')\n", 72 | "imgnovs = ee.Image('users/rosamaguilar/tutorial/imgnov')\n", 73 | "\n", 74 | "ndvijul = imgjuls.normalizedDifference(['b7', 'b5']).rename(['NDVI'])\n", 75 | "ndvinov = imgnovs.normalizedDifference(['b7', 'b5']).rename(['NDVI'])\n", 76 | "\n", 77 | "ndvijul_positive = ndvijul.where(ndvijul.lte(0),0) # to keep positive values\n", 78 | "ndvinov_positive = ndvinov.where(ndvinov.lte(0),0) # to keep positive values\n", 79 | "# define a palette for visualization, greenest color imply higher values\n", 80 | "palette =','.join(['ffffbf','a6d96a','1a9641'])\n", 81 | "\n", 82 | "img1 = Image(url =ndvijul_positive.getThumbUrl({'min': 0, 'max': 1, 'palette':palette }))\n", 83 | "img2 = Image(url =ndvinov_positive.getThumbUrl({'min': 0, 'max': 1, 'palette':palette }))\n", 84 | "display(img1,img2)\n", 85 | "\n", 86 | "\n", 87 | "# create the color bar\n", 88 | "import matplotlib.pyplot as plt\n", 89 | "from matplotlib.colors import LinearSegmentedColormap\n", 90 | "from matplotlib import cm, colorbar\n", 91 | "from matplotlib import colors as mcolors\n", 92 | "\n", 93 | "\n", 94 | "# format the pallete \n", 95 | "palette = palette.split(',')\n", 96 | "color_list = list(map(lambda x: '#'+x.strip(), palette))\n", 97 | "# create a linear segmented colormap with the specified name from a given sequence of colors \n", 98 | "cmap_obj = LinearSegmentedColormap.from_list('palette', color_list)\n", 99 | "# apply a linear normalization to the palette using min and max\n", 100 | "cnorm = mcolors.Normalize(vmin=0, vmax=1) \n", 101 | "# draw a bar\n", 102 | "fig = plt.figure(figsize=(5, 0.5))\n", 103 | "ax = plt.subplot(111)\n", 104 | "cbar = colorbar.ColorbarBase(ax, norm=cnorm, orientation='horizontal', cmap=cmap_obj)\n", 105 | "plt.show();" 106 | ] 107 | }, 108 | { 109 | "cell_type": "code", 110 | "execution_count": 5, 111 | "metadata": { 112 | "collapsed": false 113 | }, 114 | "outputs": [ 115 | { 116 | "data": { 117 | "text/html": [ 118 | "" 119 | ], 120 | "text/plain": [ 121 | "" 122 | ] 123 | }, 124 | "execution_count": 5, 125 | "metadata": {}, 126 | "output_type": "execute_result" 127 | } 128 | ], 129 | "source": [ 130 | "# Calculate the difference\n", 131 | "vi_diff = ndvijul_positive.subtract(ndvinov_positive) \n", 132 | "# create a mask \n", 133 | "mask = ee.Image(1).toByte().clip(vi_diff.geometry())\n", 134 | "mask = mask.where(vi_diff.gte(0),0) \n", 135 | "\n", 136 | "# apply the mask to the last image (nov) \n", 137 | "imgnovmasked = imgnovs.mask(mask) \n", 138 | "# transparent pixels are areas where vegetation had gain or remain equal\n", 139 | "Image(url=imgnovmasked.getThumbUrl({'min': 0, 'max': 2048,'bands': 'b5,b3,b2'}))" 140 | ] 141 | }, 142 | { 143 | "cell_type": "code", 144 | "execution_count": null, 145 | "metadata": { 146 | "collapsed": true 147 | }, 148 | "outputs": [], 149 | "source": [] 150 | } 151 | ], 152 | "metadata": { 153 | "kernelspec": { 154 | "display_name": "Python 3", 155 | "language": "python", 156 | "name": "python3" 157 | }, 158 | "language_info": { 159 | "codemirror_mode": { 160 | "name": "ipython", 161 | "version": 3 162 | }, 163 | "file_extension": ".py", 164 | "mimetype": "text/x-python", 165 | "name": "python", 166 | "nbconvert_exporter": "python", 167 | "pygments_lexer": "ipython3", 168 | "version": "3.5.1" 169 | } 170 | }, 171 | "nbformat": 4, 172 | "nbformat_minor": 2 173 | } 174 | -------------------------------------------------------------------------------- /GEE_image_classification.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "______\n", 8 | "\n", 9 | "## Google Earth Engine Tutorial\n", 10 | "### Image Classification\n", 11 | "_____" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": { 17 | "collapsed": true 18 | }, 19 | "source": [ 20 | "Image classification means mapping the values captured by remote sensors that are encoded as image digital levels to specific land cover types.
\n", 21 | "Classifying remotely sensed data into a thematic map is a relevant task beacuse the resulting information is the basis for many environmental and socioeconomic applications. In this example, a crop map type is produced by applying a [*supervised*](https://en.wikipedia.org/wiki/Supervised_learning) [*Random Forest*](https://en.wikipedia.org/wiki/Random_forest) algorithm. " 22 | ] 23 | }, 24 | { 25 | "cell_type": "markdown", 26 | "metadata": {}, 27 | "source": [ 28 | "#### Supervised Classification" 29 | ] 30 | }, 31 | { 32 | "cell_type": "markdown", 33 | "metadata": {}, 34 | "source": [ 35 | "A supervised classification method consists of training a classifier (algorithm) using (ground) truth data to classify subsequently unseen data.
\n", 36 | "The process flow in a supervised classification includes basically, the following steps:\n", 37 | "* Collect the ground data. This data is used to train the classifier and validate its results.\n", 38 | "* Train the classifier.\n", 39 | "* Apply the classifier to produce a classified image.\n", 40 | "* Assess the classification accuracy." 41 | ] 42 | }, 43 | { 44 | "cell_type": "code", 45 | "execution_count": 6, 46 | "metadata": { 47 | "collapsed": false 48 | }, 49 | "outputs": [ 50 | { 51 | "data": { 52 | "text/html": [ 53 | "" 54 | ], 55 | "text/plain": [ 56 | "" 57 | ] 58 | }, 59 | "execution_count": 6, 60 | "metadata": {}, 61 | "output_type": "execute_result" 62 | } 63 | ], 64 | "source": [ 65 | "import ee\n", 66 | "from IPython.display import Image\n", 67 | "ee.Initialize()\n", 68 | "# Load the image\n", 69 | "image= ee.Image('users/rosamaguilar/tutorial/subset')\n", 70 | "Image(url=image.getThumbUrl({'min': 0, 'max': 2048,'bands': 'b5,b3,b2'}))" 71 | ] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "execution_count": 7, 76 | "metadata": { 77 | "collapsed": false 78 | }, 79 | "outputs": [], 80 | "source": [ 81 | "# Two fusion tables previously created will be used for training set and a testing set. These tables contain ground truth data\n", 82 | "# Load tables into feature collection\n", 83 | "TR = ee.FeatureCollection('ft:11shsjBBaQQq-gTWd4M3QGl32GF47_eT5GVcQaKYO')\n", 84 | "TS = ee.FeatureCollection('ft:1O8qBNitB6Z3iyrX5-B0mA2I1HnH05Qw8cDmsbaNj')" 85 | ] 86 | }, 87 | { 88 | "cell_type": "code", 89 | "execution_count": 8, 90 | "metadata": { 91 | "collapsed": false 92 | }, 93 | "outputs": [ 94 | { 95 | "name": "stdout", 96 | "output_type": "stream", 97 | "text": [ 98 | "['b2', 'b3', 'b4', 'b5', 'b6', 'b7', 'b8', 'b1']\n" 99 | ] 100 | } 101 | ], 102 | "source": [ 103 | "# get feature names to use in classification\n", 104 | "feats = TR.first().propertyNames()\n", 105 | "# remove AA_Class that is the label, system:index that is an internal attribute and myid that is not relevant for classification\n", 106 | "feats = feats.removeAll(['AA_Class','myid','system:index']) \n", 107 | "print(feats.getInfo())" 108 | ] 109 | }, 110 | { 111 | "cell_type": "code", 112 | "execution_count": 9, 113 | "metadata": { 114 | "collapsed": false 115 | }, 116 | "outputs": [ 117 | { 118 | "name": "stdout", 119 | "output_type": "stream", 120 | "text": [ 121 | "Confusion Matrix for testing set\n", 122 | "[[108, 34, 6, 11, 15],\n", 123 | " [31, 134, 16, 34, 9],\n", 124 | " [24, 22, 47, 16, 4],\n", 125 | " [19, 38, 14, 120, 26],\n", 126 | " [14, 31, 4, 26, 130]]\n", 127 | "RF OA: 0.5777063236870311 RF kappa: 0.46405811934410174\n" 128 | ] 129 | } 130 | ], 131 | "source": [ 132 | "import pprint\n", 133 | "# define an train Random Forest clasifier\n", 134 | "rf = ee.Classifier.randomForest(10).train(TR, \"AA_Class\", feats) \n", 135 | "# apply the classifier to the training test for accuracy assessment\n", 136 | "result = TS.classify(rf, \"rfclass\")\n", 137 | "# Calculate the confusion matrix\n", 138 | "error = result.errorMatrix('AA_Class', 'rfclass')\n", 139 | "errMatrix = error.array().slice(0, 1, 6).slice(1, 1, 6)\n", 140 | "print(\"Confusion Matrix for testing set\")\n", 141 | "pprint.pprint(errMatrix.getInfo())\n", 142 | "# Extract Overall accuracy and kappa coefficient\n", 143 | "rf_oa_ts = result.errorMatrix('AA_Class', 'rfclass').accuracy().getInfo()\n", 144 | "rf_kappa_ts = result.errorMatrix('AA_Class', 'rfclass').kappa().getInfo()\n", 145 | "print(\"RF OA: \",rf_oa_ts, \"RF kappa: \",rf_kappa_ts )" 146 | ] 147 | }, 148 | { 149 | "cell_type": "code", 150 | "execution_count": 10, 151 | "metadata": { 152 | "collapsed": false 153 | }, 154 | "outputs": [ 155 | { 156 | "data": { 157 | "text/html": [ 158 | "" 159 | ], 160 | "text/plain": [ 161 | "" 162 | ] 163 | }, 164 | "execution_count": 10, 165 | "metadata": {}, 166 | "output_type": "execute_result" 167 | } 168 | ], 169 | "source": [ 170 | "# classify the image and display result\n", 171 | "classified = image.classify(rf, \"rfclass\")\n", 172 | "clas_col = ','.join(['000000','bdc3c7','1e8449','d68910','2ecc71','f9e79f']) \n", 173 | "Image(url = classified.getThumbUrl({'min': 0, 'max': 5, 'palette':clas_col}))\n" 174 | ] 175 | }, 176 | { 177 | "cell_type": "markdown", 178 | "metadata": { 179 | "collapsed": true 180 | }, 181 | "source": [ 182 | "Classification result could be improved by adding more data such as vegetation indices and textural features. You may try to perform a new classification considering those features." 183 | ] 184 | }, 185 | { 186 | "cell_type": "code", 187 | "execution_count": null, 188 | "metadata": { 189 | "collapsed": true 190 | }, 191 | "outputs": [], 192 | "source": [] 193 | } 194 | ], 195 | "metadata": { 196 | "kernelspec": { 197 | "display_name": "Python 3", 198 | "language": "python", 199 | "name": "python3" 200 | }, 201 | "language_info": { 202 | "codemirror_mode": { 203 | "name": "ipython", 204 | "version": 3 205 | }, 206 | "file_extension": ".py", 207 | "mimetype": "text/x-python", 208 | "name": "python", 209 | "nbconvert_exporter": "python", 210 | "pygments_lexer": "ipython3", 211 | "version": "3.5.1" 212 | } 213 | }, 214 | "nbformat": 4, 215 | "nbformat_minor": 2 216 | } 217 | -------------------------------------------------------------------------------- /GEE_installation.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "______\n", 8 | "\n", 9 | "## Google Earth Engine Tutorial\n", 10 | "### Installation\n", 11 | "_____\n", 12 | "\n" 13 | ] 14 | }, 15 | { 16 | "cell_type": "markdown", 17 | "metadata": {}, 18 | "source": [ 19 | "This tutorial includes basic operations that can be executed using the Pyhton API of Google Earth Engine (GEE) on Windows. \n", 20 | "GEE is a cloud platform to perform large scale analysis on Earth science data." 21 | ] 22 | }, 23 | { 24 | "cell_type": "markdown", 25 | "metadata": {}, 26 | "source": [ 27 | "## Python API Installation " 28 | ] 29 | }, 30 | { 31 | "cell_type": "markdown", 32 | "metadata": {}, 33 | "source": [ 34 | "\n", 35 | "Before the installation, you should sign up in GEE. \n", 36 | "This can be done in: https://signup.earthengine.google.com.\n", 37 | "\n", 38 | "We will use python 3.5 or higher and pip.\n", 39 | "Visit https://www.python.org/ for instructions on python installation and https://pip.pypa.io/en/stable/installing/ for instructions on pip installation. \n", 40 | "Ensure you have upgraded pip (you can run in a console: python -m pip install -U pip) \n", 41 | "\n", 42 | "In a windows console, execute the following steps:\n", 43 | "\n", 44 | "(1) pip install google-api-python-client:
\n", 45 | "\n", 46 | "![alt text](./images/step1_inst.png)" 47 | ] 48 | }, 49 | { 50 | "cell_type": "markdown", 51 | "metadata": {}, 52 | "source": [ 53 | "(2) pip install earthengine-api
\n", 54 | "![alt text](./images/step2_inst.png)" 55 | ] 56 | }, 57 | { 58 | "cell_type": "markdown", 59 | "metadata": {}, 60 | "source": [ 61 | "(3) earthengine authenticate
\n", 62 | "![alt text](./images/step_3_inst.png)\n" 63 | ] 64 | }, 65 | { 66 | "cell_type": "markdown", 67 | "metadata": {}, 68 | "source": [ 69 | "(4) The above instruction will open a browser and request to sign using your google account (if you are not already signed).
\n", 70 | "![alt text](./images/step4_inst.png) " 71 | ] 72 | }, 73 | { 74 | "cell_type": "markdown", 75 | "metadata": {}, 76 | "source": [ 77 | "(5) The GEE athenticator will also ask for permission to manage your data.
\n", 78 | "![alt text](./images/step5_inst.png)" 79 | ] 80 | }, 81 | { 82 | "cell_type": "markdown", 83 | "metadata": {}, 84 | "source": [ 85 | "(6) After giving permission, GEE will provide a token.
\n", 86 | "\n", 87 | "![alt text](./images/step6_inst.png)" 88 | ] 89 | }, 90 | { 91 | "cell_type": "markdown", 92 | "metadata": {}, 93 | "source": [ 94 | "(7) Copy the token and paste in the windows console
\n", 95 | "![alt text](./images/step7_inst.png)" 96 | ] 97 | }, 98 | { 99 | "cell_type": "markdown", 100 | "metadata": {}, 101 | "source": [ 102 | "(8) The authorisation code is saved and you can start to use the GEE python API.
\n", 103 | "![alt text](./images/step8_inst.png)
\n", 104 | "This authentication process creates a credential file located typically in:
\n", 105 | "C:\\Users\\username\\.config\\earthengine \n", 106 | "![alt text](./images/step9_inst.png)
\n", 107 | "This credential is related to the specific google account used during login (step 4).
\n" 108 | ] 109 | }, 110 | { 111 | "cell_type": "markdown", 112 | "metadata": {}, 113 | "source": [ 114 | "### Testing your installation\n" 115 | ] 116 | }, 117 | { 118 | "cell_type": "markdown", 119 | "metadata": {}, 120 | "source": [ 121 | "In a new python file, copy and paste the following code:
" 122 | ] 123 | }, 124 | { 125 | "cell_type": "markdown", 126 | "metadata": { 127 | "collapsed": false 128 | }, 129 | "source": [ 130 | "#Import the Earth Engine Python Package
\n", 131 | "import ee
\n", 132 | "#Initialize the Earth Engine object
\n", 133 | " ee.Initialize()
\n", 134 | "#Print the information for an image asset.
\n", 135 | " image = ee.Image('srtm90_v4')
\n", 136 | " print(image.getInfo())
" 137 | ] 138 | }, 139 | { 140 | "cell_type": "markdown", 141 | "metadata": {}, 142 | "source": [ 143 | "The above command should produce an output like this:
\n", 144 | "![alt text](./images/out_test_install_gee.png \"Testing GEE installation\")\n" 145 | ] 146 | }, 147 | { 148 | "cell_type": "code", 149 | "execution_count": null, 150 | "metadata": { 151 | "collapsed": true 152 | }, 153 | "outputs": [], 154 | "source": [] 155 | } 156 | ], 157 | "metadata": { 158 | "kernelspec": { 159 | "display_name": "Python 3", 160 | "language": "python", 161 | "name": "python3" 162 | }, 163 | "language_info": { 164 | "codemirror_mode": { 165 | "name": "ipython", 166 | "version": 3 167 | }, 168 | "file_extension": ".py", 169 | "mimetype": "text/x-python", 170 | "name": "python", 171 | "nbconvert_exporter": "python", 172 | "pygments_lexer": "ipython3", 173 | "version": "3.5.1" 174 | } 175 | }, 176 | "nbformat": 4, 177 | "nbformat_minor": 2 178 | } 179 | -------------------------------------------------------------------------------- /GEE_linear_filters.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "______\n", 8 | "\n", 9 | "## Google Earth Engine Tutorial\n", 10 | "### Linear filters\n", 11 | "_____\n", 12 | "\n", 13 | "\n", 14 | "\n" 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "It is not uncommon to apply filters to enhance images for visualization or previous step for other image processing. Popular methods are convolution filters. These methods calculate a new image applying a moving window over the original pixels contained in the defined window. The following image adapted from [Richards, J. (2013)](http://www.springer.com/gp/book/9783642300615), illustrates the operation of a moving window.
\n", 22 | "![alt text](./images/filter_window.png \"Filter window over an image\")\n", 23 | "\n", 24 | "In GEE the term *kernel* is used interchangeable with *kernel*. Then, to apply a filter, it is necessary to define the weigths and size of the moving window. After defining the filter, a *convolve* function is used to apply it. \n", 25 | "GEE includes several filters or kernels. In this example,\n", 26 | "we will select a square kernel that has the following parameters:
\n", 27 | "+ *radius (Float)* : The radius of the kernel to generate. For a 3x3 kernel, we should use 1, for 5x5 kernel we should use 2 and so on.
\n", 28 | "+ *units (String) *:The system of measurement for the kernel \"meters\" or \"pixels\". Default value: \"pixels\".
\n", 29 | "+ *normalize (Boolean)*: Indicates if the kernel values should be normalize to sum 1. Default value: \"True\".
\n", 30 | "+ *magnitude (Float) *: Scale each value by this amount. Default: 1.
\n", 31 | "The kernel definition of a mean filter looks like the image below:
\n", 32 | "![alt text](./images/filter_mean.png \"Kernel definition\")\n", 33 | "This filter will smooth the image as can be seen after applying the following code." 34 | ] 35 | }, 36 | { 37 | "cell_type": "code", 38 | "execution_count": 1, 39 | "metadata": { 40 | "collapsed": false 41 | }, 42 | "outputs": [ 43 | { 44 | "data": { 45 | "text/html": [ 46 | "" 47 | ], 48 | "text/plain": [ 49 | "" 50 | ] 51 | }, 52 | "execution_count": 1, 53 | "metadata": {}, 54 | "output_type": "execute_result" 55 | } 56 | ], 57 | "source": [ 58 | "import ee\n", 59 | "from IPython.display import Image\n", 60 | "ee.Initialize()\n", 61 | "# load our image \n", 62 | "visimage = ee.Image(\"users/rosamaguilar/tutorial/subset\")\n", 63 | "# Rename the bands for convenience \n", 64 | "visimage = visimage.select(\n", 65 | " ['b5','b3','b2'], # current names\n", 66 | " ['Red', 'Green', 'Blue'] # new names\n", 67 | ")\n", 68 | "# visualize the original image\n", 69 | "Image(url=visimage.getThumbUrl({'min': 0, 'max': 2048,'bands': 'Red,Green,Blue'}))" 70 | ] 71 | }, 72 | { 73 | "cell_type": "code", 74 | "execution_count": 2, 75 | "metadata": { 76 | "collapsed": false 77 | }, 78 | "outputs": [ 79 | { 80 | "data": { 81 | "text/html": [ 82 | "" 83 | ], 84 | "text/plain": [ 85 | "" 86 | ] 87 | }, 88 | "execution_count": 2, 89 | "metadata": {}, 90 | "output_type": "execute_result" 91 | } 92 | ], 93 | "source": [ 94 | "# defining the filter\n", 95 | "lpk = ee.Kernel.square(radius = 1, units = 'pixels', normalize= True) # filter mean of 3*3 \n", 96 | "# apply the filter using the function convolve\n", 97 | "smooth3x3 = visimage.convolve(lpk)\n", 98 | "# visualize the result\n", 99 | "Image(url=smooth3x3.getThumbUrl({'min': 0, 'max': 2048,'bands': 'Red,Green,Blue'}))" 100 | ] 101 | }, 102 | { 103 | "cell_type": "markdown", 104 | "metadata": { 105 | "collapsed": false, 106 | "slideshow": { 107 | "slide_type": "slide" 108 | } 109 | }, 110 | "source": [ 111 | "```python\n", 112 | "# Increasing the size of the moving window. \n", 113 | "# defining the filter\n", 114 | "lpk = ee.Kernel.square(radius = 3, units = 'pixels', normalize= True) # filtro de 7*7 \n", 115 | "# apply the filter using the function convolve\n", 116 | "smooth7x7 = visimage.convolve(lpk)\n", 117 | "# visualize the result\n", 118 | "Image(url=smooth7x7.getThumbUrl({'min': 0, 'max': 2048,'bands': 'Red,Green,Blue'}))\n", 119 | "```" 120 | ] 121 | }, 122 | { 123 | "cell_type": "markdown", 124 | "metadata": {}, 125 | "source": [ 126 | "Several predefined kernel are available in GEE. Circle, rectangle, Gaussian, among others.
\n", 127 | "We can also define the kernel using the fixed kernel option.
\n", 128 | "Parameters for a fixed kernel are:
\n", 129 | "+ *width (Integer)*: The width of the kernel in pixels.\n", 130 | "+ *height (Integer)*: The height of the kernel in pixels.\n", 131 | "+ *weights (List)*: The pixel values of the kernel.\n", 132 | "+ *x (Integer, default: -1)*:\n", 133 | "The location of the focus, as an offset from the left.\n", 134 | "+ *y (Integer, default: -1)*:The location of the focus, as an offset from the top.\n", 135 | "+ *normalize (Boolean, default: false)*:Normalize the kernel values to sum to 1." 136 | ] 137 | }, 138 | { 139 | "cell_type": "markdown", 140 | "metadata": { 141 | "collapsed": false, 142 | "slideshow": { 143 | "slide_type": "slide" 144 | } 145 | }, 146 | "source": [ 147 | "```python\n", 148 | "# Lets apply a edge detection filter of 1x3.\n", 149 | "# define the kernel\n", 150 | "list = [[-1,0 , 1]]\n", 151 | "kernel = ee.Kernel.fixed(3, 1, list, -1, 0, False)\n", 152 | "print(kernel.getInfo())\n", 153 | "```" 154 | ] 155 | }, 156 | { 157 | "cell_type": "code", 158 | "execution_count": 5, 159 | "metadata": { 160 | "collapsed": false 161 | }, 162 | "outputs": [ 163 | { 164 | "data": { 165 | "text/html": [ 166 | "" 167 | ], 168 | "text/plain": [ 169 | "" 170 | ] 171 | }, 172 | "execution_count": 5, 173 | "metadata": {}, 174 | "output_type": "execute_result" 175 | } 176 | ], 177 | "source": [ 178 | "# apply the kernel\n", 179 | "edge1x3 = visimage.convolve(kernel)\n", 180 | "\n", 181 | "# visualize the result\n", 182 | "Image(url=edge1x3.getThumbUrl({'min': 0, 'max': 2048,'bands': 'Red,Green,Blue'}))" 183 | ] 184 | }, 185 | { 186 | "cell_type": "code", 187 | "execution_count": 6, 188 | "metadata": { 189 | "collapsed": false 190 | }, 191 | "outputs": [ 192 | { 193 | "name": "stdout", 194 | "output_type": "stream", 195 | "text": [ 196 | "{'x': 0, 'height': 3, 'weights': '\\n [-1.0]\\n [0.0]\\n [1.0]', 'center': [0, 0], 'type': 'Kernel.fixed', 'width': 1, 'y': 0}\n" 197 | ] 198 | }, 199 | { 200 | "data": { 201 | "text/html": [ 202 | "" 203 | ], 204 | "text/plain": [ 205 | "" 206 | ] 207 | }, 208 | "execution_count": 6, 209 | "metadata": {}, 210 | "output_type": "execute_result" 211 | } 212 | ], 213 | "source": [ 214 | "# Lets apply a edge detection filter of 3x1.\n", 215 | "# define the kernel\n", 216 | "list = [[-1],[0] , [1]]\n", 217 | "kernel = ee.Kernel.fixed(1, 3, list, -1, 0, False)\n", 218 | "print(kernel.getInfo())\n", 219 | "# apply the kernel\n", 220 | "edge1x3 = visimage.convolve(kernel)\n", 221 | "\n", 222 | "# visualize the result\n", 223 | "Image(url=edge1x3.getThumbUrl({'min': 0, 'max': 2048,'bands': 'Red,Green,Blue'}))" 224 | ] 225 | }, 226 | { 227 | "cell_type": "markdown", 228 | "metadata": {}, 229 | "source": [ 230 | "It maybe of interest to apply a [laplacian filter](https://en.wikipedia.org/wiki/Discrete_Laplace_operator).
\n", 231 | " A possible kernel for a laplacian filter is:
\n", 232 | "![alt text](./images/laplacian.png \"Laplacian Kernel\")" 233 | ] 234 | }, 235 | { 236 | "cell_type": "code", 237 | "execution_count": 7, 238 | "metadata": { 239 | "collapsed": false 240 | }, 241 | "outputs": [ 242 | { 243 | "name": "stdout", 244 | "output_type": "stream", 245 | "text": [ 246 | "{'center': [1, 1],\n", 247 | " 'height': 3,\n", 248 | " 'type': 'Kernel.fixed',\n", 249 | " 'weights': '\\n [0.0, 1.0, 0.0]\\n [1.0, -4.0, 1.0]\\n [0.0, 1.0, 0.0]',\n", 250 | " 'width': 3,\n", 251 | " 'x': 1,\n", 252 | " 'y': 1}\n" 253 | ] 254 | }, 255 | { 256 | "data": { 257 | "text/html": [ 258 | "" 259 | ], 260 | "text/plain": [ 261 | "" 262 | ] 263 | }, 264 | "execution_count": 7, 265 | "metadata": {}, 266 | "output_type": "execute_result" 267 | } 268 | ], 269 | "source": [ 270 | "# define the kernel for laplacian filter\n", 271 | "import pprint\n", 272 | "list = [0,1,0]\n", 273 | "center = [1,-4,1]\n", 274 | "klist = [list,center,list]\n", 275 | "kernel = ee.Kernel.fixed(3, 3, klist, -1, -1, False)\n", 276 | "\n", 277 | "pprint.pprint(kernel.getInfo())\n", 278 | "# apply the kernel\n", 279 | "laplacian = visimage.convolve(kernel)\n", 280 | "\n", 281 | "# visualize the result\n", 282 | "\n", 283 | "Image(url=laplacian.getThumbUrl({'min': 0, 'max': 2048,'bands': 'Red,Green,Blue'}))" 284 | ] 285 | }, 286 | { 287 | "cell_type": "code", 288 | "execution_count": 8, 289 | "metadata": { 290 | "collapsed": false 291 | }, 292 | "outputs": [ 293 | { 294 | "name": "stdout", 295 | "output_type": "stream", 296 | "text": [ 297 | "{'center': [2, 2],\n", 298 | " 'radius': 2.0,\n", 299 | " 'type': 'Kernel.gaussian',\n", 300 | " 'weights': '\\n'\n", 301 | " ' [0.0029690167439504977, 0.013306209891013656, '\n", 302 | " '0.021938231279714653, 0.013306209891013656, '\n", 303 | " '0.0029690167439504977]\\n'\n", 304 | " ' [0.013306209891013656, 0.05963429543618016, 0.0983203313488458, '\n", 305 | " '0.05963429543618016, 0.013306209891013656]\\n'\n", 306 | " ' [0.021938231279714653, 0.0983203313488458, 0.1621028216371267, '\n", 307 | " '0.0983203313488458, 0.021938231279714653]\\n'\n", 308 | " ' [0.013306209891013656, 0.05963429543618016, 0.0983203313488458, '\n", 309 | " '0.05963429543618016, 0.013306209891013656]\\n'\n", 310 | " ' [0.0029690167439504977, 0.013306209891013656, '\n", 311 | " '0.021938231279714653, 0.013306209891013656, '\n", 312 | " '0.0029690167439504977]'}\n" 313 | ] 314 | }, 315 | { 316 | "data": { 317 | "text/html": [ 318 | "" 319 | ], 320 | "text/plain": [ 321 | "" 322 | ] 323 | }, 324 | "execution_count": 8, 325 | "metadata": {}, 326 | "output_type": "execute_result" 327 | } 328 | ], 329 | "source": [ 330 | "# Lets try another example, using a gaussian filter\n", 331 | "# define the kernel, the code below will produce a discrete aproximation of a gaussian filter with sigma= 1 and size=5x5
\n", 332 | "gauskernel = ee.Kernel.gaussian(2,1)\n", 333 | "pprint.pprint(gauskernel.getInfo())\n", 334 | "# apply the filter\n", 335 | "gauss= visimage.convolve(gauskernel)\n", 336 | "# visualize results \n", 337 | "Image(url=gauss.getThumbUrl({'min': 0, 'max': 2048,'bands': 'Red,Green,Blue'}))" 338 | ] 339 | }, 340 | { 341 | "cell_type": "markdown", 342 | "metadata": {}, 343 | "source": [ 344 | "We have defined a particular laplacian kernel. But, it is also possible to use some laplacian kernels that GEE has already defined. The follwing code illustrates a " 345 | ] 346 | }, 347 | { 348 | "cell_type": "code", 349 | "execution_count": 9, 350 | "metadata": { 351 | "collapsed": false 352 | }, 353 | "outputs": [ 354 | { 355 | "name": "stdout", 356 | "output_type": "stream", 357 | "text": [ 358 | "{'center': [1, 1],\n", 359 | " 'type': 'Kernel.laplacian8',\n", 360 | " 'weights': '\\n [1.0, 1.0, 1.0]\\n [1.0, -8.0, 1.0]\\n [1.0, 1.0, 1.0]'}\n" 361 | ] 362 | }, 363 | { 364 | "data": { 365 | "text/html": [ 366 | "" 367 | ], 368 | "text/plain": [ 369 | "" 370 | ] 371 | }, 372 | "execution_count": 9, 373 | "metadata": {}, 374 | "output_type": "execute_result" 375 | } 376 | ], 377 | "source": [ 378 | "# define the kernel
\n", 379 | "kernel = ee.Kernel.laplacian8()\n", 380 | "pprint.pprint(kernel.getInfo())\n", 381 | "# apply the filter\n", 382 | "laplacian8 = visimage.convolve(kernel)\n", 383 | "# visualize results \n", 384 | "Image(url = laplacian8.getThumbUrl({'min': 0, 'max': 2048,'bands': 'Red,Green,Blue'}))" 385 | ] 386 | }, 387 | { 388 | "cell_type": "code", 389 | "execution_count": null, 390 | "metadata": { 391 | "collapsed": true 392 | }, 393 | "outputs": [], 394 | "source": [] 395 | } 396 | ], 397 | "metadata": { 398 | "celltoolbar": "Slideshow", 399 | "kernelspec": { 400 | "display_name": "Python 3", 401 | "language": "python", 402 | "name": "python3" 403 | }, 404 | "language_info": { 405 | "codemirror_mode": { 406 | "name": "ipython", 407 | "version": 3 408 | }, 409 | "file_extension": ".py", 410 | "mimetype": "text/x-python", 411 | "name": "python", 412 | "nbconvert_exporter": "python", 413 | "pygments_lexer": "ipython3", 414 | "version": "3.5.1" 415 | } 416 | }, 417 | "nbformat": 4, 418 | "nbformat_minor": 2 419 | } 420 | -------------------------------------------------------------------------------- /GEE_nonlinear_filters.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "______\n", 8 | "\n", 9 | "## Google Earth Engine Tutorial\n", 10 | "### Nonlinear filters\n", 11 | "_____\n", 12 | "\n", 13 | "In previous noteboooks, we applied convolutional filters. Those filter compute a linear combination of pixels in a neighbourhood(specified by the window shape) according to the weights specified by the kernel. Now, we will use nonlinear filter. [Median](https://en.wikipedia.org/wiki/Median_filter) and [mode](https://www.cs.washington.edu/research/metip/tutor/tutor.Filtering.html) are examples of non linear filters.
\n", 14 | "Median filters compute the median (a non linear combination) in neighbourhood as well. An approach to apply nonlinear filters in GEE is by using the function *reduceNeighborhood*. \n" 15 | ] 16 | }, 17 | { 18 | "cell_type": "code", 19 | "execution_count": 1, 20 | "metadata": { 21 | "collapsed": false 22 | }, 23 | "outputs": [ 24 | { 25 | "data": { 26 | "text/html": [ 27 | "" 28 | ], 29 | "text/plain": [ 30 | "" 31 | ] 32 | }, 33 | "execution_count": 1, 34 | "metadata": {}, 35 | "output_type": "execute_result" 36 | } 37 | ], 38 | "source": [ 39 | "import ee\n", 40 | "from IPython.display import Image\n", 41 | "\n", 42 | "ee.Initialize()\n", 43 | "\n", 44 | "image = ee.Image('users/rosamaguilar/tutorial/subset')\n", 45 | "uniformKernel = ee.Kernel.square(1) # this means a 3x3 window\n", 46 | "\n", 47 | "median = image.reduceNeighborhood(\n", 48 | " reducer = ee.Reducer.median(), \n", 49 | " kernel = uniformKernel\n", 50 | ")\n", 51 | " \n", 52 | "# band names of the result image will have the suffix \"_median\" \n", 53 | "Image(url=median.getThumbUrl({'min': 0, 'max': 2048,'bands': 'b5_median,b3_median,b2_median'}))\n", 54 | " " 55 | ] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "execution_count": 2, 60 | "metadata": { 61 | "collapsed": false 62 | }, 63 | "outputs": [ 64 | { 65 | "data": { 66 | "text/html": [ 67 | "" 68 | ], 69 | "text/plain": [ 70 | "" 71 | ] 72 | }, 73 | "execution_count": 2, 74 | "metadata": {}, 75 | "output_type": "execute_result" 76 | } 77 | ], 78 | "source": [ 79 | "uniformKernel = ee.Kernel.square(2) # this means a 5x5 window\n", 80 | "\n", 81 | "median = image.reduceNeighborhood(\n", 82 | " reducer = ee.Reducer.median(), \n", 83 | " kernel = uniformKernel\n", 84 | ")\n", 85 | " \n", 86 | "# band names of the result image will have the suffix \"_median\" \n", 87 | "Image(url=median.getThumbUrl({'min': 0, 'max': 2048,'bands': 'b5_median,b3_median,b2_median'}))\n", 88 | " " 89 | ] 90 | }, 91 | { 92 | "cell_type": "markdown", 93 | "metadata": {}, 94 | "source": [ 95 | "In some cases, it is required to aggregate pixel values in a neighbourhood using the most common value (mode). This is special relevant for categorical maps that could be the result of a classification procedure.\n" 96 | ] 97 | }, 98 | { 99 | "cell_type": "code", 100 | "execution_count": 3, 101 | "metadata": { 102 | "collapsed": false 103 | }, 104 | "outputs": [ 105 | { 106 | "data": { 107 | "text/html": [ 108 | "" 109 | ], 110 | "text/plain": [ 111 | "" 112 | ] 113 | }, 114 | "execution_count": 3, 115 | "metadata": {}, 116 | "output_type": "execute_result" 117 | } 118 | ], 119 | "source": [ 120 | "# first, display the classified image in a map\n", 121 | "image = ee.Image('users/rosamaguilar/tutorial/classified')\n", 122 | "# define a palette as a string separate by ','\n", 123 | "clas_col = ','.join(['000000','bdc3c7','1e8449','d68910','2ecc71','f9e79f']) \n", 124 | "Image(url=image.getThumbUrl({'min': 0, 'max': 5, 'palette':clas_col}))\n" 125 | ] 126 | }, 127 | { 128 | "cell_type": "code", 129 | "execution_count": 4, 130 | "metadata": { 131 | "collapsed": false 132 | }, 133 | "outputs": [ 134 | { 135 | "data": { 136 | "text/html": [ 137 | "" 138 | ], 139 | "text/plain": [ 140 | "" 141 | ] 142 | }, 143 | "execution_count": 4, 144 | "metadata": {}, 145 | "output_type": "execute_result" 146 | } 147 | ], 148 | "source": [ 149 | "# Let's calculate the mode of a classified image \n", 150 | "\n", 151 | "uniformKernel = ee.Kernel.square(1) # this means a 3x3 window\n", 152 | "mode = image.reduceNeighborhood(\n", 153 | " reducer = ee.Reducer.mode(), \n", 154 | " kernel = ee.Kernel.square(2)\n", 155 | ")\n", 156 | "\n", 157 | "Image(url=mode.getThumbUrl({'min': 0, 'max': 5,'palette':clas_col}))" 158 | ] 159 | }, 160 | { 161 | "cell_type": "markdown", 162 | "metadata": {}, 163 | "source": [ 164 | "Filters can help enhancing visually the image and reducing noise. However, when the interest rely on objects (connected group of pixels) present in the image rather than individual pixels, we may use [morphological operations](https://en.wikipedia.org/wiki/Mathematical_morphology). These operations are useful to clean objects that can have gaps or are not well defined because of noise. \n", 165 | "\n", 166 | "Dilation and erosion are commonly applied to remote sensing images. The following lines apply dilation and erosion to a multi-spectral image. Later those operations are applied to a classified (categorical) image as well. In these examples, the *structuring element* is a square of size 3*3 pixels (square kernel of radio 1 pixel). *Opening* and *closing* can be executed by combining erosion and dilation.
\n" 167 | ] 168 | }, 169 | { 170 | "cell_type": "code", 171 | "execution_count": 5, 172 | "metadata": { 173 | "collapsed": false 174 | }, 175 | "outputs": [ 176 | { 177 | "data": { 178 | "text/html": [ 179 | "" 180 | ], 181 | "text/plain": [ 182 | "" 183 | ] 184 | }, 185 | "execution_count": 5, 186 | "metadata": {}, 187 | "output_type": "execute_result" 188 | } 189 | ], 190 | "source": [ 191 | "# dilation \n", 192 | "image = ee.Image('users/rosamaguilar/tutorial/subset')\n", 193 | "# Dilate by taking the max in each 3x3 neighborhood.\n", 194 | "imagemax = image.reduceNeighborhood(\n", 195 | " reducer = ee.Reducer.max(), \n", 196 | " kernel = ee.Kernel.square(1)\n", 197 | ")\n", 198 | "Image(url=imagemax.getThumbUrl({'min': 0, 'max': 2048,'bands': 'b5_max,b3_max,b2_max'}))" 199 | ] 200 | }, 201 | { 202 | "cell_type": "code", 203 | "execution_count": 6, 204 | "metadata": { 205 | "collapsed": false 206 | }, 207 | "outputs": [ 208 | { 209 | "data": { 210 | "text/html": [ 211 | "" 212 | ], 213 | "text/plain": [ 214 | "" 215 | ] 216 | }, 217 | "execution_count": 6, 218 | "metadata": {}, 219 | "output_type": "execute_result" 220 | } 221 | ], 222 | "source": [ 223 | "# erosion\n", 224 | "image = ee.Image('users/rosamaguilar/tutorial/subset')\n", 225 | "# Dilate by takaing the max in each 3x3 neighborhood.\n", 226 | "imagemin = image.reduceNeighborhood(\n", 227 | " reducer = ee.Reducer.min(), \n", 228 | " kernel = ee.Kernel.square(1)\n", 229 | ")\n", 230 | "Image(url=imagemin.getThumbUrl({'min': 0, 'max': 2048,'bands': 'b5_min,b3_min,b2_min'}))" 231 | ] 232 | }, 233 | { 234 | "cell_type": "code", 235 | "execution_count": 7, 236 | "metadata": { 237 | "collapsed": false 238 | }, 239 | "outputs": [ 240 | { 241 | "data": { 242 | "text/html": [ 243 | "" 244 | ], 245 | "text/plain": [ 246 | "" 247 | ] 248 | }, 249 | "execution_count": 7, 250 | "metadata": {}, 251 | "output_type": "execute_result" 252 | } 253 | ], 254 | "source": [ 255 | "# dilation for a categorical image\n", 256 | "#Image(url = imagemax.getThumbUrl({'min': 0, 'max': 5,'palette':clas_col}))\n", 257 | "# dilation \n", 258 | "image = ee.Image('users/rosamaguilar/tutorial/classified')\n", 259 | "# Dilate by takaing the max in each 3x3 neighborhood.\n", 260 | "imagemax = image.reduceNeighborhood(\n", 261 | " reducer = ee.Reducer.max(), \n", 262 | " kernel = ee.Kernel.square(1)\n", 263 | ")\n", 264 | "Image(url=imagemax.getThumbUrl({'min': 0, 'max': 5,'palette':clas_col}))" 265 | ] 266 | }, 267 | { 268 | "cell_type": "code", 269 | "execution_count": 8, 270 | "metadata": { 271 | "collapsed": false 272 | }, 273 | "outputs": [ 274 | { 275 | "data": { 276 | "text/html": [ 277 | "" 278 | ], 279 | "text/plain": [ 280 | "" 281 | ] 282 | }, 283 | "execution_count": 8, 284 | "metadata": {}, 285 | "output_type": "execute_result" 286 | } 287 | ], 288 | "source": [ 289 | "# erosion for a categorical image\n", 290 | "#Image(url = imagemax.getThumbUrl({'min': 0, 'max': 5,'palette':clas_col}))\n", 291 | "image = ee.Image('users/rosamaguilar/tutorial/classified')\n", 292 | "# Dilate by takaing the max in each 3x3 neighborhood.\n", 293 | "imagemax = image.reduceNeighborhood(\n", 294 | " reducer = ee.Reducer.min(), \n", 295 | " kernel = ee.Kernel.square(1)\n", 296 | ")\n", 297 | "Image(url=imagemax.getThumbUrl({'min': 0, 'max': 5,'palette':clas_col}))" 298 | ] 299 | }, 300 | { 301 | "cell_type": "markdown", 302 | "metadata": {}, 303 | "source": [ 304 | "Opening can be computed applying a dilation over an erosion
" 305 | ] 306 | }, 307 | { 308 | "cell_type": "code", 309 | "execution_count": 9, 310 | "metadata": { 311 | "collapsed": false 312 | }, 313 | "outputs": [ 314 | { 315 | "data": { 316 | "text/html": [ 317 | "" 318 | ], 319 | "text/plain": [ 320 | "" 321 | ] 322 | }, 323 | "execution_count": 9, 324 | "metadata": {}, 325 | "output_type": "execute_result" 326 | } 327 | ], 328 | "source": [ 329 | "# erosion for a categorical image\n", 330 | "image = ee.Image('users/rosamaguilar/tutorial/classified')\n", 331 | "imagemin = image.reduceNeighborhood(\n", 332 | " reducer = ee.Reducer.min(), \n", 333 | " kernel = ee.Kernel.square(1))\n", 334 | "# dilation \n", 335 | "imagemax = imagemax.reduceNeighborhood(\n", 336 | " reducer = ee.Reducer.max(), \n", 337 | " kernel = ee.Kernel.square(1))\n", 338 | "\n", 339 | "Image(url=imagemax.getThumbUrl({'min': 0, 'max': 5,'palette':clas_col}))" 340 | ] 341 | }, 342 | { 343 | "cell_type": "code", 344 | "execution_count": 10, 345 | "metadata": { 346 | "collapsed": false 347 | }, 348 | "outputs": [ 349 | { 350 | "data": { 351 | "text/html": [ 352 | "" 353 | ], 354 | "text/plain": [ 355 | "" 356 | ] 357 | }, 358 | "execution_count": 10, 359 | "metadata": {}, 360 | "output_type": "execute_result" 361 | } 362 | ], 363 | "source": [ 364 | "# In a similar way, to apply closing, apply a dilation followed by an erosion\n", 365 | "image = ee.Image('users/rosamaguilar/tutorial/classified')\n", 366 | "# dilation for a categorical image\n", 367 | "imagemax = imagemax.reduceNeighborhood(\n", 368 | " reducer = ee.Reducer.max(), \n", 369 | " kernel = ee.Kernel.square(1))\n", 370 | "# erosion \n", 371 | "imagemin = imagemax.reduceNeighborhood(\n", 372 | " reducer = ee.Reducer.min(), \n", 373 | " kernel = ee.Kernel.square(1))\n", 374 | "\n", 375 | "Image(url=imagemin.getThumbUrl({'min': 0, 'max': 5,'palette':clas_col}))" 376 | ] 377 | }, 378 | { 379 | "cell_type": "markdown", 380 | "metadata": { 381 | "collapsed": true 382 | }, 383 | "source": [ 384 | "You may want to try with a different structuring element, for example a disk by using a kernel circle." 385 | ] 386 | }, 387 | { 388 | "cell_type": "code", 389 | "execution_count": null, 390 | "metadata": { 391 | "collapsed": true 392 | }, 393 | "outputs": [], 394 | "source": [] 395 | } 396 | ], 397 | "metadata": { 398 | "kernelspec": { 399 | "display_name": "Python 3", 400 | "language": "python", 401 | "name": "python3" 402 | }, 403 | "language_info": { 404 | "codemirror_mode": { 405 | "name": "ipython", 406 | "version": 3 407 | }, 408 | "file_extension": ".py", 409 | "mimetype": "text/x-python", 410 | "name": "python", 411 | "nbconvert_exporter": "python", 412 | "pygments_lexer": "ipython3", 413 | "version": "3.5.1" 414 | } 415 | }, 416 | "nbformat": 4, 417 | "nbformat_minor": 2 418 | } 419 | -------------------------------------------------------------------------------- /GEE_subset_export.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "______\n", 8 | "\n", 9 | "## Google Earth Engine Tutorial\n", 10 | "### Subset and export \n", 11 | "_____" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": { 17 | "collapsed": true 18 | }, 19 | "source": [ 20 | "In this section, we will perform a change detection analysis. Firts, two raster subsets will be generated and exported as new images to a GEE asset. Second, NDVI will be extracted from the subsets and a change detection analysis will be performed by image algebra. " 21 | ] 22 | }, 23 | { 24 | "cell_type": "markdown", 25 | "metadata": {}, 26 | "source": [ 27 | "### Subset\n", 28 | "A clip polygon in the format of a fusion table will be used to clip a raster.
\n" 29 | ] 30 | }, 31 | { 32 | "cell_type": "code", 33 | "execution_count": 1, 34 | "metadata": { 35 | "collapsed": false 36 | }, 37 | "outputs": [ 38 | { 39 | "data": { 40 | "text/html": [ 41 | "" 42 | ], 43 | "text/plain": [ 44 | "" 45 | ] 46 | }, 47 | "execution_count": 1, 48 | "metadata": {}, 49 | "output_type": "execute_result" 50 | } 51 | ], 52 | "source": [ 53 | "import ee\n", 54 | "ee.Initialize()\n", 55 | "clip = ee.FeatureCollection('ft:1ESjFoDfKue9_kIZng_vWn5zPiTkawuSNdrsITTaZ')\n", 56 | "# this images must be changed later\n", 57 | "imgnov = ee.Image(\"users/STARS/DG_MALI_MULTI/054112895020_01_ML_Sukumba_2014Y11M01D_WorldView-2_ORStandard2A_transformed_topocorr\"); \n", 58 | "imgjul = ee.Image (\"users/STARS/DG_MALI_MULTI/054112895070_01_ML_Sukumba_2014Y07M29D_WorldView-2_ORStandard2A_transformed_topocorr\")\n", 59 | "from IPython.display import Image\n", 60 | "# Visualize the entire image\n", 61 | "Image(url=imgnov.getThumbUrl({'min': 0, 'max': 2048,'bands': 'b5,b3,b2'}))" 62 | ] 63 | }, 64 | { 65 | "cell_type": "code", 66 | "execution_count": 2, 67 | "metadata": { 68 | "collapsed": false 69 | }, 70 | "outputs": [ 71 | { 72 | "data": { 73 | "text/html": [ 74 | "" 75 | ], 76 | "text/plain": [ 77 | "" 78 | ] 79 | }, 80 | "execution_count": 2, 81 | "metadata": {}, 82 | "output_type": "execute_result" 83 | } 84 | ], 85 | "source": [ 86 | "# Clip and visualize the image\n", 87 | "imgnovs=imgnov.clip(clip)\n", 88 | "from IPython.display import Image\n", 89 | "Image(url=imgnovs.getThumbUrl({'min': 0, 'max': 2048,'bands': 'b5,b3,b2'}))\n" 90 | ] 91 | }, 92 | { 93 | "cell_type": "code", 94 | "execution_count": 3, 95 | "metadata": { 96 | "collapsed": false 97 | }, 98 | "outputs": [ 99 | { 100 | "name": "stdout", 101 | "output_type": "stream", 102 | "text": [ 103 | "Export task started!\n" 104 | ] 105 | } 106 | ], 107 | "source": [ 108 | "# The subset keep the metadata information of the original image\n", 109 | "# We will adjust this during the export\n", 110 | "\n", 111 | "region = clip.geometry().bounds().getInfo()['coordinates'][0]\n", 112 | "\n", 113 | "task = ee.batch.Export.image.toAsset(\n", 114 | " image = imgnovs,\n", 115 | " description = \"Image noviembre\",\n", 116 | " assetId = 'users/rosamaguilar/tutorial/' + \"imgnovs\",\n", 117 | " maxPixels=100000000,\n", 118 | " region = region,\n", 119 | " scale = 2)\n", 120 | "task.start()\n", 121 | "print(\"Export task started!\")" 122 | ] 123 | }, 124 | { 125 | "cell_type": "code", 126 | "execution_count": 4, 127 | "metadata": { 128 | "collapsed": false 129 | }, 130 | "outputs": [ 131 | { 132 | "name": "stdout", 133 | "output_type": "stream", 134 | "text": [ 135 | "Export task 2 started!\n" 136 | ] 137 | } 138 | ], 139 | "source": [ 140 | "# Clip and export the other image \n", 141 | "imgjuls = imgjul.clip(clip)\n", 142 | "task = ee.batch.Export.image.toAsset(\n", 143 | " image = imgjuls,\n", 144 | " description = \"Image july\",\n", 145 | " assetId = 'users/rosamaguilar/tutorial/' + \"imgjuls\",\n", 146 | " maxPixels=100000000,\n", 147 | " region = region,\n", 148 | " scale = 2)\n", 149 | "task.start()\n", 150 | "print(\"Export task 2 started!\")" 151 | ] 152 | }, 153 | { 154 | "cell_type": "markdown", 155 | "metadata": {}, 156 | "source": [ 157 | "It may take a while to complete the export. You can check the task status on the GEE Javascript playground. When the export task finish, you can visualize using the following code." 158 | ] 159 | }, 160 | { 161 | "cell_type": "code", 162 | "execution_count": 5, 163 | "metadata": { 164 | "collapsed": false 165 | }, 166 | "outputs": [ 167 | { 168 | "data": { 169 | "text/html": [ 170 | "" 171 | ], 172 | "text/plain": [ 173 | "" 174 | ] 175 | }, 176 | "execution_count": 5, 177 | "metadata": {}, 178 | "output_type": "execute_result" 179 | } 180 | ], 181 | "source": [ 182 | "# Visualize the subsets, Extent (footprint) of the image is adjusted.\n", 183 | "imgjuls = ee.Image('users/rosamaguilar/tutorial/imgjuls')\n", 184 | "Image(url=imgjuls.getThumbUrl({'min': 0, 'max': 2048,'bands': 'b5,b3,b2'}))" 185 | ] 186 | }, 187 | { 188 | "cell_type": "code", 189 | "execution_count": 6, 190 | "metadata": { 191 | "collapsed": false 192 | }, 193 | "outputs": [ 194 | { 195 | "data": { 196 | "text/html": [ 197 | "" 198 | ], 199 | "text/plain": [ 200 | "" 201 | ] 202 | }, 203 | "execution_count": 6, 204 | "metadata": {}, 205 | "output_type": "execute_result" 206 | } 207 | ], 208 | "source": [ 209 | "imgnovs = ee.Image('users/rosamaguilar/tutorial/imgnovs')\n", 210 | "Image(url=imgnovs.getThumbUrl({'min': 0, 'max': 2048,'bands': 'b5,b3,b2'}))" 211 | ] 212 | }, 213 | { 214 | "cell_type": "code", 215 | "execution_count": 7, 216 | "metadata": { 217 | "collapsed": false 218 | }, 219 | "outputs": [ 220 | { 221 | "name": "stdout", 222 | "output_type": "stream", 223 | "text": [ 224 | "Export to drive started!\n" 225 | ] 226 | } 227 | ], 228 | "source": [ 229 | "# This example export an image to a google drive \n", 230 | " \n", 231 | "task = ee.batch.Export.image.toDrive(\n", 232 | " image = imgjuls,\n", 233 | " description = \"Image july\",\n", 234 | " folder = \"pruebatest\",\n", 235 | " maxPixels = 100000000,\n", 236 | " region = region,\n", 237 | " scale = 2)\n", 238 | "task.start()\n", 239 | "print(\"Export to drive started!\")\n", 240 | " " 241 | ] 242 | }, 243 | { 244 | "cell_type": "markdown", 245 | "metadata": {}, 246 | "source": [ 247 | "In the Javascript playground you can see the progress of the export and the output link when is done." 248 | ] 249 | }, 250 | { 251 | "cell_type": "code", 252 | "execution_count": null, 253 | "metadata": { 254 | "collapsed": true 255 | }, 256 | "outputs": [], 257 | "source": [] 258 | } 259 | ], 260 | "metadata": { 261 | "kernelspec": { 262 | "display_name": "Python 3", 263 | "language": "python", 264 | "name": "python3" 265 | }, 266 | "language_info": { 267 | "codemirror_mode": { 268 | "name": "ipython", 269 | "version": 3 270 | }, 271 | "file_extension": ".py", 272 | "mimetype": "text/x-python", 273 | "name": "python", 274 | "nbconvert_exporter": "python", 275 | "pygments_lexer": "ipython3", 276 | "version": "3.5.1" 277 | } 278 | }, 279 | "nbformat": 4, 280 | "nbformat_minor": 2 281 | } 282 | -------------------------------------------------------------------------------- /GEE_tutorial.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Google Earth Engine Tutorial " 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "This tutorial includes basic operations that can be executed using the Pyhton API of Google Earth Engine (GEE) on Windows. \n", 15 | "GEE is a cloud platform to perform large scale analysis on Earth science data." 16 | ] 17 | }, 18 | { 19 | "cell_type": "markdown", 20 | "metadata": {}, 21 | "source": [ 22 | "## Python API Installation " 23 | ] 24 | }, 25 | { 26 | "cell_type": "markdown", 27 | "metadata": {}, 28 | "source": [ 29 | "\n", 30 | "Before the installation, you should sign up in GEE. \n", 31 | "This can be done in: https://signup.earthengine.google.com.\n", 32 | "\n", 33 | "We will use python 3.5 or higher and pip.\n", 34 | "Visit https://www.python.org/ for instructions on python installation and https://pip.pypa.io/en/stable/installing/ for instructions on pip installation. \n", 35 | "Ensure you have upgraded pip (you can run in a console: python -m pip install -U pip) \n", 36 | "\n", 37 | "In a windows console, execute the following steps:\n", 38 | "\n", 39 | "(1) pip install google-api-python-client:
\n", 40 | "\n", 41 | "![alt text](/files/images/step1_inst.png)" 42 | ] 43 | }, 44 | { 45 | "cell_type": "markdown", 46 | "metadata": {}, 47 | "source": [ 48 | "(2) pip install earthengine-api
\n", 49 | "![alt text](/files/images/step2_inst.png)" 50 | ] 51 | }, 52 | { 53 | "cell_type": "markdown", 54 | "metadata": {}, 55 | "source": [ 56 | "(3) earthengine authenticate
\n", 57 | "![alt text](/files/images/step_3_inst.png)\n" 58 | ] 59 | }, 60 | { 61 | "cell_type": "markdown", 62 | "metadata": {}, 63 | "source": [ 64 | "(4) The above instruction will open a browser and request to sign using your google account (if you are not already signed).
\n", 65 | "![alt text](/files/images/step4_inst.png)" 66 | ] 67 | }, 68 | { 69 | "cell_type": "markdown", 70 | "metadata": {}, 71 | "source": [ 72 | "(5) The GEE athenticator will also ask for permission to manage your data.
\n", 73 | "![alt text](/files/images/step5_inst.png)" 74 | ] 75 | }, 76 | { 77 | "cell_type": "markdown", 78 | "metadata": {}, 79 | "source": [ 80 | "(6) After giving permission, GEE will provide a token.
\n", 81 | "\n", 82 | "![alt text](/files/images/step6_inst.png)" 83 | ] 84 | }, 85 | { 86 | "cell_type": "markdown", 87 | "metadata": {}, 88 | "source": [ 89 | "(7) Copy the token and paste in the windows console
\n", 90 | "![alt text](/files/images/step7_inst.png)" 91 | ] 92 | }, 93 | { 94 | "cell_type": "markdown", 95 | "metadata": {}, 96 | "source": [ 97 | "(8) The authorisation code is saved and you can start to use the GEE python API.
\n", 98 | "![alt text](/files/images/step8_inst.png)
\n", 99 | "This authentication process creates a credential file located typically in:
\n", 100 | "C:\\Users\\username\\.config\\earthengine \n", 101 | "![alt text](/files/images/step9_inst.png)
\n", 102 | "This credential is related to the specific google account used during login (step 4).
\n" 103 | ] 104 | }, 105 | { 106 | "cell_type": "markdown", 107 | "metadata": {}, 108 | "source": [ 109 | "### Testing your installation\n" 110 | ] 111 | }, 112 | { 113 | "cell_type": "markdown", 114 | "metadata": {}, 115 | "source": [ 116 | "In a new python file, copy and paste the following code:
" 117 | ] 118 | }, 119 | { 120 | "cell_type": "markdown", 121 | "metadata": { 122 | "collapsed": false 123 | }, 124 | "source": [ 125 | "#Import the Earth Engine Python Package
\n", 126 | "import ee
\n", 127 | "#Initialize the Earth Engine object
\n", 128 | " ee.Initialize()
\n", 129 | "#Print the information for an image asset.
\n", 130 | " image = ee.Image('srtm90_v4')
\n", 131 | " print(image.getInfo())
" 132 | ] 133 | }, 134 | { 135 | "cell_type": "markdown", 136 | "metadata": {}, 137 | "source": [ 138 | "The above command should produce an output like this:
\n", 139 | "![alt text](/files/images/out_test_install_gee.png \"Testing GEE installation\")\n" 140 | ] 141 | } 142 | ], 143 | "metadata": { 144 | "kernelspec": { 145 | "display_name": "Python 3", 146 | "language": "python", 147 | "name": "python3" 148 | }, 149 | "language_info": { 150 | "codemirror_mode": { 151 | "name": "ipython", 152 | "version": 3 153 | }, 154 | "file_extension": ".py", 155 | "mimetype": "text/x-python", 156 | "name": "python", 157 | "nbconvert_exporter": "python", 158 | "pygments_lexer": "ipython3", 159 | "version": "3.5.1" 160 | } 161 | }, 162 | "nbformat": 4, 163 | "nbformat_minor": 2 164 | } 165 | -------------------------------------------------------------------------------- /GEE_tutorial3.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Image Processing" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "Previously, we display the image metadata. We will go for specific details.
\n", 15 | "Let's first initialize GEE and load and image." 16 | ] 17 | }, 18 | { 19 | "cell_type": "code", 20 | "execution_count": 12, 21 | "metadata": { 22 | "collapsed": false 23 | }, 24 | "outputs": [], 25 | "source": [ 26 | "import ee\n", 27 | "from IPython.display import Image\n", 28 | "ee.Initialize()\n", 29 | "# load our image \n", 30 | "mimage = ee.Image(\"users/rosamaguilar/tutorial/subset\")" 31 | ] 32 | }, 33 | { 34 | "cell_type": "code", 35 | "execution_count": 17, 36 | "metadata": { 37 | "collapsed": false 38 | }, 39 | "outputs": [ 40 | { 41 | "name": "stdout", 42 | "output_type": "stream", 43 | "text": [ 44 | "['b1', 'b2', 'b3', 'b4', 'b5', 'b6', 'b7', 'b8']\n" 45 | ] 46 | } 47 | ], 48 | "source": [ 49 | "# get the band names of an image\n", 50 | "names = mimage.bandNames();\n", 51 | "print(names.getInfo())" 52 | ] 53 | }, 54 | { 55 | "cell_type": "code", 56 | "execution_count": 14, 57 | "metadata": { 58 | "collapsed": false 59 | }, 60 | "outputs": [ 61 | { 62 | "name": "stdout", 63 | "output_type": "stream", 64 | "text": [ 65 | "Image scale: 2.0009777545928955\n" 66 | ] 67 | } 68 | ], 69 | "source": [ 70 | "# Retrieve the scale of the image from its projecton\n", 71 | "# please note that we should use getInfo to retrieve the value of a variable or object. \n", 72 | "imScale = mimage.projection().nominalScale()\n", 73 | "print('Image scale:', imScale.getInfo())\n", 74 | "# for more information about scale in GEE, see the document: https://developers.google.com/earth-engine/scale" 75 | ] 76 | }, 77 | { 78 | "cell_type": "code", 79 | "execution_count": 19, 80 | "metadata": { 81 | "collapsed": false 82 | }, 83 | "outputs": [ 84 | { 85 | "data": { 86 | "text/html": [ 87 | "" 88 | ], 89 | "text/plain": [ 90 | "" 91 | ] 92 | }, 93 | "execution_count": 19, 94 | "metadata": {}, 95 | "output_type": "execute_result" 96 | } 97 | ], 98 | "source": [ 99 | "#As you may observe the image has 8 bands because is a World-view2 image.\n", 100 | "# We may want to select only the band in the visible range, this mean bands blue, green and red (bands: b2, b3,b5) \n", 101 | "# we can select some bands of this image and create a new image\n", 102 | "visimage = mimage.select(['b5','b3','b2'])\n", 103 | "# and display the new image\n", 104 | "Image(url=visimage.getThumbUrl({'min': 0, 'max': 2048,'bands': 'b5,b3,b2', 'gamma': '0.95, 1.1, 1'}))" 105 | ] 106 | }, 107 | { 108 | "cell_type": "code", 109 | "execution_count": 20, 110 | "metadata": { 111 | "collapsed": false 112 | }, 113 | "outputs": [ 114 | { 115 | "data": { 116 | "text/html": [ 117 | "" 118 | ], 119 | "text/plain": [ 120 | "" 121 | ] 122 | }, 123 | "execution_count": 20, 124 | "metadata": {}, 125 | "output_type": "execute_result" 126 | } 127 | ], 128 | "source": [ 129 | "#If we want to rename the new bands as b1,b2,b3. We can add the new names as follows:\n", 130 | "#\n", 131 | "visimage = mimage.select(\n", 132 | " ['b5','b3','b2'], # current names\n", 133 | " ['Red', 'Green', 'Blue'] # new names\n", 134 | ")\n", 135 | "Image(url=visimage.getThumbUrl({'min': 0, 'max': 2048,'bands': 'Red,Green,Blue', 'gamma': '0.95, 1.1, 1'}))" 136 | ] 137 | }, 138 | { 139 | "cell_type": "markdown", 140 | "metadata": {}, 141 | "source": [ 142 | "Let's apply a filter over the image.\n", 143 | "First, we need to define the filter to apply. In GEE the term kernel is used interchangeable with kernel. After define the filter, we use convolve to apply it. \n", 144 | "\n" 145 | ] 146 | }, 147 | { 148 | "cell_type": "markdown", 149 | "metadata": {}, 150 | "source": [ 151 | "# aquiiiii\n", 152 | "The kernel defines the weigths and size of the moving window. If we want to apply a kernel of 3x3, we will choose a square kernel of size 1.
\n", 153 | "GEE includes several filters or kernels. In this example, we will select a square kernel that has the following parameters:
\n", 154 | " radius (Float) : The radius of the kernel to generate.
\n", 155 | "units (String, default: \"pixels\"):\n", 156 | "The system of measurement for the kernel ('pixels' or 'meters'). If the kernel is specified in meters, it will resize when the zoom-level is changed.
\n", 157 | "normalize (Boolean, default: true):Normalize the kernel values to sum to 1.
\n", 158 | "magnitude (Float, default: 1):
\n", 159 | "Scale each value by this amount.
" 160 | ] 161 | }, 162 | { 163 | "cell_type": "code", 164 | "execution_count": null, 165 | "metadata": { 166 | "collapsed": true 167 | }, 168 | "outputs": [], 169 | "source": [ 170 | "lpk = ee.Kernel.square(radius = 3, units = 'pixels', normalize= True) # filtro de 7*7\n", 171 | " # Smooth the image by convolving with the lp kernel." 172 | ] 173 | }, 174 | { 175 | "cell_type": "code", 176 | "execution_count": null, 177 | "metadata": { 178 | "collapsed": true 179 | }, 180 | "outputs": [], 181 | "source": [ 182 | "# now , we apply the filter using the function convolve \n", 183 | "smooth = imagep.convolve(lpk)" 184 | ] 185 | }, 186 | { 187 | "cell_type": "code", 188 | "execution_count": null, 189 | "metadata": { 190 | "collapsed": true 191 | }, 192 | "outputs": [], 193 | "source": [ 194 | "creata a new image and use later to store a result" 195 | ] 196 | } 197 | ], 198 | "metadata": { 199 | "kernelspec": { 200 | "display_name": "Python 3", 201 | "language": "python", 202 | "name": "python3" 203 | }, 204 | "language_info": { 205 | "codemirror_mode": { 206 | "name": "ipython", 207 | "version": 3.0 208 | }, 209 | "file_extension": ".py", 210 | "mimetype": "text/x-python", 211 | "name": "python", 212 | "nbconvert_exporter": "python", 213 | "pygments_lexer": "ipython3", 214 | "version": "3.5.1" 215 | } 216 | }, 217 | "nbformat": 4, 218 | "nbformat_minor": 0 219 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Google Earth Engine (GEE) Tutorial 2 | This tutorial is intended for novice users. 3 | It covers basic steps in GEE, from installation to image classification and image exportation. 4 | The examples use python 3.5. 5 | 6 | That's it. Have fun! 7 | -------------------------------------------------------------------------------- /imageMulticlassification.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 17, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import os\n", 12 | "import ee\n", 13 | "\n", 14 | "ee.Initialize()\n", 15 | "\n", 16 | "#====================parameters\n", 17 | "root = 'E:/itc-stars/code/'\n", 18 | "imagepath = 'baseClassifiedImagesPath.txt'\n", 19 | "\n", 20 | "\n", 21 | "# ======================================load the classified images\n", 22 | "os.chdir(root)\n", 23 | "ID_Image = open(root + imagepath, 'r')\n", 24 | "lstimages = ID_Image.readlines()\n", 25 | "lstimages = list(map(str.strip,lstimages))\n", 26 | "\n", 27 | "# ==============================geometry and region to clip and export results\n", 28 | "image = ee.Image(lstimages[0])\n", 29 | "geom = image.geometry()\n", 30 | "region = image.geometry().bounds().getInfo()['coordinates'][0]\n", 31 | "#print(geom.getInfo())\n", 32 | "\n", 33 | "\n", 34 | "# =====================================initialize 5 images to stack the classification\n", 35 | "IC1 = ee.Image()\n", 36 | "IC2 = ee.Image()\n", 37 | "IC3 = ee.Image()\n", 38 | "IC4 = ee.Image()\n", 39 | "IC5 = ee.Image()\n" 40 | ] 41 | }, 42 | { 43 | "cell_type": "code", 44 | "execution_count": 22, 45 | "metadata": { 46 | "collapsed": false 47 | }, 48 | "outputs": [], 49 | "source": [ 50 | "#concatenar las imagenes como bandas\n", 51 | "for fname in lstimages:\n", 52 | " image2 = ee.Image(fname)\n", 53 | " \n", 54 | " if fname.find('class1') > 0:\n", 55 | " IC1 = IC1.addBands(image2)\n", 56 | " elif fname.find('class2') > 0:\n", 57 | " IC2 = IC2.addBands(image2)\n", 58 | " elif fname.find('class3') > 0:\n", 59 | " IC3 = IC3.addBands(image2)\n", 60 | " elif fname.find('class4') > 0:\n", 61 | " IC4 = IC4.addBands(image2)\n", 62 | " elif fname.find('class5') > 0:\n", 63 | " IC5 = IC5.addBands(image2)" 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": 23, 69 | "metadata": { 70 | "collapsed": false 71 | }, 72 | "outputs": [ 73 | { 74 | "name": "stdout", 75 | "output_type": "stream", 76 | "text": [ 77 | "{'bands': [{'id': 'constant', 'data_type': {'max': 0, 'precision': 'int', 'min': 0, 'type': 'PixelType'}, 'crs_transform': [1.0, 0.0, 0.0, 0.0, 1.0, 0.0], 'crs': 'EPSG:4326'}, {'id': 'constant_1', 'data_type': {'precision': 'double', 'type': 'PixelType'}, 'crs_transform': [4.49157642059761e-06, 0.0, -5.2363965721196255, 0.0, -4.49157642059761e-06, 12.217415749104195], 'dimensions': [20801, 20458], 'crs': 'EPSG:4326'}, {'id': 'constant_2', 'data_type': {'precision': 'double', 'type': 'PixelType'}, 'crs_transform': [4.49157642059761e-06, 0.0, -5.2363965721196255, 0.0, -4.49157642059761e-06, 12.217415749104195], 'dimensions': [20801, 20458], 'crs': 'EPSG:4326'}, {'id': 'constant_3', 'data_type': {'precision': 'double', 'type': 'PixelType'}, 'crs_transform': [4.49157642059761e-06, 0.0, -5.2363965721196255, 0.0, -4.49157642059761e-06, 12.217415749104195], 'dimensions': [20801, 20458], 'crs': 'EPSG:4326'}, {'id': 'constant_4', 'data_type': {'precision': 'double', 'type': 'PixelType'}, 'crs_transform': [4.49157642059761e-06, 0.0, -5.2363965721196255, 0.0, -4.49157642059761e-06, 12.217415749104195], 'dimensions': [20801, 20458], 'crs': 'EPSG:4326'}, {'id': 'constant_5', 'data_type': {'precision': 'double', 'type': 'PixelType'}, 'crs_transform': [4.49157642059761e-06, 0.0, -5.2363965721196255, 0.0, -4.49157642059761e-06, 12.217415749104195], 'dimensions': [20801, 20458], 'crs': 'EPSG:4326'}, {'id': 'constant_6', 'data_type': {'precision': 'double', 'type': 'PixelType'}, 'crs_transform': [4.49157642059761e-06, 0.0, -5.2363965721196255, 0.0, -4.49157642059761e-06, 12.217415749104195], 'dimensions': [20801, 20458], 'crs': 'EPSG:4326'}, {'id': 'constant_7', 'data_type': {'precision': 'double', 'type': 'PixelType'}, 'crs_transform': [4.49157642059761e-06, 0.0, -5.2363965721196255, 0.0, -4.49157642059761e-06, 12.217415749104195], 'dimensions': [20801, 20458], 'crs': 'EPSG:4326'}, {'id': 'constant_8', 'data_type': {'precision': 'double', 'type': 'PixelType'}, 'crs_transform': [4.49157642059761e-06, 0.0, -5.2363965721196255, 0.0, -4.49157642059761e-06, 12.217415749104195], 'dimensions': [20801, 20458], 'crs': 'EPSG:4326'}], 'type': 'Image'}\n" 78 | ] 79 | } 80 | ], 81 | "source": [ 82 | "print(IC4.getInfo())" 83 | ] 84 | }, 85 | { 86 | "cell_type": "code", 87 | "execution_count": 24, 88 | "metadata": { 89 | "collapsed": true 90 | }, 91 | "outputs": [], 92 | "source": [ 93 | "#=================================== Accumulate the weights\n", 94 | "# initialize images\n", 95 | "IC1sum = ee.Image(0)\n", 96 | "IC2sum = ee.Image(0)\n", 97 | "IC3sum = ee.Image(0)\n", 98 | "IC4sum = ee.Image(0)\n", 99 | "IC5sum = ee.Image(0)\n", 100 | "\n", 101 | "# Accumulate the weiths -- hacer un reducer que sume\n", 102 | "\n", 103 | "IC1sum = IC1.reduce(ee.Reducer.sum())\n", 104 | "IC2sum = IC2.reduce(ee.Reducer.sum())\n", 105 | "IC3sum = IC3.reduce(ee.Reducer.sum())\n", 106 | "IC4sum = IC4.reduce(ee.Reducer.sum())\n", 107 | "IC5sum = IC5.reduce(ee.Reducer.sum())\n" 108 | ] 109 | }, 110 | { 111 | "cell_type": "code", 112 | "execution_count": 25, 113 | "metadata": { 114 | "collapsed": false 115 | }, 116 | "outputs": [ 117 | { 118 | "name": "stdout", 119 | "output_type": "stream", 120 | "text": [ 121 | "{'bands': [{'id': 'sum', 'data_type': {'precision': 'double', 'type': 'PixelType'}, 'crs_transform': [1.0, 0.0, 0.0, 0.0, 1.0, 0.0], 'crs': 'EPSG:4326'}], 'type': 'Image'}\n" 122 | ] 123 | } 124 | ], 125 | "source": [ 126 | "print(IC1sum.getInfo())" 127 | ] 128 | }, 129 | { 130 | "cell_type": "code", 131 | "execution_count": 26, 132 | "metadata": { 133 | "collapsed": false 134 | }, 135 | "outputs": [ 136 | { 137 | "name": "stdout", 138 | "output_type": "stream", 139 | "text": [ 140 | "*************************************************\n", 141 | " {'bands': [{'id': 'sum', 'data_type': {'precision': 'double', 'type': 'PixelType'}, 'crs_transform': [1.0, 0.0, 0.0, 0.0, 1.0, 0.0], 'crs': 'EPSG:4326'}, {'id': 'sum_1', 'data_type': {'precision': 'double', 'type': 'PixelType'}, 'crs_transform': [1.0, 0.0, 0.0, 0.0, 1.0, 0.0], 'crs': 'EPSG:4326'}, {'id': 'sum_2', 'data_type': {'precision': 'double', 'type': 'PixelType'}, 'crs_transform': [1.0, 0.0, 0.0, 0.0, 1.0, 0.0], 'crs': 'EPSG:4326'}, {'id': 'sum_3', 'data_type': {'precision': 'double', 'type': 'PixelType'}, 'crs_transform': [1.0, 0.0, 0.0, 0.0, 1.0, 0.0], 'crs': 'EPSG:4326'}, {'id': 'sum_4', 'data_type': {'precision': 'double', 'type': 'PixelType'}, 'crs_transform': [1.0, 0.0, 0.0, 0.0, 1.0, 0.0], 'crs': 'EPSG:4326'}], 'type': 'Image'}\n" 142 | ] 143 | } 144 | ], 145 | "source": [ 146 | "IC = IC1sum.addBands(IC2sum).addBands(IC3sum).addBands(IC4sum).addBands(IC5sum)\n", 147 | "print(\"*************************************************\\n\",IC.getInfo())" 148 | ] 149 | }, 150 | { 151 | "cell_type": "code", 152 | "execution_count": 27, 153 | "metadata": { 154 | "collapsed": true 155 | }, 156 | "outputs": [], 157 | "source": [ 158 | "# ================================Extract the maximum # majority voting\n", 159 | "\n", 160 | "cond11 = IC.expression('b(\"sum\") >= b(\"sum_1\") && b(\"sum\") >= b(\"sum_2\")')\n", 161 | "cond12 = IC.expression('b(\"sum\") >= b(\"sum_3\") && b(\"sum\") >= b(\"sum_4\")')\n", 162 | "cond1 = cond11.And(cond12)\n", 163 | "cond21 = IC.expression('b(\"sum_1\") > b(\"sum\") && b(\"sum_1\") >= b(\"sum_2\")')\n", 164 | "cond22 = IC.expression('b(\"sum_1\") >= b(\"sum_3\") && b(\"sum_1\") >= b(\"sum_4\")')\n", 165 | "cond2 = cond21.And(cond22)\n", 166 | "cond31 = IC.expression('b(\"sum_2\") > b(\"sum\") && b(\"sum_2\") > b(\"sum_1\")')\n", 167 | "cond32 = IC.expression('b(\"sum_2\") >= b(\"sum_3\") && b(\"sum_2\") >= b(\"sum_4\")')\n", 168 | "cond3 = cond31.And(cond32)\n", 169 | "\n", 170 | "cond41 = IC.expression('b(\"sum_3\") > b(\"sum\") && b(\"sum_3\") > b(\"sum_1\")')\n", 171 | "cond42 = IC.expression('b(\"sum_3\") > b(\"sum_2\") && b(\"sum_3\") >= b(\"sum_4\")')\n", 172 | "cond4 = cond41.And(cond42) # And in uppercase\n", 173 | "\n", 174 | "cond51 = IC.expression('b(\"sum_4\") > b(\"sum\") && b(\"sum_4\") > b(\"sum_1\")')\n", 175 | "cond52 = IC.expression('b(\"sum_4\") > b(\"sum_3\") && b(\"sum_4\") > b(\"sum_2\")')\n", 176 | "cond5 = cond51.And(cond52)" 177 | ] 178 | }, 179 | { 180 | "cell_type": "code", 181 | "execution_count": 43, 182 | "metadata": { 183 | "collapsed": false 184 | }, 185 | "outputs": [ 186 | { 187 | "name": "stdout", 188 | "output_type": "stream", 189 | "text": [ 190 | "*************************************************\n", 191 | " {'bands': [{'id': 'constant', 'crs_transform': [1.0, 0.0, 0.0, 0.0, 1.0, 0.0], 'origin': [-6, 11], 'data_type': {'max': 5, 'precision': 'int', 'min': 0, 'type': 'PixelType'}, 'dimensions': [2, 2], 'crs': 'EPSG:4326'}], 'properties': {'system:footprint': {'coordinates': [[[-5.236394875491211, 12.125524882429849], [-5.2363943178275125, 12.12552480600459], [-5.189681947295634, 12.12552482139066], [-5.142969554934702, 12.125524809925233], [-5.142967407474762, 12.125526675183306], [-5.142965100943807, 12.12552819565501], [-5.142964941872711, 12.125528980980178], [-5.142964941872711, 12.21741346750349], [-5.142966771190352, 12.217415608568812], [-5.142968361901392, 12.217417841080646], [-5.142969157256931, 12.21741800028432], [-5.189681947295634, 12.217418043281285], [-5.2363943178275125, 12.217418017065055], [-5.236396468816098, 12.217416149409656], [-5.236398779137263, 12.217414626711694], [-5.23639893846976, 12.217413840741836], [-5.23639893846976, 12.125529325866783], [-5.2363970264798185, 12.125527275741774], [-5.236395433154918, 12.12552495885511], [-5.236394875491211, 12.125524882429849]]], 'geodesic': True, 'type': 'Polygon'}}, 'type': 'Image'}\n" 192 | ] 193 | } 194 | ], 195 | "source": [ 196 | "geom = image.geometry()\n", 197 | "output = ee.Image(0)\n", 198 | "output = output.clip(geom)\n", 199 | "\n", 200 | "#1 - Maize\t400\t225 #2 - Millet\t400\t225 #3 - Peanut\t400\t225 #4 - Sorghum\t400\t225 #5- Cotton\t520\t299\n", 201 | "\n", 202 | "output = output.where(cond1, 1) \n", 203 | "output = output.where(cond2, 2) \n", 204 | "output = output.where(cond3, 3) \n", 205 | "output = output.where(cond4, 4) \n", 206 | "output = output.where(cond5, 5) \n", 207 | "output = output.clip(geom)\n", 208 | "print(\"*************************************************\\n\",output.getInfo())" 209 | ] 210 | }, 211 | { 212 | "cell_type": "code", 213 | "execution_count": 47, 214 | "metadata": { 215 | "collapsed": false 216 | }, 217 | "outputs": [ 218 | { 219 | "ename": "EEException", 220 | "evalue": "Invalid color value.", 221 | "output_type": "error", 222 | "traceback": [ 223 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 224 | "\u001b[0;31mEEException\u001b[0m Traceback (most recent call last)", 225 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mIPython\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdisplay\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mImage\u001b[0m \u001b[1;31m# To display image thumbnails.\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0mmpalette\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m[\u001b[0m\u001b[1;34m'000000'\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;34m'bdc3c7'\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;34m'1e8449'\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;34m'd68910'\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;34m'2ecc71'\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;34m'f9e79f'\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0murl\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0moutput\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mgetThumbUrl\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m{\u001b[0m\u001b[1;34m'min'\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;34m'max'\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;36m5\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;34m'palette'\u001b[0m\u001b[1;33m:\u001b[0m\u001b[0mmpalette\u001b[0m\u001b[1;33m}\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0murl\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mImage\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0murl\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0murl\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 226 | "\u001b[0;32mC:\\Python35\\lib\\site-packages\\ee\\deprecation.py\u001b[0m in \u001b[0;36mWrapper\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m 30\u001b[0m \u001b[0mfilename\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mfunc\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m__code__\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mco_filename\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m 31\u001b[0m lineno=func.__code__.co_firstlineno + 1)\n\u001b[0;32m---> 32\u001b[0;31m \u001b[1;32mreturn\u001b[0m \u001b[0mfunc\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 33\u001b[0m \u001b[0mWrapper\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m__doc__\u001b[0m \u001b[1;33m+=\u001b[0m \u001b[1;34m'\\nDEPRECATED: '\u001b[0m \u001b[1;33m+\u001b[0m \u001b[0mmessage\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m 34\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mWrapper\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 227 | "\u001b[0;32mC:\\Python35\\lib\\site-packages\\ee\\image.py\u001b[0m in \u001b[0;36mgetThumbURL\u001b[0;34m(self, params)\u001b[0m\n\u001b[1;32m 195\u001b[0m raise ee_exception.EEException(\n\u001b[1;32m 196\u001b[0m 'The region parameter must be an array or a GeoJSON object.')\n\u001b[0;32m--> 197\u001b[0;31m \u001b[1;32mreturn\u001b[0m \u001b[0mdata\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mmakeThumbUrl\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mgetThumbId\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mrequest\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 198\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m 199\u001b[0m \u001b[1;31m# Deprecated spellings to match the JS library.\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 228 | "\u001b[0;32mC:\\Python35\\lib\\site-packages\\ee\\data.py\u001b[0m in \u001b[0;36mgetThumbId\u001b[0;34m(params)\u001b[0m\n\u001b[1;32m 282\u001b[0m \u001b[1;32mif\u001b[0m \u001b[1;34m'size'\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mrequest\u001b[0m \u001b[1;32mand\u001b[0m \u001b[0misinstance\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mrequest\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;34m'size'\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m(\u001b[0m\u001b[0mlist\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mtuple\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m 283\u001b[0m \u001b[0mrequest\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;34m'size'\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;34m'x'\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mjoin\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mmap\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mstr\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mrequest\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;34m'size'\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m--> 284\u001b[0;31m \u001b[1;32mreturn\u001b[0m \u001b[0msend_\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'/thumb'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mrequest\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 285\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m 286\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", 229 | "\u001b[0;32mC:\\Python35\\lib\\site-packages\\ee\\data.py\u001b[0m in \u001b[0;36msend_\u001b[0;34m(path, params, opt_method, opt_raw)\u001b[0m\n\u001b[1;32m 726\u001b[0m \u001b[1;32mraise\u001b[0m \u001b[0mee_exception\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mEEException\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'Invalid JSON: %s'\u001b[0m \u001b[1;33m%\u001b[0m \u001b[0mcontent\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m 727\u001b[0m \u001b[1;32mif\u001b[0m \u001b[1;34m'error'\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mjson_content\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m--> 728\u001b[0;31m \u001b[1;32mraise\u001b[0m \u001b[0mee_exception\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mEEException\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mjson_content\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;34m'error'\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;34m'message'\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 729\u001b[0m \u001b[1;32mif\u001b[0m \u001b[1;34m'data'\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mcontent\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m 730\u001b[0m \u001b[1;32mraise\u001b[0m \u001b[0mee_exception\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mEEException\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'Malformed response: '\u001b[0m \u001b[1;33m+\u001b[0m \u001b[0mstr\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mcontent\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", 230 | "\u001b[0;31mEEException\u001b[0m: Invalid color value." 231 | ] 232 | } 233 | ], 234 | "source": [ 235 | "from IPython.display import Image # To display image thumbnails.\n", 236 | "mpalette = ['000000','bdc3c7','1e8449','d68910','2ecc71','f9e79f']\n", 237 | "url = output.getThumbUrl({'min':1, 'max':5})\n", 238 | "print(url)\n", 239 | "Image(url=url)" 240 | ] 241 | }, 242 | { 243 | "cell_type": "code", 244 | "execution_count": null, 245 | "metadata": { 246 | "collapsed": true 247 | }, 248 | "outputs": [], 249 | "source": [ 250 | "# load our image \n", 251 | "image = ee.Image(\"users/rosamaguilar/tutorial/subset\")\n", 252 | "# display the image, The maximun pixel value is 2048 because it has 11-bit per pixel.\n", 253 | "Image(url=image.getThumbUrl({'min':0, 'max':2048}))" 254 | ] 255 | } 256 | ], 257 | "metadata": { 258 | "kernelspec": { 259 | "display_name": "Python 3", 260 | "language": "python", 261 | "name": "python3" 262 | }, 263 | "language_info": { 264 | "codemirror_mode": { 265 | "name": "ipython", 266 | "version": 3 267 | }, 268 | "file_extension": ".py", 269 | "mimetype": "text/x-python", 270 | "name": "python", 271 | "nbconvert_exporter": "python", 272 | "pygments_lexer": "ipython3", 273 | "version": "3.5.1" 274 | } 275 | }, 276 | "nbformat": 4, 277 | "nbformat_minor": 2 278 | } 279 | -------------------------------------------------------------------------------- /imageclass1.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 2, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import os\n", 12 | "import ee\n", 13 | "import time\n", 14 | "import re\n", 15 | "from six.moves.urllib.request import urlretrieve\n", 16 | "import numpy as np\n", 17 | "import datetime\n", 18 | "from tabulate import tabulate\n", 19 | "from sortedcontainers import SortedDict\n", 20 | "import csv\n", 21 | "import itertools\n", 22 | "import math\n", 23 | "from IPython.display import Image" 24 | ] 25 | }, 26 | { 27 | "cell_type": "code", 28 | "execution_count": 3, 29 | "metadata": { 30 | "collapsed": true 31 | }, 32 | "outputs": [], 33 | "source": [ 34 | "ee.Initialize()" 35 | ] 36 | }, 37 | { 38 | "cell_type": "code", 39 | "execution_count": 4, 40 | "metadata": { 41 | "collapsed": false 42 | }, 43 | "outputs": [ 44 | { 45 | "data": { 46 | "text/html": [ 47 | "" 48 | ], 49 | "text/plain": [ 50 | "" 51 | ] 52 | }, 53 | "execution_count": 4, 54 | "metadata": {}, 55 | "output_type": "execute_result" 56 | } 57 | ], 58 | "source": [ 59 | "image = ee.Image('srtm90_v4')\n", 60 | "Image(url=image.getThumbUrl({'min':0, 'max':3000}))" 61 | ] 62 | }, 63 | { 64 | "cell_type": "code", 65 | "execution_count": 6, 66 | "metadata": { 67 | "collapsed": true 68 | }, 69 | "outputs": [], 70 | "source": [ 71 | "# load the expanded images\n", 72 | "image = ee.Image(\"users/rosamaguilar/hcsfeats/sintext054112895010_01_ML_Sukumba_2014Y10M18D_WorldView-2_ORStandard2A_fused\")\n", 73 | "image2 = ee.Image(\"users/rosamaguilar/hcsfeats/sintext054112895020_01_ML_Sukumba_2014Y11M01D_WorldView-2_ORStandard2A_fused\")\n", 74 | "image3 = ee.Image(\"users/rosamaguilar/hcsfeats/sintext054112895030_01_ML_Sukumba_2014Y11M14D_WorldView-2_ORStandard2A_fused\")\n", 75 | "image4 = ee.Image(\"users/rosamaguilar/hcsfeats/sintext054112895040_01_ML_Sukumba_2014Y06M26D_WorldView-2_ORStandard2A_fused\")\n", 76 | "image5 = ee.Image(\"users/rosamaguilar/hcsfeats/sintext054112895070_01_ML_Sukumba_2014Y07M29D_WorldView-2_ORStandard2A_fused\")\n", 77 | "image6 = ee.Image(\"users/rosamaguilar/hcsfeats/sintext054330672010_01_ML_Sukumba_2014Y05M30D_WorldView-2_ORStandard2A_fused\")\n", 78 | "image7 = ee.Image(\"users/rosamaguilar/hcsfeats/sintext054330675010_01_ML_Sukumba_2014Y05M22D_WorldView-2_ORStandard2A_fused\")" 79 | ] 80 | }, 81 | { 82 | "cell_type": "code", 83 | "execution_count": 13, 84 | "metadata": { 85 | "collapsed": false 86 | }, 87 | "outputs": [ 88 | { 89 | "data": { 90 | "text/html": [ 91 | "" 92 | ], 93 | "text/plain": [ 94 | "" 95 | ] 96 | }, 97 | "execution_count": 13, 98 | "metadata": {}, 99 | "output_type": "execute_result" 100 | } 101 | ], 102 | "source": [ 103 | "Image(url=image.getThumbUrl({'min':0, 'max':3000}))" 104 | ] 105 | }, 106 | { 107 | "cell_type": "code", 108 | "execution_count": 7, 109 | "metadata": { 110 | "collapsed": false 111 | }, 112 | "outputs": [ 113 | { 114 | "data": { 115 | "text/html": [ 116 | "" 117 | ], 118 | "text/plain": [ 119 | "" 120 | ] 121 | }, 122 | "execution_count": 7, 123 | "metadata": {}, 124 | "output_type": "execute_result" 125 | } 126 | ], 127 | "source": [ 128 | "Image(url=image2.getThumbUrl({min: 0, max: 2048, 'bands': 'b7,b4,b2', 'gamma': '1.1, 1.1, 1.1'}))" 129 | ] 130 | }, 131 | { 132 | "cell_type": "code", 133 | "execution_count": 1, 134 | "metadata": { 135 | "collapsed": false 136 | }, 137 | "outputs": [ 138 | { 139 | "ename": "NameError", 140 | "evalue": "name 'Image' is not defined", 141 | "traceback": [ 142 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 143 | "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", 144 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mImage\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0murl\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mimage3\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mgetThumbUrl\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m{\u001b[0m\u001b[0mmin\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;36m0\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmax\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;36m1024\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;34m'bands'\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'b5,b3,b2'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;34m'gamma'\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;34m'1, 1.1, 1.1'\u001b[0m\u001b[1;33m}\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", 145 | "\u001b[0;31mNameError\u001b[0m: name 'Image' is not defined" 146 | ], 147 | "output_type": "error" 148 | } 149 | ], 150 | "source": [ 151 | "Image(url=image3.getThumbUrl({min: 0, max: 1024, 'bands': 'b5,b3,b2', 'gamma': '1, 1.1, 1.1'}))" 152 | ] 153 | }, 154 | { 155 | "cell_type": "code", 156 | "execution_count": 74, 157 | "metadata": { 158 | "collapsed": false 159 | }, 160 | "outputs": [ 161 | { 162 | "name": "stdout", 163 | "output_type": "stream", 164 | "text": [ 165 | "['fmask', 'b2', 'b3', 'b4', 'b5', 'b6', 'b7', 'NDI_b3_b2', 'NDI_b4_b2', 'NDI_b5_b2', 'NDI_b6_b2', 'NDI_b7_b2', 'NDI_b4_b3', 'NDI_b5_b3', 'NDI_b6_b3', 'NDI_b7_b3', 'NDI_b5_b4', 'NDI_b6_b4', 'NDI_b7_b4', 'NDI_b6_b5', 'NDI_b7_b5', 'NDI_b7_b6', 'DVI_b3_b2', 'DVI_b4_b2', 'DVI_b5_b2', 'DVI_b6_b2', 'DVI_b7_b2', 'DVI_b4_b3', 'DVI_b5_b3', 'DVI_b6_b3', 'DVI_b7_b3', 'DVI_b5_b4', 'DVI_b6_b4', 'DVI_b7_b4', 'DVI_b6_b5', 'DVI_b7_b5', 'DVI_b7_b6', 'RVI_b3_b2', 'RVI_b4_b2', 'RVI_b5_b2', 'RVI_b6_b2', 'RVI_b7_b2', 'RVI_b4_b3', 'RVI_b5_b3', 'RVI_b6_b3', 'RVI_b7_b3', 'RVI_b5_b4', 'RVI_b6_b4', 'RVI_b7_b4', 'RVI_b6_b5', 'RVI_b7_b5', 'RVI_b7_b6', 'EVI', 'TCARI', 'SAVI', 'MSAVI2', 'VARI', 'GLI', 'b2_1', 'b3_1', 'b4_1', 'b5_1', 'b6_1', 'b7_1', 'NDI_b3_b2_1', 'NDI_b4_b2_1', 'NDI_b5_b2_1', 'NDI_b6_b2_1', 'NDI_b7_b2_1', 'NDI_b4_b3_1', 'NDI_b5_b3_1', 'NDI_b6_b3_1', 'NDI_b7_b3_1', 'NDI_b5_b4_1', 'NDI_b6_b4_1', 'NDI_b7_b4_1', 'NDI_b6_b5_1', 'NDI_b7_b5_1', 'NDI_b7_b6_1', 'DVI_b3_b2_1', 'DVI_b4_b2_1', 'DVI_b5_b2_1', 'DVI_b6_b2_1', 'DVI_b7_b2_1', 'DVI_b4_b3_1', 'DVI_b5_b3_1', 'DVI_b6_b3_1', 'DVI_b7_b3_1', 'DVI_b5_b4_1', 'DVI_b6_b4_1', 'DVI_b7_b4_1', 'DVI_b6_b5_1', 'DVI_b7_b5_1', 'DVI_b7_b6_1', 'RVI_b3_b2_1', 'RVI_b4_b2_1', 'RVI_b5_b2_1', 'RVI_b6_b2_1', 'RVI_b7_b2_1', 'RVI_b4_b3_1', 'RVI_b5_b3_1', 'RVI_b6_b3_1', 'RVI_b7_b3_1', 'RVI_b5_b4_1', 'RVI_b6_b4_1', 'RVI_b7_b4_1', 'RVI_b6_b5_1', 'RVI_b7_b5_1', 'RVI_b7_b6_1', 'EVI_1', 'TCARI_1', 'SAVI_1', 'MSAVI2_1', 'VARI_1', 'GLI_1', 'b2_2', 'b3_2', 'b4_2', 'b5_2', 'b6_2', 'b7_2', 'NDI_b3_b2_2', 'NDI_b4_b2_2', 'NDI_b5_b2_2', 'NDI_b6_b2_2', 'NDI_b7_b2_2', 'NDI_b4_b3_2', 'NDI_b5_b3_2', 'NDI_b6_b3_2', 'NDI_b7_b3_2', 'NDI_b5_b4_2', 'NDI_b6_b4_2', 'NDI_b7_b4_2', 'NDI_b6_b5_2', 'NDI_b7_b5_2', 'NDI_b7_b6_2', 'DVI_b3_b2_2', 'DVI_b4_b2_2', 'DVI_b5_b2_2', 'DVI_b6_b2_2', 'DVI_b7_b2_2', 'DVI_b4_b3_2', 'DVI_b5_b3_2', 'DVI_b6_b3_2', 'DVI_b7_b3_2', 'DVI_b5_b4_2', 'DVI_b6_b4_2', 'DVI_b7_b4_2', 'DVI_b6_b5_2', 'DVI_b7_b5_2', 'DVI_b7_b6_2', 'RVI_b3_b2_2', 'RVI_b4_b2_2', 'RVI_b5_b2_2', 'RVI_b6_b2_2', 'RVI_b7_b2_2', 'RVI_b4_b3_2', 'RVI_b5_b3_2', 'RVI_b6_b3_2', 'RVI_b7_b3_2', 'RVI_b5_b4_2', 'RVI_b6_b4_2', 'RVI_b7_b4_2', 'RVI_b6_b5_2', 'RVI_b7_b5_2', 'RVI_b7_b6_2', 'EVI_2', 'TCARI_2', 'SAVI_2', 'MSAVI2_2', 'VARI_2', 'GLI_2', 'b2_3', 'b3_3', 'b4_3', 'b5_3', 'b6_3', 'b7_3', 'NDI_b3_b2_3', 'NDI_b4_b2_3', 'NDI_b5_b2_3', 'NDI_b6_b2_3', 'NDI_b7_b2_3', 'NDI_b4_b3_3', 'NDI_b5_b3_3', 'NDI_b6_b3_3', 'NDI_b7_b3_3', 'NDI_b5_b4_3', 'NDI_b6_b4_3', 'NDI_b7_b4_3', 'NDI_b6_b5_3', 'NDI_b7_b5_3', 'NDI_b7_b6_3', 'DVI_b3_b2_3', 'DVI_b4_b2_3', 'DVI_b5_b2_3', 'DVI_b6_b2_3', 'DVI_b7_b2_3', 'DVI_b4_b3_3', 'DVI_b5_b3_3', 'DVI_b6_b3_3', 'DVI_b7_b3_3', 'DVI_b5_b4_3', 'DVI_b6_b4_3', 'DVI_b7_b4_3', 'DVI_b6_b5_3', 'DVI_b7_b5_3', 'DVI_b7_b6_3', 'RVI_b3_b2_3', 'RVI_b4_b2_3', 'RVI_b5_b2_3', 'RVI_b6_b2_3', 'RVI_b7_b2_3', 'RVI_b4_b3_3', 'RVI_b5_b3_3', 'RVI_b6_b3_3', 'RVI_b7_b3_3', 'RVI_b5_b4_3', 'RVI_b6_b4_3', 'RVI_b7_b4_3', 'RVI_b6_b5_3', 'RVI_b7_b5_3', 'RVI_b7_b6_3', 'EVI_3', 'TCARI_3', 'SAVI_3', 'MSAVI2_3', 'VARI_3', 'GLI_3', 'b2_4', 'b3_4', 'b4_4', 'b5_4', 'b6_4', 'b7_4', 'NDI_b3_b2_4', 'NDI_b4_b2_4', 'NDI_b5_b2_4', 'NDI_b6_b2_4', 'NDI_b7_b2_4', 'NDI_b4_b3_4', 'NDI_b5_b3_4', 'NDI_b6_b3_4', 'NDI_b7_b3_4', 'NDI_b5_b4_4', 'NDI_b6_b4_4', 'NDI_b7_b4_4', 'NDI_b6_b5_4', 'NDI_b7_b5_4', 'NDI_b7_b6_4', 'DVI_b3_b2_4', 'DVI_b4_b2_4', 'DVI_b5_b2_4', 'DVI_b6_b2_4', 'DVI_b7_b2_4', 'DVI_b4_b3_4', 'DVI_b5_b3_4', 'DVI_b6_b3_4', 'DVI_b7_b3_4', 'DVI_b5_b4_4', 'DVI_b6_b4_4', 'DVI_b7_b4_4', 'DVI_b6_b5_4', 'DVI_b7_b5_4', 'DVI_b7_b6_4', 'RVI_b3_b2_4', 'RVI_b4_b2_4', 'RVI_b5_b2_4', 'RVI_b6_b2_4', 'RVI_b7_b2_4', 'RVI_b4_b3_4', 'RVI_b5_b3_4', 'RVI_b6_b3_4', 'RVI_b7_b3_4', 'RVI_b5_b4_4', 'RVI_b6_b4_4', 'RVI_b7_b4_4', 'RVI_b6_b5_4', 'RVI_b7_b5_4', 'RVI_b7_b6_4', 'EVI_4', 'TCARI_4', 'SAVI_4', 'MSAVI2_4', 'VARI_4', 'GLI_4', 'b2_5', 'b3_5', 'b4_5', 'b5_5', 'b6_5', 'b7_5', 'NDI_b3_b2_5', 'NDI_b4_b2_5', 'NDI_b5_b2_5', 'NDI_b6_b2_5', 'NDI_b7_b2_5', 'NDI_b4_b3_5', 'NDI_b5_b3_5', 'NDI_b6_b3_5', 'NDI_b7_b3_5', 'NDI_b5_b4_5', 'NDI_b6_b4_5', 'NDI_b7_b4_5', 'NDI_b6_b5_5', 'NDI_b7_b5_5', 'NDI_b7_b6_5', 'DVI_b3_b2_5', 'DVI_b4_b2_5', 'DVI_b5_b2_5', 'DVI_b6_b2_5', 'DVI_b7_b2_5', 'DVI_b4_b3_5', 'DVI_b5_b3_5', 'DVI_b6_b3_5', 'DVI_b7_b3_5', 'DVI_b5_b4_5', 'DVI_b6_b4_5', 'DVI_b7_b4_5', 'DVI_b6_b5_5', 'DVI_b7_b5_5', 'DVI_b7_b6_5', 'RVI_b3_b2_5', 'RVI_b4_b2_5', 'RVI_b5_b2_5', 'RVI_b6_b2_5', 'RVI_b7_b2_5', 'RVI_b4_b3_5', 'RVI_b5_b3_5', 'RVI_b6_b3_5', 'RVI_b7_b3_5', 'RVI_b5_b4_5', 'RVI_b6_b4_5', 'RVI_b7_b4_5', 'RVI_b6_b5_5', 'RVI_b7_b5_5', 'RVI_b7_b6_5', 'EVI_5', 'TCARI_5', 'SAVI_5', 'MSAVI2_5', 'VARI_5', 'GLI_5']\n" 166 | ] 167 | } 168 | ], 169 | "source": [ 170 | "IC_toScaled = image.addBands(image2).addBands(image3).addBands(image4).addBands(image5).addBands(image6).addBands(image7)\n", 171 | "Image(url=IC_toScaled.getThumbUrl({min: 0, max: 1024, 'bands': 'b5,b3,b2', 'gamma': '1.1, 1.1, 1.1'}))\n", 172 | "print(IC_toScaled.bandNames().getInfo())" 173 | ] 174 | }, 175 | { 176 | "cell_type": "code", 177 | "execution_count": 66, 178 | "metadata": { 179 | "collapsed": false 180 | }, 181 | "outputs": [], 182 | "source": [ 183 | "perc = 0\n", 184 | "# function to scale values between 0 and 1\n", 185 | "## function to transform the image to 255 bits (uint8):\n", 186 | "#def transformTouint8Reducers(image, perc):\n", 187 | "\n", 188 | "# This scale consider all values at the same time ?\n", 189 | "# how to apply a reducer per band\n", 190 | "NameBands = IC_toScaled.bandNames()" 191 | ] 192 | }, 193 | { 194 | "cell_type": "code", 195 | "execution_count": 65, 196 | "metadata": { 197 | "collapsed": false 198 | }, 199 | "outputs": [ 200 | { 201 | "name": "stdout", 202 | "output_type": "stream", 203 | "text": [ 204 | "{'bands': [{'crs': 'EPSG:32614', 'id': 'min', 'data_type': {'min': 0, 'precision': 'int', 'max': 255, 'type': 'PixelType'}, 'crs_transform': [30.0, 0.0, 571785.0, 0.0, -30.0, 3140715.0]}, {'crs': 'EPSG:32614', 'id': 'max', 'data_type': {'min': 0, 'precision': 'int', 'max': 255, 'type': 'PixelType'}, 'crs_transform': [30.0, 0.0, 571785.0, 0.0, -30.0, 3140715.0]}], 'type': 'Image', 'properties': {'system:footprint': {'coordinates': [[[-97.7964, 27.300800000000002], [-96.99639999999998, 27.300800000000002], [-96.99639999999998, 28.100800000000003], [-97.7964, 28.100800000000003], [-97.7964, 27.300800000000002]]], 'geodesic': True, 'type': 'Polygon'}}}\n" 205 | ] 206 | } 207 | ], 208 | "source": [ 209 | "extrema = IC_toScaled.reduce(ee.Reducer.minMax())\n", 210 | "print(extrema.getInfo())\n", 211 | "m0 = ee.Number(extrema.get('min'))\n", 212 | "m0.getInfo()" 213 | ] 214 | }, 215 | { 216 | "cell_type": "code", 217 | "execution_count": 68, 218 | "metadata": { 219 | "collapsed": false 220 | }, 221 | "outputs": [], 222 | "source": [ 223 | "geom = image2.geometry()\n", 224 | "minValues = IC_toScaled.reduceRegion(\n", 225 | " reducer=ee.Reducer.max(),\n", 226 | " bestEffort=True,\n", 227 | " maxPixels=100000000).toImage(NameBands) # to pairwise with the names of bands and use later \n", 228 | "\n", 229 | "maxValues = IC_toScaled.reduceRegion(\n", 230 | " reducer=ee.Reducer.percentile([100]),\n", 231 | " bestEffort=True,\n", 232 | " maxPixels=100000000).toImage(NameBands)\n", 233 | "\n", 234 | "IC = (IC_toScaled.subtract(minValues).divide(maxValues.subtract(minValues))).toUint8() #scale to 0-1\n", 235 | "IC = IC.clip(geom)" 236 | ] 237 | }, 238 | { 239 | "cell_type": "code", 240 | "execution_count": 69, 241 | "metadata": { 242 | "collapsed": false 243 | }, 244 | "outputs": [ 245 | { 246 | "ename": "SyntaxError", 247 | "evalue": "unexpected EOF while parsing (, line 3)", 248 | "traceback": [ 249 | "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m3\u001b[0m\n\u001b[0;31m \u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m unexpected EOF while parsing\n" 250 | ], 251 | "output_type": "error" 252 | } 253 | ], 254 | "source": [ 255 | "" 256 | ] 257 | }, 258 | { 259 | "cell_type": "code", 260 | "execution_count": 72, 261 | "metadata": { 262 | "collapsed": false 263 | }, 264 | "outputs": [ 265 | { 266 | "data": { 267 | "text/html": [ 268 | "" 269 | ], 270 | "text/plain": [ 271 | "" 272 | ] 273 | }, 274 | "execution_count": 72, 275 | "metadata": {}, 276 | "output_type": "execute_result" 277 | } 278 | ], 279 | "source": [ 280 | "Image(url=IC_toScaled.getThumbUrl({min: 0, max: 1, 'bands': 'b5,b3,b2', 'gamma': '1, 1.1, 1.1'}))" 281 | ] 282 | }, 283 | { 284 | "cell_type": "code", 285 | "execution_count": null, 286 | "metadata": { 287 | "collapsed": true 288 | }, 289 | "outputs": [], 290 | "source": [ 291 | "classifiers = ({'CART':True, 'RF':True, 'SVML': True, 'SVMP': True, 'GMO': True})\n", 292 | "weigth_classifiers = ({'CART':[0.94125],'GMO':[0.61625],'RF':[0.958125]" 293 | ] 294 | } 295 | ], 296 | "metadata": { 297 | "kernelspec": { 298 | "display_name": "Python 3", 299 | "language": "python", 300 | "name": "python3" 301 | }, 302 | "language_info": { 303 | "codemirror_mode": { 304 | "name": "ipython", 305 | "version": 3.0 306 | }, 307 | "file_extension": ".py", 308 | "mimetype": "text/x-python", 309 | "name": "python", 310 | "nbconvert_exporter": "python", 311 | "pygments_lexer": "ipython3", 312 | "version": "3.5.1" 313 | } 314 | }, 315 | "nbformat": 4, 316 | "nbformat_minor": 0 317 | } -------------------------------------------------------------------------------- /images/GEE_overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rosaguilar/geetutorial/c94ade86ef13de115535b863a833e76c4405c11c/images/GEE_overview.png -------------------------------------------------------------------------------- /images/create_folder_gee.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rosaguilar/geetutorial/c94ade86ef13de115535b863a833e76c4405c11c/images/create_folder_gee.png -------------------------------------------------------------------------------- /images/create_folder_gee2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rosaguilar/geetutorial/c94ade86ef13de115535b863a833e76c4405c11c/images/create_folder_gee2.png -------------------------------------------------------------------------------- /images/filter_mean.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rosaguilar/geetutorial/c94ade86ef13de115535b863a833e76c4405c11c/images/filter_mean.png -------------------------------------------------------------------------------- /images/filter_window.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rosaguilar/geetutorial/c94ade86ef13de115535b863a833e76c4405c11c/images/filter_window.png -------------------------------------------------------------------------------- /images/headerlogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rosaguilar/geetutorial/c94ade86ef13de115535b863a833e76c4405c11c/images/headerlogo.png -------------------------------------------------------------------------------- /images/insert_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rosaguilar/geetutorial/c94ade86ef13de115535b863a833e76c4405c11c/images/insert_image.png -------------------------------------------------------------------------------- /images/kernel_definition.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rosaguilar/geetutorial/c94ade86ef13de115535b863a833e76c4405c11c/images/kernel_definition.png -------------------------------------------------------------------------------- /images/kernel_textures.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rosaguilar/geetutorial/c94ade86ef13de115535b863a833e76c4405c11c/images/kernel_textures.png -------------------------------------------------------------------------------- /images/kernel_textures_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rosaguilar/geetutorial/c94ade86ef13de115535b863a833e76c4405c11c/images/kernel_textures_2.png -------------------------------------------------------------------------------- /images/laplacian.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rosaguilar/geetutorial/c94ade86ef13de115535b863a833e76c4405c11c/images/laplacian.png -------------------------------------------------------------------------------- /images/laplacian2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rosaguilar/geetutorial/c94ade86ef13de115535b863a833e76c4405c11c/images/laplacian2.png -------------------------------------------------------------------------------- /images/legend_ndvi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rosaguilar/geetutorial/c94ade86ef13de115535b863a833e76c4405c11c/images/legend_ndvi.png -------------------------------------------------------------------------------- /images/out_test_install_gee.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rosaguilar/geetutorial/c94ade86ef13de115535b863a833e76c4405c11c/images/out_test_install_gee.png -------------------------------------------------------------------------------- /images/step1_inst.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rosaguilar/geetutorial/c94ade86ef13de115535b863a833e76c4405c11c/images/step1_inst.png -------------------------------------------------------------------------------- /images/step2_inst.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rosaguilar/geetutorial/c94ade86ef13de115535b863a833e76c4405c11c/images/step2_inst.png -------------------------------------------------------------------------------- /images/step4_inst.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rosaguilar/geetutorial/c94ade86ef13de115535b863a833e76c4405c11c/images/step4_inst.png -------------------------------------------------------------------------------- /images/step5_inst.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rosaguilar/geetutorial/c94ade86ef13de115535b863a833e76c4405c11c/images/step5_inst.png -------------------------------------------------------------------------------- /images/step6_inst.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rosaguilar/geetutorial/c94ade86ef13de115535b863a833e76c4405c11c/images/step6_inst.png -------------------------------------------------------------------------------- /images/step7_inst.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rosaguilar/geetutorial/c94ade86ef13de115535b863a833e76c4405c11c/images/step7_inst.png -------------------------------------------------------------------------------- /images/step8_inst.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rosaguilar/geetutorial/c94ade86ef13de115535b863a833e76c4405c11c/images/step8_inst.png -------------------------------------------------------------------------------- /images/step9_inst.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rosaguilar/geetutorial/c94ade86ef13de115535b863a833e76c4405c11c/images/step9_inst.png -------------------------------------------------------------------------------- /images/step_3_inst.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rosaguilar/geetutorial/c94ade86ef13de115535b863a833e76c4405c11c/images/step_3_inst.png -------------------------------------------------------------------------------- /images/view_image_asset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rosaguilar/geetutorial/c94ade86ef13de115535b863a833e76c4405c11c/images/view_image_asset.png -------------------------------------------------------------------------------- /index.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "______\n", 8 | "\n", 9 | "## Google Earth Engine (GEE) Tutorial\n", 10 | "_____" 11 | ] 12 | }, 13 | { 14 | "cell_type": "markdown", 15 | "metadata": {}, 16 | "source": [ 17 | "This *tutorial* covers basic image processing in Google Earth Engine (GEE). Its purpose is to provide a user guide of GEE when using its python API. As a basic tutorial, it covers common tasks for data loading, image visualisation and processing. An example of image classification is provided and the ending topic is exporting results to eithera cloud platform or a local drive." 18 | ] 19 | }, 20 | { 21 | "cell_type": "markdown", 22 | "metadata": {}, 23 | "source": [ 24 | "**Content:**\n", 25 | "\n", 26 | "[1. Installation](GEE_installation.ipynb)
\n", 27 | "[2. Data loading](GEE_data_load.ipynb)
\n", 28 | "[3. Basic visualisation](GEE_basic_visualisation.ipynb)
\n", 29 | "[4. Histograms](GEE_histograms.ipynb)
\n", 30 | "[5. Linear filters](GEE_linear_filters.ipynb)
\n", 31 | "[6. Non linear filters](GEE_nonlinear_filters.ipynb)
\n", 32 | "[7. Feature extraction](GEE_feature_extraction.ipynb)
\n", 33 | "[8. Classification](GEE_image_classification.ipynb)
\n", 34 | "[9. Image Algebra](GEE_image_algebra.ipynb)
\n", 35 | "[10. Subset and export data](GEE_subset_export.ipynb)
\n", 36 | "\n" 37 | ] 38 | }, 39 | { 40 | "cell_type": "markdown", 41 | "metadata": {}, 42 | "source": [ 43 | "This tutorial is granted as is, free of charge for research and education purposes only. All functions were tested in Python 3.5.
\n", 44 | " Author: Aguilar, R., Zurita-Milla, R., Izquierdo-Verdiguier E.
\n", 45 | " Created: 31/05/2017
\n", 46 | " \n", 47 | "For further questions or if you plan to use it for non-scientific purposes, don't hesitate to contact me: r.m.aguilardearchila@utwente.nl" 48 | ] 49 | }, 50 | { 51 | "cell_type": "code", 52 | "execution_count": null, 53 | "metadata": { 54 | "collapsed": true 55 | }, 56 | "outputs": [], 57 | "source": [] 58 | } 59 | ], 60 | "metadata": { 61 | "kernelspec": { 62 | "display_name": "Python 3", 63 | "language": "python", 64 | "name": "python3" 65 | }, 66 | "language_info": { 67 | "codemirror_mode": { 68 | "name": "ipython", 69 | "version": 3 70 | }, 71 | "file_extension": ".py", 72 | "mimetype": "text/x-python", 73 | "name": "python", 74 | "nbconvert_exporter": "python", 75 | "pygments_lexer": "ipython3", 76 | "version": "3.5.1" 77 | } 78 | }, 79 | "nbformat": 4, 80 | "nbformat_minor": 2 81 | } 82 | --------------------------------------------------------------------------------