Spaces:
Runtime error
Runtime error
Upload 3 files
Browse files- image_call.py +389 -0
- model_architecture.json +1 -0
- requirements.txt +6 -0
image_call.py
ADDED
|
@@ -0,0 +1,389 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import ee
|
| 2 |
+
import numpy as np
|
| 3 |
+
from PIL import Image
|
| 4 |
+
import io
|
| 5 |
+
import pandas as pd
|
| 6 |
+
from datetime import datetime, timedelta
|
| 7 |
+
import requests
|
| 8 |
+
import os
|
| 9 |
+
import logging
|
| 10 |
+
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
| 11 |
+
|
| 12 |
+
service_account = "deploy-1@firepatternrecognition.iam.gserviceaccount.com"
|
| 13 |
+
credentials = ee.ServiceAccountCredentials(service_account, '2AB9532A8B7759C26D6980A570EF6EEE8B49DE78_firepatternrecognition-c10928272b24.json')
|
| 14 |
+
ee.Initialize(credentials)
|
| 15 |
+
|
| 16 |
+
# Initialize the Earth Engine module.
|
| 17 |
+
width, height = 158,292
|
| 18 |
+
nw_corner_list = [98.00, 20.15]
|
| 19 |
+
ne_corner_list = [99.58, 20.15]
|
| 20 |
+
sw_corner_list = [98.00, 17.23]
|
| 21 |
+
se_corner_list = [99.58, 17.23]
|
| 22 |
+
|
| 23 |
+
# Define the coordinates of the new area.
|
| 24 |
+
nw_corner = ee.Geometry.Point(nw_corner_list)
|
| 25 |
+
ne_corner = ee.Geometry.Point(ne_corner_list)
|
| 26 |
+
sw_corner = ee.Geometry.Point(sw_corner_list)
|
| 27 |
+
se_corner = ee.Geometry.Point(se_corner_list)
|
| 28 |
+
|
| 29 |
+
# Create a rectangle from the corners.
|
| 30 |
+
area = ee.Geometry.Polygon([
|
| 31 |
+
[nw_corner.coordinates(), ne_corner.coordinates(), se_corner.coordinates(), sw_corner.coordinates(), nw_corner.coordinates()]
|
| 32 |
+
])
|
| 33 |
+
|
| 34 |
+
def calculate_ndvi(image):
|
| 35 |
+
"""Calculate NDVI for an image."""
|
| 36 |
+
ndvi = image.normalizedDifference(['B8', 'B4']).rename('NDVI')
|
| 37 |
+
return image.addBands(ndvi)
|
| 38 |
+
|
| 39 |
+
def create_image_ndvi(date1, date2, new_area=area):
|
| 40 |
+
logging.info("Starting create image ndvi")
|
| 41 |
+
date_obj = datetime.strptime(date2, '%Y-%m-%d')
|
| 42 |
+
new_date_obj = date_obj + timedelta(days=1)
|
| 43 |
+
new_date_str = new_date_obj.strftime('%Y-%m-%d')
|
| 44 |
+
|
| 45 |
+
# Create an ImageCollection and filter it by date and bounds
|
| 46 |
+
image_collection = ee.ImageCollection('COPERNICUS/S2_SR') \
|
| 47 |
+
.filterDate(date1, new_date_str) \
|
| 48 |
+
.filterBounds(new_area)
|
| 49 |
+
|
| 50 |
+
# Select bands 4 and 8 and calculate NDVI for each image in the collection
|
| 51 |
+
image_collection = image_collection.select(['B4', 'B8']).map(calculate_ndvi)
|
| 52 |
+
|
| 53 |
+
# Get the median NDVI image and clip it to the area of interest
|
| 54 |
+
ndvi_image = image_collection.select('NDVI').max().clip(new_area)
|
| 55 |
+
ndvi_vis_params = {
|
| 56 |
+
'min': -1,
|
| 57 |
+
'max': 1,
|
| 58 |
+
'palette': ['white', 'black']
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
# Get the URL for the NDVI image
|
| 62 |
+
url = ndvi_image.getThumbURL({
|
| 63 |
+
'min': ndvi_vis_params['min'],
|
| 64 |
+
'max': ndvi_vis_params['max'],
|
| 65 |
+
'palette': ','.join(ndvi_vis_params['palette']),
|
| 66 |
+
'region': new_area,
|
| 67 |
+
'dimensions': [width, height],
|
| 68 |
+
'format': 'png'
|
| 69 |
+
})
|
| 70 |
+
|
| 71 |
+
response = requests.get(url)
|
| 72 |
+
image = Image.open(io.BytesIO(response.content)).convert("L")
|
| 73 |
+
ndvi_array = np.array(image)
|
| 74 |
+
|
| 75 |
+
ndvi_array = ndvi_array / 255.0
|
| 76 |
+
logging.info("End create image ndvi")
|
| 77 |
+
|
| 78 |
+
return ndvi_array,image
|
| 79 |
+
|
| 80 |
+
def calculate_ndwi(image):
|
| 81 |
+
ndwi = image.normalizedDifference(['B3', 'B8']).rename('NDWI')
|
| 82 |
+
return image.addBands(ndwi)
|
| 83 |
+
|
| 84 |
+
def create_image_ndwi(date1, date2, new_area=area):
|
| 85 |
+
logging.info("Starting create image ndwi")
|
| 86 |
+
date_obj = datetime.strptime(date2, '%Y-%m-%d')
|
| 87 |
+
new_date_obj = date_obj + timedelta(days=1)
|
| 88 |
+
new_date_str = new_date_obj.strftime('%Y-%m-%d')
|
| 89 |
+
|
| 90 |
+
image_collection = ee.ImageCollection('COPERNICUS/S2_SR') \
|
| 91 |
+
.filterDate(date1, new_date_str) \
|
| 92 |
+
.filterBounds(new_area)
|
| 93 |
+
|
| 94 |
+
# Select bands 3 and 8 and calculate NDWI for each image in the collection
|
| 95 |
+
image_collection = image_collection.select(['B3', 'B8']).map(calculate_ndwi)
|
| 96 |
+
|
| 97 |
+
# Get the mean NDWI image and clip it to the area of interest
|
| 98 |
+
ndwi_image = image_collection.select('NDWI').max().clip(new_area)
|
| 99 |
+
|
| 100 |
+
# Define visualization parameters for NDWI
|
| 101 |
+
ndwi_vis_params = {
|
| 102 |
+
'min': -1,
|
| 103 |
+
'max': 1,
|
| 104 |
+
'palette': ['white', 'black']
|
| 105 |
+
}
|
| 106 |
+
|
| 107 |
+
# Get the URL for the NDWI image
|
| 108 |
+
url = ndwi_image.getThumbURL({
|
| 109 |
+
'min': ndwi_vis_params['min'],
|
| 110 |
+
'max': ndwi_vis_params['max'],
|
| 111 |
+
'palette': ','.join(ndwi_vis_params['palette']),
|
| 112 |
+
'region': new_area,
|
| 113 |
+
'dimensions': [width, height],
|
| 114 |
+
'format': 'png'
|
| 115 |
+
})
|
| 116 |
+
|
| 117 |
+
# Request the image from the URL
|
| 118 |
+
response = requests.get(url)
|
| 119 |
+
image = Image.open(io.BytesIO(response.content)).convert("L")
|
| 120 |
+
|
| 121 |
+
# Convert the image to a NumPy array
|
| 122 |
+
ndwi_array = np.array(image)
|
| 123 |
+
ndwi_array = ndwi_array / 255
|
| 124 |
+
logging.info("End create image ndwi")
|
| 125 |
+
|
| 126 |
+
return ndwi_array,image
|
| 127 |
+
|
| 128 |
+
|
| 129 |
+
def calculate_ndmi(image):
|
| 130 |
+
ndmi = image.normalizedDifference(['B8', 'B11']).rename('NDMI')
|
| 131 |
+
return image.addBands(ndmi)
|
| 132 |
+
|
| 133 |
+
def create_image_ndmi(date1, date2, new_area=area):
|
| 134 |
+
logging.info("Starting create image ndmi")
|
| 135 |
+
date_obj = datetime.strptime(date2, '%Y-%m-%d')
|
| 136 |
+
new_date_obj = date_obj + timedelta(days=1)
|
| 137 |
+
new_date_str = new_date_obj.strftime('%Y-%m-%d')
|
| 138 |
+
|
| 139 |
+
# Create an ImageCollection and filter it by date and bounds
|
| 140 |
+
image_collection = ee.ImageCollection('COPERNICUS/S2_SR') \
|
| 141 |
+
.filterDate(date1, new_date_str) \
|
| 142 |
+
.filterBounds(new_area)
|
| 143 |
+
|
| 144 |
+
# Select bands 8 and 11 and calculate NDMI for each image in the collection
|
| 145 |
+
image_collection = image_collection.select(['B8', 'B11']).map(calculate_ndmi)
|
| 146 |
+
|
| 147 |
+
# Get the mean NDMI image and clip it to the area of interest
|
| 148 |
+
ndmi_image = image_collection.select('NDMI').max().clip(new_area)
|
| 149 |
+
|
| 150 |
+
# Define visualization parameters for NDMI
|
| 151 |
+
ndmi_vis_params = {
|
| 152 |
+
'min': -1,
|
| 153 |
+
'max': 1,
|
| 154 |
+
'palette': ['white', 'black']
|
| 155 |
+
}
|
| 156 |
+
|
| 157 |
+
# Get the URL for the NDMI image
|
| 158 |
+
url = ndmi_image.getThumbURL({
|
| 159 |
+
'min': ndmi_vis_params['min'],
|
| 160 |
+
'max': ndmi_vis_params['max'],
|
| 161 |
+
'palette': ','.join(ndmi_vis_params['palette']),
|
| 162 |
+
'region': new_area,
|
| 163 |
+
'dimensions': [width, height],
|
| 164 |
+
'format': 'png'
|
| 165 |
+
})
|
| 166 |
+
|
| 167 |
+
# Request the image from the URL
|
| 168 |
+
response = requests.get(url)
|
| 169 |
+
image = Image.open(io.BytesIO(response.content)).convert("L")
|
| 170 |
+
|
| 171 |
+
# Convert the image to a NumPy array
|
| 172 |
+
ndmi_array = np.array(image)
|
| 173 |
+
ndmi_array = ndmi_array/255
|
| 174 |
+
|
| 175 |
+
logging.info("End create image ndmi")
|
| 176 |
+
|
| 177 |
+
return ndmi_array,image
|
| 178 |
+
|
| 179 |
+
|
| 180 |
+
def calculate_nddi(image):
|
| 181 |
+
ndvi = image.select('NDVI')
|
| 182 |
+
ndwi = image.select('NDWI')
|
| 183 |
+
# nddi = ndvi.subtract(ndwi).divide(ndvi.add(ndwi)).rename('NDDI')
|
| 184 |
+
nddi = ndvi.subtract(ndwi).rename('NDDI')
|
| 185 |
+
return nddi
|
| 186 |
+
|
| 187 |
+
def create_image_nddi(date1, date2, new_area=area):
|
| 188 |
+
logging.info("Starting create image nddi")
|
| 189 |
+
# Parse the end date and add one day
|
| 190 |
+
date_obj = datetime.strptime(date2, '%Y-%m-%d')
|
| 191 |
+
new_date_obj = date_obj + timedelta(days=1)
|
| 192 |
+
new_date_str = new_date_obj.strftime('%Y-%m-%d')
|
| 193 |
+
|
| 194 |
+
# Create an ImageCollection and filter it by date and bounds
|
| 195 |
+
image_collection = ee.ImageCollection('COPERNICUS/S2_SR') \
|
| 196 |
+
.filterDate(date1, new_date_str) \
|
| 197 |
+
.filterBounds(new_area)
|
| 198 |
+
|
| 199 |
+
# Select bands 8, 4, and 3 and calculate NDVI and NDWI for each image in the collection
|
| 200 |
+
image_collection = image_collection.select(['B8', 'B4', 'B3']).map(calculate_ndvi).map(calculate_ndwi)
|
| 201 |
+
|
| 202 |
+
# Calculate NDDI for each image in the collection
|
| 203 |
+
# image_collection = image_collection.map(lambda image: image.addBands(calculate_nddi(image)))
|
| 204 |
+
image_collection = image_collection.map(calculate_nddi)
|
| 205 |
+
|
| 206 |
+
# Get the mean NDDI image and clip it to the area of interest
|
| 207 |
+
nddi_image = image_collection.select('NDDI').max().clip(new_area)
|
| 208 |
+
|
| 209 |
+
# Define visualization parameters for NDDI
|
| 210 |
+
nddi_vis_params = {
|
| 211 |
+
'min': -1,
|
| 212 |
+
'max': 1,
|
| 213 |
+
'palette': ['white', 'black']
|
| 214 |
+
}
|
| 215 |
+
|
| 216 |
+
# Get the URL for the NDDI image
|
| 217 |
+
url = nddi_image.getThumbURL({
|
| 218 |
+
'min': nddi_vis_params['min'],
|
| 219 |
+
'max': nddi_vis_params['max'],
|
| 220 |
+
'palette': ','.join(nddi_vis_params['palette']),
|
| 221 |
+
'region': new_area,
|
| 222 |
+
'dimensions': [width, height],
|
| 223 |
+
'format': 'png'
|
| 224 |
+
})
|
| 225 |
+
|
| 226 |
+
# Request the image from the URL
|
| 227 |
+
response = requests.get(url)
|
| 228 |
+
image = Image.open(io.BytesIO(response.content)).convert("L")
|
| 229 |
+
|
| 230 |
+
# Convert the image to a NumPy array
|
| 231 |
+
nddi_array = np.array(image)
|
| 232 |
+
nddi_array = nddi_array /255
|
| 233 |
+
|
| 234 |
+
logging.info("End create image nddi")
|
| 235 |
+
|
| 236 |
+
return nddi_array,image
|
| 237 |
+
|
| 238 |
+
def calculate_savi(image):
|
| 239 |
+
red = image.select('B4')
|
| 240 |
+
nir = image.select('B8')
|
| 241 |
+
# Define the soil adjustment factor (L), typically between 0 to 1
|
| 242 |
+
L = 0.5
|
| 243 |
+
savi = nir.subtract(red).multiply(1 + L).divide(nir.add(red).add(L)).rename('SAVI')
|
| 244 |
+
return image.addBands(savi)
|
| 245 |
+
|
| 246 |
+
def create_image_savi(date1, date2, new_area=area):
|
| 247 |
+
logging.info("Starting create image savi")
|
| 248 |
+
# Parse the end date and add one day
|
| 249 |
+
date_obj = datetime.strptime(date2, '%Y-%m-%d')
|
| 250 |
+
new_date_obj = date_obj + timedelta(days=1)
|
| 251 |
+
new_date_str = new_date_obj.strftime('%Y-%m-%d')
|
| 252 |
+
|
| 253 |
+
# Create an ImageCollection and filter it by date and bounds
|
| 254 |
+
image_collection = ee.ImageCollection('COPERNICUS/S2_SR') \
|
| 255 |
+
.filterDate(date1, new_date_str) \
|
| 256 |
+
.filterBounds(new_area)
|
| 257 |
+
|
| 258 |
+
# Select bands 4, 8, and 12 and calculate SAVI for each image in the collection
|
| 259 |
+
image_collection = image_collection.select(['B4', 'B8', 'B12']).map(calculate_savi)
|
| 260 |
+
|
| 261 |
+
# Get the mean SAVI image and clip it to the area of interest
|
| 262 |
+
savi_image = image_collection.select('SAVI').max().clip(new_area)
|
| 263 |
+
|
| 264 |
+
# Define visualization parameters for SAVI
|
| 265 |
+
savi_vis_params = {
|
| 266 |
+
'min': -1,
|
| 267 |
+
'max': 1,
|
| 268 |
+
'palette': ['white', 'black']
|
| 269 |
+
}
|
| 270 |
+
|
| 271 |
+
# Get the URL for the SAVI image
|
| 272 |
+
url = savi_image.getThumbURL({
|
| 273 |
+
'min': savi_vis_params['min'],
|
| 274 |
+
'max': savi_vis_params['max'],
|
| 275 |
+
'palette': ','.join(savi_vis_params['palette']),
|
| 276 |
+
'region': new_area,
|
| 277 |
+
'dimensions': [158, 292],
|
| 278 |
+
'format': 'png'
|
| 279 |
+
})
|
| 280 |
+
|
| 281 |
+
# Request the image from the URL
|
| 282 |
+
response = requests.get(url)
|
| 283 |
+
image = Image.open(io.BytesIO(response.content)).convert("L")
|
| 284 |
+
|
| 285 |
+
# Convert the image to a NumPy array
|
| 286 |
+
savi_array = np.array(image)
|
| 287 |
+
|
| 288 |
+
# Normalize the values to be between -1 and 1
|
| 289 |
+
savi_array = savi_array / 255
|
| 290 |
+
|
| 291 |
+
logging.info("End create image savi")
|
| 292 |
+
|
| 293 |
+
return savi_array,image
|
| 294 |
+
|
| 295 |
+
def date_create(today_date,new_area=area):
|
| 296 |
+
# today_date = datetime.today().strftime('%Y-%m-%d')
|
| 297 |
+
today_date = datetime.strptime(today_date, '%Y-%m-%d')
|
| 298 |
+
seven_days_ago = (today_date - timedelta(days=7)).strftime('%Y-%m-%d')
|
| 299 |
+
image_collection = ee.ImageCollection('COPERNICUS/S2_SR')
|
| 300 |
+
image_collection_filter = image_collection.filterDate(seven_days_ago, today_date).filterBounds(new_area)
|
| 301 |
+
image_info = image_collection_filter.aggregate_array('system:index').getInfo()
|
| 302 |
+
image_dates = image_collection_filter.aggregate_array('system:time_start').map(lambda d: ee.Date(d).format('YYYY-MM-dd')).getInfo()
|
| 303 |
+
df_day = pd.DataFrame({'Image ID': image_info, 'Date': image_dates})
|
| 304 |
+
df_du = pd.unique(df_day['Date'])
|
| 305 |
+
df_latest_2day = df_du[-2:]
|
| 306 |
+
return df_latest_2day
|
| 307 |
+
|
| 308 |
+
def load_and_process_file(file_path):
|
| 309 |
+
logging.info(f"Loading file: {file_path}")
|
| 310 |
+
# Check if the file exists
|
| 311 |
+
if not os.path.isfile(file_path):
|
| 312 |
+
raise FileNotFoundError(f"The file '{file_path}' does not exist.")
|
| 313 |
+
|
| 314 |
+
# Check the file extension
|
| 315 |
+
file_extension = os.path.splitext(file_path)[1].lower()
|
| 316 |
+
|
| 317 |
+
if file_extension == '.csv':
|
| 318 |
+
# Load CSV file
|
| 319 |
+
df = pd.read_csv(file_path)
|
| 320 |
+
elif file_extension in ['.xls', '.xlsx']:
|
| 321 |
+
# Load Excel file
|
| 322 |
+
df = pd.read_excel(file_path)
|
| 323 |
+
else:
|
| 324 |
+
raise ValueError("The file must be a CSV or Excel file with extensions '.csv', '.xls', or '.xlsx'.")
|
| 325 |
+
|
| 326 |
+
# Convert column names to lowercase
|
| 327 |
+
df.columns = df.columns.str.lower()
|
| 328 |
+
df = df[["latitude","longitude","acq_date"]]
|
| 329 |
+
|
| 330 |
+
return df
|
| 331 |
+
|
| 332 |
+
def filter_latest_date(df, date_column='date'):
|
| 333 |
+
lat_min = sw_corner_list[1]
|
| 334 |
+
lat_max = nw_corner_list[1]
|
| 335 |
+
lon_min = sw_corner_list[0]
|
| 336 |
+
lon_max = se_corner_list[0]
|
| 337 |
+
|
| 338 |
+
df = df[(df['latitude'] >= lat_min) & (df['latitude'] <= lat_max) &
|
| 339 |
+
(df['longitude'] >= lon_min) & (df['longitude'] <= lon_max)]
|
| 340 |
+
|
| 341 |
+
# Convert the date column to datetime format
|
| 342 |
+
df[date_column] = pd.to_datetime(df[date_column])
|
| 343 |
+
|
| 344 |
+
# Find the latest date
|
| 345 |
+
latest_date = df[date_column].max()
|
| 346 |
+
|
| 347 |
+
# Filter the DataFrame to only include rows with the latest date
|
| 348 |
+
filtered_df = df[df[date_column] == latest_date]
|
| 349 |
+
filtered_df = filtered_df.reset_index(drop=True)
|
| 350 |
+
|
| 351 |
+
|
| 352 |
+
logging.info(f"Loading file: {str(filtered_df[date_column][0].date())}")
|
| 353 |
+
return filtered_df
|
| 354 |
+
|
| 355 |
+
def create_image_from_coordinates(df):
|
| 356 |
+
logging.info("Start create_image_from_coordinates")
|
| 357 |
+
|
| 358 |
+
# Create a blank (black) image array
|
| 359 |
+
image_array = np.zeros((height, width), dtype=np.uint8)
|
| 360 |
+
|
| 361 |
+
# Function to convert lat/lon to pixel coordinates
|
| 362 |
+
def latlon_to_pixel(lat, lon):
|
| 363 |
+
lat_range = nw_corner_list[1] - sw_corner_list[1]
|
| 364 |
+
lon_range = ne_corner_list[0] - nw_corner_list[0]
|
| 365 |
+
|
| 366 |
+
y = int(height * (nw_corner_list[1] - lat) / lat_range)
|
| 367 |
+
x = int(width * (lon - nw_corner_list[0]) / lon_range)
|
| 368 |
+
|
| 369 |
+
return x, y
|
| 370 |
+
|
| 371 |
+
# Iterate through each coordinate in the dataframe
|
| 372 |
+
for index, row in df.iterrows():
|
| 373 |
+
lat, lon = row['latitude'], row['longitude']
|
| 374 |
+
x, y = latlon_to_pixel(lat, lon)
|
| 375 |
+
|
| 376 |
+
# Paint a 11x11 pixel square centered on the hotspot coordinate if within bounds
|
| 377 |
+
for dx in range(-2, 3):
|
| 378 |
+
for dy in range(-2, 3):
|
| 379 |
+
new_x = x + dx
|
| 380 |
+
new_y = y + dy
|
| 381 |
+
if 0 <= new_x < width and 0 <= new_y < height:
|
| 382 |
+
image_array[new_y, new_x] = 255
|
| 383 |
+
|
| 384 |
+
# Convert array to PIL Image
|
| 385 |
+
pil_image = Image.fromarray(image_array).convert("L")
|
| 386 |
+
logging.info("End create_image_from_coordinates")
|
| 387 |
+
|
| 388 |
+
# Return both the array and the PIL Image
|
| 389 |
+
return image_array
|
model_architecture.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
{"class_name": "Sequential", "config": {"name": "sequential", "layers": [{"module": "keras.layers", "class_name": "InputLayer", "config": {"batch_input_shape": [null, 292, 158, 6], "dtype": "float32", "sparse": false, "ragged": false, "name": "input_1"}, "registered_name": null}, {"module": "keras.layers", "class_name": "Conv2D", "config": {"name": "conv2d", "trainable": true, "dtype": "float32", "filters": 32, "kernel_size": [3, 3], "strides": [1, 1], "padding": "same", "data_format": "channels_last", "dilation_rate": [1, 1], "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"module": "keras.initializers", "class_name": "GlorotUniform", "config": {"seed": null}, "registered_name": null}, "bias_initializer": {"module": "keras.initializers", "class_name": "Zeros", "config": {}, "registered_name": null}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "registered_name": null, "build_config": {"input_shape": [null, 292, 158, 6]}}, {"module": "keras.layers", "class_name": "MaxPooling2D", "config": {"name": "max_pooling2d", "trainable": true, "dtype": "float32", "pool_size": [2, 2], "padding": "valid", "strides": [2, 2], "data_format": "channels_last"}, "registered_name": null, "build_config": {"input_shape": [null, 292, 158, 32]}}, {"module": "keras.layers", "class_name": "BatchNormalization", "config": {"name": "batch_normalization", "trainable": true, "dtype": "float32", "axis": [3], "momentum": 0.99, "epsilon": 0.001, "center": true, "scale": true, "beta_initializer": {"module": "keras.initializers", "class_name": "Zeros", "config": {}, "registered_name": null}, "gamma_initializer": {"module": "keras.initializers", "class_name": "Ones", "config": {}, "registered_name": null}, "moving_mean_initializer": {"module": "keras.initializers", "class_name": "Zeros", "config": {}, "registered_name": null}, "moving_variance_initializer": {"module": "keras.initializers", "class_name": "Ones", "config": {}, "registered_name": null}, "beta_regularizer": null, "gamma_regularizer": null, "beta_constraint": null, "gamma_constraint": null}, "registered_name": null, "build_config": {"input_shape": [null, 146, 79, 32]}}, {"module": "keras.layers", "class_name": "Dropout", "config": {"name": "dropout", "trainable": true, "dtype": "float32", "rate": 0.2, "noise_shape": null, "seed": null}, "registered_name": null, "build_config": {"input_shape": [null, 146, 79, 32]}}, {"module": "keras.layers", "class_name": "Conv2D", "config": {"name": "conv2d_1", "trainable": true, "dtype": "float32", "filters": 64, "kernel_size": [3, 3], "strides": [1, 1], "padding": "same", "data_format": "channels_last", "dilation_rate": [1, 1], "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"module": "keras.initializers", "class_name": "GlorotUniform", "config": {"seed": null}, "registered_name": null}, "bias_initializer": {"module": "keras.initializers", "class_name": "Zeros", "config": {}, "registered_name": null}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "registered_name": null, "build_config": {"input_shape": [null, 146, 79, 32]}}, {"module": "keras.layers", "class_name": "MaxPooling2D", "config": {"name": "max_pooling2d_1", "trainable": true, "dtype": "float32", "pool_size": [2, 2], "padding": "valid", "strides": [2, 2], "data_format": "channels_last"}, "registered_name": null, "build_config": {"input_shape": [null, 146, 79, 64]}}, {"module": "keras.layers", "class_name": "BatchNormalization", "config": {"name": "batch_normalization_1", "trainable": true, "dtype": "float32", "axis": [3], "momentum": 0.99, "epsilon": 0.001, "center": true, "scale": true, "beta_initializer": {"module": "keras.initializers", "class_name": "Zeros", "config": {}, "registered_name": null}, "gamma_initializer": {"module": "keras.initializers", "class_name": "Ones", "config": {}, "registered_name": null}, "moving_mean_initializer": {"module": "keras.initializers", "class_name": "Zeros", "config": {}, "registered_name": null}, "moving_variance_initializer": {"module": "keras.initializers", "class_name": "Ones", "config": {}, "registered_name": null}, "beta_regularizer": null, "gamma_regularizer": null, "beta_constraint": null, "gamma_constraint": null}, "registered_name": null, "build_config": {"input_shape": [null, 73, 39, 64]}}, {"module": "keras.layers", "class_name": "Dropout", "config": {"name": "dropout_1", "trainable": true, "dtype": "float32", "rate": 0.3, "noise_shape": null, "seed": null}, "registered_name": null, "build_config": {"input_shape": [null, 73, 39, 64]}}, {"module": "keras.layers", "class_name": "Conv2D", "config": {"name": "conv2d_2", "trainable": true, "dtype": "float32", "filters": 128, "kernel_size": [3, 3], "strides": [1, 1], "padding": "same", "data_format": "channels_last", "dilation_rate": [1, 1], "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"module": "keras.initializers", "class_name": "GlorotUniform", "config": {"seed": null}, "registered_name": null}, "bias_initializer": {"module": "keras.initializers", "class_name": "Zeros", "config": {}, "registered_name": null}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "registered_name": null, "build_config": {"input_shape": [null, 73, 39, 64]}}, {"module": "keras.layers", "class_name": "MaxPooling2D", "config": {"name": "max_pooling2d_2", "trainable": true, "dtype": "float32", "pool_size": [2, 2], "padding": "valid", "strides": [2, 2], "data_format": "channels_last"}, "registered_name": null, "build_config": {"input_shape": [null, 73, 39, 128]}}, {"module": "keras.layers", "class_name": "BatchNormalization", "config": {"name": "batch_normalization_2", "trainable": true, "dtype": "float32", "axis": [3], "momentum": 0.99, "epsilon": 0.001, "center": true, "scale": true, "beta_initializer": {"module": "keras.initializers", "class_name": "Zeros", "config": {}, "registered_name": null}, "gamma_initializer": {"module": "keras.initializers", "class_name": "Ones", "config": {}, "registered_name": null}, "moving_mean_initializer": {"module": "keras.initializers", "class_name": "Zeros", "config": {}, "registered_name": null}, "moving_variance_initializer": {"module": "keras.initializers", "class_name": "Ones", "config": {}, "registered_name": null}, "beta_regularizer": null, "gamma_regularizer": null, "beta_constraint": null, "gamma_constraint": null}, "registered_name": null, "build_config": {"input_shape": [null, 36, 19, 128]}}, {"module": "keras.layers", "class_name": "Dropout", "config": {"name": "dropout_2", "trainable": true, "dtype": "float32", "rate": 0.4, "noise_shape": null, "seed": null}, "registered_name": null, "build_config": {"input_shape": [null, 36, 19, 128]}}, {"module": "keras.layers", "class_name": "Conv2D", "config": {"name": "conv2d_3", "trainable": true, "dtype": "float32", "filters": 256, "kernel_size": [3, 3], "strides": [1, 1], "padding": "same", "data_format": "channels_last", "dilation_rate": [1, 1], "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"module": "keras.initializers", "class_name": "GlorotUniform", "config": {"seed": null}, "registered_name": null}, "bias_initializer": {"module": "keras.initializers", "class_name": "Zeros", "config": {}, "registered_name": null}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "registered_name": null, "build_config": {"input_shape": [null, 36, 19, 128]}}, {"module": "keras.layers", "class_name": "MaxPooling2D", "config": {"name": "max_pooling2d_3", "trainable": true, "dtype": "float32", "pool_size": [2, 2], "padding": "valid", "strides": [2, 2], "data_format": "channels_last"}, "registered_name": null, "build_config": {"input_shape": [null, 36, 19, 256]}}, {"module": "keras.layers", "class_name": "BatchNormalization", "config": {"name": "batch_normalization_3", "trainable": true, "dtype": "float32", "axis": [3], "momentum": 0.99, "epsilon": 0.001, "center": true, "scale": true, "beta_initializer": {"module": "keras.initializers", "class_name": "Zeros", "config": {}, "registered_name": null}, "gamma_initializer": {"module": "keras.initializers", "class_name": "Ones", "config": {}, "registered_name": null}, "moving_mean_initializer": {"module": "keras.initializers", "class_name": "Zeros", "config": {}, "registered_name": null}, "moving_variance_initializer": {"module": "keras.initializers", "class_name": "Ones", "config": {}, "registered_name": null}, "beta_regularizer": null, "gamma_regularizer": null, "beta_constraint": null, "gamma_constraint": null}, "registered_name": null, "build_config": {"input_shape": [null, 18, 9, 256]}}, {"module": "keras.layers", "class_name": "Dropout", "config": {"name": "dropout_3", "trainable": true, "dtype": "float32", "rate": 0.5, "noise_shape": null, "seed": null}, "registered_name": null, "build_config": {"input_shape": [null, 18, 9, 256]}}, {"module": "keras.layers", "class_name": "Conv2D", "config": {"name": "conv2d_4", "trainable": true, "dtype": "float32", "filters": 512, "kernel_size": [3, 3], "strides": [1, 1], "padding": "same", "data_format": "channels_last", "dilation_rate": [1, 1], "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"module": "keras.initializers", "class_name": "GlorotUniform", "config": {"seed": null}, "registered_name": null}, "bias_initializer": {"module": "keras.initializers", "class_name": "Zeros", "config": {}, "registered_name": null}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "registered_name": null, "build_config": {"input_shape": [null, 18, 9, 256]}}, {"module": "keras.layers", "class_name": "MaxPooling2D", "config": {"name": "max_pooling2d_4", "trainable": true, "dtype": "float32", "pool_size": [2, 2], "padding": "valid", "strides": [2, 2], "data_format": "channels_last"}, "registered_name": null, "build_config": {"input_shape": [null, 18, 9, 512]}}, {"module": "keras.layers", "class_name": "BatchNormalization", "config": {"name": "batch_normalization_4", "trainable": true, "dtype": "float32", "axis": [3], "momentum": 0.99, "epsilon": 0.001, "center": true, "scale": true, "beta_initializer": {"module": "keras.initializers", "class_name": "Zeros", "config": {}, "registered_name": null}, "gamma_initializer": {"module": "keras.initializers", "class_name": "Ones", "config": {}, "registered_name": null}, "moving_mean_initializer": {"module": "keras.initializers", "class_name": "Zeros", "config": {}, "registered_name": null}, "moving_variance_initializer": {"module": "keras.initializers", "class_name": "Ones", "config": {}, "registered_name": null}, "beta_regularizer": null, "gamma_regularizer": null, "beta_constraint": null, "gamma_constraint": null}, "registered_name": null, "build_config": {"input_shape": [null, 9, 4, 512]}}, {"module": "keras.layers", "class_name": "Dropout", "config": {"name": "dropout_4", "trainable": true, "dtype": "float32", "rate": 0.5, "noise_shape": null, "seed": null}, "registered_name": null, "build_config": {"input_shape": [null, 9, 4, 512]}}, {"module": "keras.layers", "class_name": "Flatten", "config": {"name": "flatten", "trainable": true, "dtype": "float32", "data_format": "channels_last"}, "registered_name": null, "build_config": {"input_shape": [null, 9, 4, 512]}}, {"module": "keras.layers", "class_name": "Dense", "config": {"name": "dense", "trainable": true, "dtype": "float32", "units": 512, "activation": "relu", "use_bias": true, "kernel_initializer": {"module": "keras.initializers", "class_name": "GlorotUniform", "config": {"seed": null}, "registered_name": null}, "bias_initializer": {"module": "keras.initializers", "class_name": "Zeros", "config": {}, "registered_name": null}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "registered_name": null, "build_config": {"input_shape": [null, 18432]}}, {"module": "keras.layers", "class_name": "Dropout", "config": {"name": "dropout_5", "trainable": true, "dtype": "float32", "rate": 0.5, "noise_shape": null, "seed": null}, "registered_name": null, "build_config": {"input_shape": [null, 512]}}, {"module": "keras.layers", "class_name": "Dense", "config": {"name": "dense_1", "trainable": true, "dtype": "float32", "units": 1024, "activation": "relu", "use_bias": true, "kernel_initializer": {"module": "keras.initializers", "class_name": "GlorotUniform", "config": {"seed": null}, "registered_name": null}, "bias_initializer": {"module": "keras.initializers", "class_name": "Zeros", "config": {}, "registered_name": null}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "registered_name": null, "build_config": {"input_shape": [null, 512]}}, {"module": "keras.layers", "class_name": "Dropout", "config": {"name": "dropout_6", "trainable": true, "dtype": "float32", "rate": 0.5, "noise_shape": null, "seed": null}, "registered_name": null, "build_config": {"input_shape": [null, 1024]}}, {"module": "keras.layers", "class_name": "Dense", "config": {"name": "dense_2", "trainable": true, "dtype": "float32", "units": 1024, "activation": "relu", "use_bias": true, "kernel_initializer": {"module": "keras.initializers", "class_name": "GlorotUniform", "config": {"seed": null}, "registered_name": null}, "bias_initializer": {"module": "keras.initializers", "class_name": "Zeros", "config": {}, "registered_name": null}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "registered_name": null, "build_config": {"input_shape": [null, 1024]}}, {"module": "keras.layers", "class_name": "Dropout", "config": {"name": "dropout_7", "trainable": true, "dtype": "float32", "rate": 0.5, "noise_shape": null, "seed": null}, "registered_name": null, "build_config": {"input_shape": [null, 1024]}}, {"module": "keras.layers", "class_name": "Dense", "config": {"name": "dense_3", "trainable": true, "dtype": "float32", "units": 512, "activation": "relu", "use_bias": true, "kernel_initializer": {"module": "keras.initializers", "class_name": "GlorotUniform", "config": {"seed": null}, "registered_name": null}, "bias_initializer": {"module": "keras.initializers", "class_name": "Zeros", "config": {}, "registered_name": null}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "registered_name": null, "build_config": {"input_shape": [null, 1024]}}, {"module": "keras.layers", "class_name": "Dense", "config": {"name": "dense_4", "trainable": true, "dtype": "float32", "units": 138408, "activation": "sigmoid", "use_bias": true, "kernel_initializer": {"module": "keras.initializers", "class_name": "GlorotUniform", "config": {"seed": null}, "registered_name": null}, "bias_initializer": {"module": "keras.initializers", "class_name": "Zeros", "config": {}, "registered_name": null}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "registered_name": null, "build_config": {"input_shape": [null, 512]}}, {"module": "keras.layers", "class_name": "Reshape", "config": {"name": "reshape", "trainable": true, "dtype": "float32", "target_shape": [292, 158, 3]}, "registered_name": null, "build_config": {"input_shape": [null, 138408]}}]}, "keras_version": "2.15.0", "backend": "tensorflow"}
|
requirements.txt
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
earthengine-api --upgrade
|
| 2 |
+
pillow==10.3.0
|
| 3 |
+
numpy
|
| 4 |
+
pandas
|
| 5 |
+
xlrd
|
| 6 |
+
tensorflow
|