opticallyshallowdeep 1.2.1__tar.gz → 1.2.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. {opticallyshallowdeep-1.2.1 → opticallyshallowdeep-1.2.3}/PKG-INFO +29 -9
  2. opticallyshallowdeep-1.2.1/opticallyshallowdeep.egg-info/PKG-INFO → opticallyshallowdeep-1.2.3/README.md +16 -26
  3. opticallyshallowdeep-1.2.3/opticallyshallowdeep/__init__.py +1 -0
  4. {opticallyshallowdeep-1.2.1 → opticallyshallowdeep-1.2.3}/opticallyshallowdeep/check_transpose.py +1 -4
  5. {opticallyshallowdeep-1.2.1 → opticallyshallowdeep-1.2.3}/opticallyshallowdeep/cloud_mask.py +1 -6
  6. {opticallyshallowdeep-1.2.1 → opticallyshallowdeep-1.2.3}/opticallyshallowdeep/find_epsg.py +0 -19
  7. {opticallyshallowdeep-1.2.1 → opticallyshallowdeep-1.2.3}/opticallyshallowdeep/make_multiband_image.py +1 -3
  8. {opticallyshallowdeep-1.2.1 → opticallyshallowdeep-1.2.3}/opticallyshallowdeep/make_vertical_strips.py +1 -6
  9. {opticallyshallowdeep-1.2.1 → opticallyshallowdeep-1.2.3}/opticallyshallowdeep/netcdf_to_multiband_geotiff.py +1 -5
  10. {opticallyshallowdeep-1.2.1 → opticallyshallowdeep-1.2.3}/opticallyshallowdeep/parse_string.py +1 -3
  11. {opticallyshallowdeep-1.2.1 → opticallyshallowdeep-1.2.3}/opticallyshallowdeep/process_as_strips.py +1 -20
  12. {opticallyshallowdeep-1.2.1 → opticallyshallowdeep-1.2.3}/opticallyshallowdeep/run.py +2 -6
  13. {opticallyshallowdeep-1.2.1 → opticallyshallowdeep-1.2.3}/opticallyshallowdeep/write_georef_image.py +1 -3
  14. opticallyshallowdeep-1.2.1/README.md → opticallyshallowdeep-1.2.3/opticallyshallowdeep.egg-info/PKG-INFO +46 -5
  15. {opticallyshallowdeep-1.2.1 → opticallyshallowdeep-1.2.3}/opticallyshallowdeep.egg-info/requires.txt +2 -2
  16. {opticallyshallowdeep-1.2.1 → opticallyshallowdeep-1.2.3}/setup.py +2 -2
  17. opticallyshallowdeep-1.2.1/opticallyshallowdeep/__init__.py +0 -2
  18. {opticallyshallowdeep-1.2.1 → opticallyshallowdeep-1.2.3}/LICENSE +0 -0
  19. {opticallyshallowdeep-1.2.1 → opticallyshallowdeep-1.2.3}/MANIFEST.in +0 -0
  20. {opticallyshallowdeep-1.2.1 → opticallyshallowdeep-1.2.3}/opticallyshallowdeep/models/SR.h5 +0 -0
  21. {opticallyshallowdeep-1.2.1 → opticallyshallowdeep-1.2.3}/opticallyshallowdeep/models/TOA.h5 +0 -0
  22. {opticallyshallowdeep-1.2.1 → opticallyshallowdeep-1.2.3}/opticallyshallowdeep.egg-info/SOURCES.txt +0 -0
  23. {opticallyshallowdeep-1.2.1 → opticallyshallowdeep-1.2.3}/opticallyshallowdeep.egg-info/dependency_links.txt +0 -0
  24. {opticallyshallowdeep-1.2.1 → opticallyshallowdeep-1.2.3}/opticallyshallowdeep.egg-info/top_level.txt +0 -0
  25. {opticallyshallowdeep-1.2.1 → opticallyshallowdeep-1.2.3}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: opticallyshallowdeep
3
- Version: 1.2.1
3
+ Version: 1.2.3
4
4
  Summary: Identify optically shallow and deep waters in satellite imagery
5
5
  Author: Yulun Wu
6
6
  Author-email: yulunwu8@gmail.com
