-
Notifications
You must be signed in to change notification settings - Fork 1
/
image_reader.py
153 lines (120 loc) · 4.76 KB
/
image_reader.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
import os
import logging
import numpy as np
import skimage
from osgeo import gdal
from skimage import transform
from abc import ABC, abstractmethod
from configuration import Config
from tools.path_operations import get_path_image
class ImageReader(ABC):
""" Abstract class ImageReader. All compatible image readers must inherit from
this class and implement the abstract methods.
Abstract Methods
----------------
read_band(self, path_band)
read_image(self, path, image_idx)
"""
def __init__(self):
""" Initialize an abstract ImageReader.
"""
super().__init__()
logging.debug("Creating instance of Image Reader object...")
@abstractmethod
def read_band(self, path_band: str):
""" Abstract method to read the band of an image by knowing its path.
Parameters
----------
path_band : str
path of the band to be read
Returns
-------
None (Abstract method)
"""
@abstractmethod
def read_image(self, path: str, image_idx: int):
""" Abstract method to read the bands of the image with index *image_idx*.
Parameters
----------
path : str
path that includes the folders with the available bands
image_idx : int
index linked to the image to be read, if sorting by file_name in ascending order, and only
considering the images of type and file extension specified in the configuration file.
Returns
-------
None (Abstract method)
"""
class ReadSentinel2(ImageReader):
""" Reads Sentinel2 images. The bands to be read must be specified in the configuration
file.
Class Attributes
----------
dim_x : int
horizontal dimension of images to be read
dim_y : int
vertical dimension of images to be read
"""
def __init__(self, dim_x: int, dim_y: int):
""" Initializes instance of ReadSentinel2 object with the corresponding
class attributes.
"""
super().__init__()
self.dim_x = dim_x
self.dim_y = dim_y
def read_band(self, path_band: str):
""" Reads and returns the band with path *path_band*. Each image is linked to
one date, and for each date there are multiple available bands.
Parameters
----------
path_band : str
path of the band to be read
Returns
-------
band : np.ndarray
read band
"""
band = gdal.Open(path_band).ReadAsArray()
#print(f'Mean Value Band {np.mean(band)}')
# Check if the image dimensions are the proper ones
if band.shape != (self.dim_x, self.dim_y):
band = transform.resize(band, (self.dim_x, self.dim_y), anti_aliasing=True, preserve_range=True)
#print('issue')
return band
def read_image(self, path: str, image_idx: int):
""" Reads and returns all the bands for the image with index *image_idx*.
Parameters
----------
path : str
path including the folders with the available bands
image_idx : int
index linked to the image to be read, if sorting by file_name in ascending order, and only
considering the images of type and file extension specified in the configuration file.
Returns
-------
image : np.ndarray
all the read bands for the image with index *image_idx*
"""
# TODO: add date_string variable to descriptions
# Empty list
image_all_bands = []
# Loop through bands
# Each band sub-folder must contain the image linked to image_idx
# taken at the corresponding frequency band.
for band_id in Config.bands_to_read:
# Get path of image to be read in this iteration, which depends on the image index
path_band_folder = os.path.join(path, f'Sentinel2_B{band_id}')
path_image_band, date_string = get_path_image(path_folder=path_band_folder,
image_type=Config.image_types[Config.scenario],
file_extension='.tif', image_index=image_idx, band_id=band_id)
# Read the corresponding band
image_band = self.read_band(path_band=path_image_band)
#print(path_image_band)
#print(np.mean(image_band))
# Add the read band to the *image_all_bands* array
image_all_bands.extend([image_band.flatten()])
# Transpose for proper dimensions
image_all_bands = np.transpose(image_all_bands)
# Scale images
image_all_bands = image_all_bands * Config.scaling_factor_sentinel
return image_all_bands, date_string