@@ -9,8 +9,8 @@ Requires-Python: >=3.8
9
9
  Description-Content-Type: text/markdown
10
10
  License-File: LICENSE
11
11
  Requires-Dist: geopandas
12
- Requires-Dist: rasterio
13
- Requires-Dist: tifffile
12
+ Requires-Dist: rasterio==1.3.9
13
+ Requires-Dist: tifffile==2023.8.12
14
14
  Requires-Dist: netCDF4
15
15
  Requires-Dist: pyproj
16
16
  Requires-Dist: joblib
@@ -18,6 +18,15 @@ Requires-Dist: scipy
18
18
  Requires-Dist: matplotlib
19
19
  Requires-Dist: imagecodecs
20
20
  Requires-Dist: tensorflow
21
+ Dynamic: author
22
+ Dynamic: author-email
23
+ Dynamic: classifier
24
+ Dynamic: description
25
+ Dynamic: description-content-type
26
+ Dynamic: license-file
27
+ Dynamic: requires-dist
28
+ Dynamic: requires-python
29
+ Dynamic: summary
21
30
 
22
31
  # Optically-Shallow-Deep
23
32
 
@@ -25,10 +34,13 @@ This python tool delineates optically shallow and deep waters in Sentinel-2 imag
25
34
 
26
35
  Supported input includes Level-1C (L1C) SAFE files and ACOLITE-processed L2R netCDF files. The output geotiff contains probabilities of water pixels being optically shallow and deep.
27
36
 
28
- Originally coded by by Galen Richardson and Anders Knudby, modified and packaged by Yulun Wu
37
+ **Home page:** <a href="https://github.com/yulunwu8/Optically-Shallow-Deep" target="_blank">https://github.com/yulunwu8/Optically-Shallow-Deep</a>
29
38
 
30
- Home page: <a href="https://github.com/yulunwu8/Optically-Shallow-Deep" target="_blank">https://github.com/yulunwu8/Optically-Shallow-Deep</a>
39
+ **Publication:** Richardson, G., Foreman, N., Knudby, A., Wu, Y., & Lin, Y. (2024). Global deep learning model for delineation of optically shallow and optically deep water in Sentinel-2 imagery. *Remote Sensing of Environment*, 311, 114302. <a href="https://doi.org/10.1016/j.rse.2024.114302" target="_blank">https://doi.org/10.1016/j.rse.2024.114302</a>
31
40
 
41
+ Originally coded by G. Richardson and A. Knudby, modified and packaged by Y. Wu
42
+
43
+ Models trained by G. Richardson and N. Foreman
32
44
 
33
45
 
34
46
  ## Installation
@@ -50,14 +62,14 @@ python -m pip install tensorflow-macos
50
62
  ```
51
63
 
52
64
 
53
- For windows:
65
+ For Windows and Linux:
54
66
 
55
67
  ```bash
56
68
  pip3 install tensorflow==2.13.0
57
69
  ```
58
70
 
59
71
 
60
- For Linux and more on installing tensorflow: [https://www.tensorflow.org/install](https://www.tensorflow.org/install)
72
+ More on installing tensorflow: [https://www.tensorflow.org/install](https://www.tensorflow.org/install)
61
73
 
62
74
 
63
75
  **3 - Install opticallyshallowdeep:**
@@ -103,7 +115,7 @@ osd.run(file_L1C, folder_out, file_L2R=file_L2R)
103
115
  The L1C file is always required as it contains a built-in cloud mask. Pixels within 8 pixels of the cloud mask are masked to reduce the impact of clouds.
104
116
 
105
117
 
106
- Output is a 1-band geotiff, with values of prediction probability of optically shallow water (OSW): 100 means most likely OSW, 0 means most likely optically deep water (ODW). Non-water pixels are masked. It is recommended to treat pixels between 0 and 40 as ODW, and pixels between 60 and 100 as OSW (publication in review).
118
+ Output is a 1-band geotiff, with values of prediction probability of optically shallow water (OSW): 100 means most likely OSW, 0 means most likely optically deep water (ODW). Non-water pixels are masked.
107
119
 
108
120
  A log file, an intermediate multi-band geotiff, and a preview PNG are also generated in the output folder. They can be deleted after the processing.
109
121
 
@@ -114,6 +126,14 @@ A log file, an intermediate multi-band geotiff, and a preview PNG are also gener
114
126
 
115
127
  <img src="images/OSW.jpeg" height="500">
116
128
 
129
+
130
+ ## Tips
131
+
132
+ It is recommended to treat pixels with values between 0 and 40 as ODW, and those between 60 and 100 as OSW (Richardson et al., 2024).
133
+
134
+ Users have reported that averaging results from multiple images acquired on different days can help reduce noise and improve the overall accuracy of classification results.
135
+
136
+
117
137
  ## Training, test, and validation data
118
138
 
119
139
  All annotated shapefiles used in training, testing, and validating the DNN model are in the annotated_shapefiles folder, grouped by Sentinel-2 Scene ID.
@@ -1,34 +1,16 @@
1
- Metadata-Version: 2.1
2
- Name: opticallyshallowdeep
3
- Version: 1.2.1
4
- Summary: Identify optically shallow and deep waters in satellite imagery
5
- Author: Yulun Wu
6
- Author-email: yulunwu8@gmail.com
7
- Classifier: Programming Language :: Python :: 3
8
- Requires-Python: >=3.8
9
- Description-Content-Type: text/markdown
10
- License-File: LICENSE
11
- Requires-Dist: geopandas
12
- Requires-Dist: rasterio
13
- Requires-Dist: tifffile
14
- Requires-Dist: netCDF4
15
- Requires-Dist: pyproj
16
- Requires-Dist: joblib
17
- Requires-Dist: scipy
18
- Requires-Dist: matplotlib
19
- Requires-Dist: imagecodecs
20
- Requires-Dist: tensorflow
21
-
22
1
  # Optically-Shallow-Deep
23
2
 
24
3
  This python tool delineates optically shallow and deep waters in Sentinel-2 imagery. The tool uses a deep neural network (DNN) that was trained on a diverse set of global images.
25
4
 
26
5
  Supported input includes Level-1C (L1C) SAFE files and ACOLITE-processed L2R netCDF files. The output geotiff contains probabilities of water pixels being optically shallow and deep.
27
6
 
28
- Originally coded by by Galen Richardson and Anders Knudby, modified and packaged by Yulun Wu
7
+ **Home page:** <a href="https://github.com/yulunwu8/Optically-Shallow-Deep" target="_blank">https://github.com/yulunwu8/Optically-Shallow-Deep</a>
8
+
9
+ **Publication:** Richardson, G., Foreman, N., Knudby, A., Wu, Y., & Lin, Y. (2024). Global deep learning model for delineation of optically shallow and optically deep water in Sentinel-2 imagery. *Remote Sensing of Environment*, 311, 114302. <a href="https://doi.org/10.1016/j.rse.2024.114302" target="_blank">https://doi.org/10.1016/j.rse.2024.114302</a>
29
10
 
30
- Home page: <a href="https://github.com/yulunwu8/Optically-Shallow-Deep" target="_blank">https://github.com/yulunwu8/Optically-Shallow-Deep</a>
11
+ Originally coded by G. Richardson and A. Knudby, modified and packaged by Y. Wu
31
12
 
13
+ Models trained by G. Richardson and N. Foreman
32
14
 
33
15
 
34
16
  ## Installation
@@ -50,14 +32,14 @@ python -m pip install tensorflow-macos
50
32
  ```
51
33
 
52
34
 
53
- For windows:
35
+ For Windows and Linux:
54
36
 
55
37
  ```bash
56
38
  pip3 install tensorflow==2.13.0
57
39
  ```
58
40
 
59
41
 
60
- For Linux and more on installing tensorflow: [https://www.tensorflow.org/install](https://www.tensorflow.org/install)
42
+ More on installing tensorflow: [https://www.tensorflow.org/install](https://www.tensorflow.org/install)
61
43
 
62
44
 
63
45
  **3 - Install opticallyshallowdeep:**
@@ -103,7 +85,7 @@ osd.run(file_L1C, folder_out, file_L2R=file_L2R)
103
85
  The L1C file is always required as it contains a built-in cloud mask. Pixels within 8 pixels of the cloud mask are masked to reduce the impact of clouds.
104
86
 
105
87
 
106
- Output is a 1-band geotiff, with values of prediction probability of optically shallow water (OSW): 100 means most likely OSW, 0 means most likely optically deep water (ODW). Non-water pixels are masked. It is recommended to treat pixels between 0 and 40 as ODW, and pixels between 60 and 100 as OSW (publication in review).
88
+ Output is a 1-band geotiff, with values of prediction probability of optically shallow water (OSW): 100 means most likely OSW, 0 means most likely optically deep water (ODW). Non-water pixels are masked.
107
89
 
108
90
  A log file, an intermediate multi-band geotiff, and a preview PNG are also generated in the output folder. They can be deleted after the processing.
109
91
 
@@ -114,6 +96,14 @@ A log file, an intermediate multi-band geotiff, and a preview PNG are also gener
114
96
 
115
97
  <img src="images/OSW.jpeg" height="500">
116
98
 
99
+
100
+ ## Tips
101
+
102
+ It is recommended to treat pixels with values between 0 and 40 as ODW, and those between 60 and 100 as OSW (Richardson et al., 2024).
103
+
104
+ Users have reported that averaging results from multiple images acquired on different days can help reduce noise and improve the overall accuracy of classification results.
105
+
106
+
117
107
  ## Training, test, and validation data
118
108
 
119
109
  All annotated shapefiles used in training, testing, and validating the DNN model are in the annotated_shapefiles folder, grouped by Sentinel-2 Scene ID.
@@ -0,0 +1 @@
1
+ from .run import *
@@ -1,10 +1,7 @@
1
-
2
1
  # Always output row, column, band
3
-
4
2
  def check_transpose(img):
5
3
  #if the #of bands is greater than the number of x or y cords
6
4
  y,x,b=img.shape
7
5
  if b>y or b>x:
8
6
  img=img.transpose(1,2,0)
9
- return img
10
-
7
+ return img
@@ -1,7 +1,3 @@
1
-
2
-
3
-
4
-
5
1
  import os, sys
6
2
  import rasterio
7
3
  import numpy as np
@@ -99,5 +95,4 @@ def cloud_mask(file_L1C, buffer_size = 8):
99
95
  mask_cloud_buffered = ndimage.binary_dilation(mask_cloud, structure=struct1,iterations=buffer_size).astype(mask_cloud.dtype)
100
96
 
101
97
  print('Done')
102
- return mask_cloud_buffered
103
-
98
+ return mask_cloud_buffered
@@ -1,5 +1,3 @@
1
-
2
-
3
1
  def find_epsg(data):
4
2
 
5
3
  # Use regex to extract the desired part
@@ -29,25 +27,8 @@ def find_epsg(data):
29
27
  # return f"The EPSG code for '{crs_name}' is {epsg_code}."
30
28
  return epsg_code
31
29
 
32
-
33
30
  else:
34
31
  print( "EPSG code could not be found.")
35
32
 
36
-
37
33
  except Exception as e:
38
34
  return f"An error occurred: {str(e)}"
39
-
40
-
41
-
42
-
43
-
44
-
45
-
46
-
47
-
48
-
49
-
50
-
51
-
52
-
53
-
@@ -10,7 +10,7 @@ def make_multiband_image(file_in,folder_out):
10
10
  basename = os.path.basename(file_in).rstrip(".SAFE")
11
11
 
12
12
  # output path
13
- imageFile = os.path.join(folder_out,basename) + '.tif'
13
+ imageFile = os.path.join(folder_out, f"{basename}.tif")
14
14
 
15
15
  if os.path.exists(imageFile):
16
16
  print('Multi-band geotiff exists: ' + str(imageFile))
@@ -54,5 +54,3 @@ def make_multiband_image(file_in,folder_out):
54
54
  print('Done')
55
55
 
56
56
  return imageFile
57
-
58
-
@@ -1,8 +1,4 @@
1
-
2
-
3
1
  import numpy as np
4
-
5
-
6
2
  def make_vertical_strips(full_img):
7
3
  '''use to save ram, process bigger images faster, and it overlaps so middle image is not
8
4
  distorted from how edge pixels are handled'''
@@ -30,5 +26,4 @@ def make_vertical_strips(full_img):
30
26
  import sys
31
27
  sys.exit('Unknown dimension(s) of input imagery to be splited into strips')
32
28
 
33
- return [strip1,strip2,strip3,strip4,strip5]
34
-
29
+ return [strip1,strip2,strip3,strip4,strip5]
@@ -1,4 +1,3 @@
1
-
2
1
  import os
3
2
  import numpy as np
4
3
  import rasterio
@@ -7,9 +6,7 @@ from rasterio.crs import CRS
7
6
  from rasterio.transform import from_origin
8
7
  import netCDF4 as nc4
9
8
  # from pyproj import Proj, transform
10
-
11
9
  import pyproj
12
-
13
10
  from .find_epsg import find_epsg
14
11
 
15
12
  def netcdf_to_multiband_geotiff(netcdf_file, folder_out):
@@ -87,5 +84,4 @@ def netcdf_to_multiband_geotiff(netcdf_file, folder_out):
87
84
 
88
85
  print('Done')
89
86
 
90
- return output_geotiff_file
91
-
87
+ return output_geotiff_file
@@ -1,6 +1,4 @@
1
-
2
1
  import re
3
-
4
2
  def parse_string(s):
5
3
  if s.lower() in ["lat", "long", "lat_abs"]:
6
4
  return [s.lower()]#parses the column names for our model and makes into things that our scripts can interpret
@@ -19,4 +17,4 @@ def parse_string(s):
19
17
  first_group_int = first_group
20
18
  return [first_group_int, int(groups[2]), groups[4]] if groups[4] else [first_group_int, int(groups[2]), None]
21
19
  else:
22
- return None
20
+ return None
@@ -1,4 +1,3 @@
1
-
2
1
  import os, gc, warnings, math
3
2
  import numpy as np
4
3
  import pandas as pd
@@ -20,7 +19,6 @@ tf.compat.v1.logging.set_verbosity(tf.compat.v1.logging.ERROR)
20
19
 
21
20
  from .make_vertical_strips import make_vertical_strips
22
21
 
23
-
24
22
  def process_as_strips (full_img, image_path, if_SR, model_path, selected_columns, model_columns, file_in, cloud_list):
25
23
  striplist=make_vertical_strips(full_img) #create a list of strips with overlap
26
24
  RGBlist=[]
@@ -57,9 +55,7 @@ def process_img_to_rgb(img, file_path, if_SR, model_path, selected_columns, mode
57
55
  gc.collect()
58
56
  return RGB_img #this image is 0: OSW/ODW, 1:pred/prob, 2: Mask
59
57
 
60
-
61
58
  def correct_baseline(img,file_path, if_SR, file_in):
62
-
63
59
  from xml.dom import minidom
64
60
 
65
61
  # if ACOLITE input
@@ -160,7 +156,6 @@ def get_water_pix_coord(img,correction, if_SR, img_cloud):
160
156
  gc.collect()
161
157
  return common_coordinates_list
162
158
 
163
-
164
159
  def make_blank_img(img):
165
160
  Y_b, X_b, b = img.shape #sometimes the image is all no data or the correction value, in this instance, we make a blank image
166
161
  RGB_img = np.zeros((Y_b, X_b, 3), dtype=np.uint8)
@@ -171,7 +166,6 @@ def make_blank_img(img):
171
166
  def time_tracker(start_time):
172
167
  return "{}sec".format(round((datetime.now() - start_time).total_seconds(), 2))
173
168
 
174
-
175
169
  def process_image_with_filters(img, selected_columns):
176
170
  height, width, bands = img.shape#the output of this is an image of the filters required for this model
177
171
  filter_list = [value for value in selected_columns if value not in [["lat"], ["long"], ["lat_abs"]]]
@@ -353,7 +347,6 @@ def load_model_and_predict_pixels(value_list, model_path, cord_list, if_SR):
353
347
 
354
348
  return cord_list.tolist(), pred_results.tolist(), con_1.tolist()
355
349
 
356
-
357
350
  def load_tf_model(model_path, if_SR):
358
351
  if if_SR == False:
359
352
  model=d6_model(32,0.01)
@@ -422,16 +415,4 @@ def plot_RGB_img(RGB_img, image_path):
422
415
  # plt.show()
423
416
 
424
417
  out_path = image_path.replace('.tif','.png')
425
- plt.savefig(out_path)
426
-
427
-
428
-
429
-
430
-
431
-
432
-
433
-
434
-
435
-
436
-
437
-
418
+ plt.savefig(out_path)
@@ -1,4 +1,3 @@
1
-
2
1
  import sys, os, gc, time
3
2
  import tifffile as tif
4
3
  from importlib.metadata import version
@@ -14,9 +13,6 @@ from .netcdf_to_multiband_geotiff import netcdf_to_multiband_geotiff
14
13
  from .make_vertical_strips import make_vertical_strips
15
14
  from .cloud_mask import cloud_mask
16
15
 
17
-
18
-
19
-
20
16
  def run(file_L1C, folder_out, file_L2R = None, to_log=True):
21
17
 
22
18
  ### Check the two
@@ -74,7 +70,7 @@ def run(file_L1C, folder_out, file_L2R = None, to_log=True):
74
70
  if file_L2R is None:
75
71
 
76
72
  if_SR = False
77
- model = 'models/TOA.h5'
73
+ model = os.path.join('models', 'TOA.h5')
78
74
  model_columns = GTOA_model_columns
79
75
  file_in = file_L1C
80
76
 
@@ -88,7 +84,7 @@ def run(file_L1C, folder_out, file_L2R = None, to_log=True):
88
84
  sys.exit('file_L2R does not exist: ' + str(file_L2R))
89
85
 
90
86
  if_SR = True
91
- model = 'models/SR.h5'
87
+ model = os.path.join('models', 'SR.h5')
92
88
  model_columns = GACOLITE_model_columns
93
89
  file_in = file_L2R
94
90
 
@@ -1,4 +1,3 @@
1
-
2
1
  import rasterio, gc
3
2
  import numpy as np
4
3
 
@@ -23,5 +22,4 @@ def write_georef_image(image_path,RGB_img):
23
22
  dst.write(output_band, 1)
24
23
 
25
24
  del raster_with_ref
26
- gc.collect()
27
-
25
+ gc.collect()
@@ -1,13 +1,46 @@
1
+ Metadata-Version: 2.4
2
+ Name: opticallyshallowdeep
3
+ Version: 1.2.3
4
+ Summary: Identify optically shallow and deep waters in satellite imagery
5
+ Author: Yulun Wu
6
+ Author-email: yulunwu8@gmail.com
7
+ Classifier: Programming Language :: Python :: 3
8
+ Requires-Python: >=3.8
9
+ Description-Content-Type: text/markdown
10
+ License-File: LICENSE
11
+ Requires-Dist: geopandas
12
+ Requires-Dist: rasterio==1.3.9
13
+ Requires-Dist: tifffile==2023.8.12
14
+ Requires-Dist: netCDF4
15
+ Requires-Dist: pyproj
16
+ Requires-Dist: joblib
17
+ Requires-Dist: scipy
18
+ Requires-Dist: matplotlib
19
+ Requires-Dist: imagecodecs
20
+ Requires-Dist: tensorflow
21
+ Dynamic: author
22
+ Dynamic: author-email
23
+ Dynamic: classifier
24
+ Dynamic: description
25
+ Dynamic: description-content-type
26
+ Dynamic: license-file
27
+ Dynamic: requires-dist
28
+ Dynamic: requires-python
29
+ Dynamic: summary
30
+
1
31
  # Optically-Shallow-Deep
2
32
 
3
33
  This python tool delineates optically shallow and deep waters in Sentinel-2 imagery. The tool uses a deep neural network (DNN) that was trained on a diverse set of global images.
4
34
 
5
35
  Supported input includes Level-1C (L1C) SAFE files and ACOLITE-processed L2R netCDF files. The output geotiff contains probabilities of water pixels being optically shallow and deep.
6
36
 
7
- Originally coded by by Galen Richardson and Anders Knudby, modified and packaged by Yulun Wu
37
+ **Home page:** <a href="https://github.com/yulunwu8/Optically-Shallow-Deep" target="_blank">https://github.com/yulunwu8/Optically-Shallow-Deep</a>
38
+
39
+ **Publication:** Richardson, G., Foreman, N., Knudby, A., Wu, Y., & Lin, Y. (2024). Global deep learning model for delineation of optically shallow and optically deep water in Sentinel-2 imagery. *Remote Sensing of Environment*, 311, 114302. <a href="https://doi.org/10.1016/j.rse.2024.114302" target="_blank">https://doi.org/10.1016/j.rse.2024.114302</a>
8
40
 
9
- Home page: <a href="https://github.com/yulunwu8/Optically-Shallow-Deep" target="_blank">https://github.com/yulunwu8/Optically-Shallow-Deep</a>
41
+ Originally coded by G. Richardson and A. Knudby, modified and packaged by Y. Wu
10
42
 
43
+ Models trained by G. Richardson and N. Foreman
11
44
 
12
45
 
13
46
  ## Installation
@@ -29,14 +62,14 @@ python -m pip install tensorflow-macos
29
62
  ```
30
63
 
31
64
 
32
- For windows:
65
+ For Windows and Linux:
33
66
 
34
67
  ```bash
35
68
  pip3 install tensorflow==2.13.0
36
69
  ```
37
70
 
38
71
 
39
- For Linux and more on installing tensorflow: [https://www.tensorflow.org/install](https://www.tensorflow.org/install)
72
+ More on installing tensorflow: [https://www.tensorflow.org/install](https://www.tensorflow.org/install)
40
73
 
41
74
 
42
75
  **3 - Install opticallyshallowdeep:**
@@ -82,7 +115,7 @@ osd.run(file_L1C, folder_out, file_L2R=file_L2R)
82
115
  The L1C file is always required as it contains a built-in cloud mask. Pixels within 8 pixels of the cloud mask are masked to reduce the impact of clouds.
83
116
 
84
117
 
85
- Output is a 1-band geotiff, with values of prediction probability of optically shallow water (OSW): 100 means most likely OSW, 0 means most likely optically deep water (ODW). Non-water pixels are masked. It is recommended to treat pixels between 0 and 40 as ODW, and pixels between 60 and 100 as OSW (publication in review).
118
+ Output is a 1-band geotiff, with values of prediction probability of optically shallow water (OSW): 100 means most likely OSW, 0 means most likely optically deep water (ODW). Non-water pixels are masked.
86
119
 
87
120
  A log file, an intermediate multi-band geotiff, and a preview PNG are also generated in the output folder. They can be deleted after the processing.
88
121
 
@@ -93,6 +126,14 @@ A log file, an intermediate multi-band geotiff, and a preview PNG are also gener
93
126
 
94
127
  <img src="images/OSW.jpeg" height="500">
95
128
 
129
+
130
+ ## Tips
131
+
132
+ It is recommended to treat pixels with values between 0 and 40 as ODW, and those between 60 and 100 as OSW (Richardson et al., 2024).
133
+
134
+ Users have reported that averaging results from multiple images acquired on different days can help reduce noise and improve the overall accuracy of classification results.
135
+
136
+
96
137
  ## Training, test, and validation data
97
138
 
98
139
  All annotated shapefiles used in training, testing, and validating the DNN model are in the annotated_shapefiles folder, grouped by Sentinel-2 Scene ID.
@@ -1,6 +1,6 @@
1
1
  geopandas
2
- rasterio
3
- tifffile
2
+ rasterio==1.3.9
3
+ tifffile==2023.8.12
4
4
  netCDF4
5
5
  pyproj
6
6
  joblib
@@ -5,7 +5,7 @@ with open("readme.md", "r") as fh:
5
5
 
6
6
  setup(
7
7
  name='opticallyshallowdeep',
8
- version='1.2.1',
8
+ version='1.2.3',
9
9
  author='Yulun Wu',
10
10
  author_email='yulunwu8@gmail.com',
11
11
  description='Identify optically shallow and deep waters in satellite imagery',
@@ -18,7 +18,7 @@ setup(
18
18
  'Programming Language :: Python :: 3'
19
19
  ],
20
20
  python_requires='>=3.8',
21
- install_requires=['geopandas','rasterio','tifffile','netCDF4','pyproj',
21
+ install_requires=['geopandas','rasterio==1.3.9','tifffile==2023.8.12','netCDF4','pyproj',
22
22
  'joblib','scipy','matplotlib','imagecodecs','tensorflow']
23
23
  )
24
24
 
@@ -1,2 +0,0 @@
1
- from .run import *
2
-