-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSRC_Updated_FCC.py
206 lines (162 loc) · 8.38 KB
/
SRC_Updated_FCC.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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
import rasterio
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.backend_bases import MouseEvent
from matplotlib.widgets import Button # Import Button from matplotlib.widgets
# Path to the EnMAP L2A data (adjust the path accordingly)
reflectance_file = r"D:\ENMAP\Python_Codes\ENMAP01-____L2A-DT0000001045_20220611T054731Z_001_V010402_20240914T033148Z\ENMAP01-____L2A-DT0000001045_20220611T054731Z_001_V010402_20240914T033148Z-SPECTRAL_IMAGE.TIF"
# Open the reflectance data
with rasterio.open(reflectance_file) as src:
reflectance = src.read() # Read all bands as a 3D array (Bands, Rows, Columns)
profile = src.profile # Metadata (e.g., dimensions, CRS)
bands_count = reflectance.shape[0] # Number of bands
# Scale reflectance if needed (check metadata for scaling factor)
reflectance = reflectance / 10000.0 # Adjust this if scaling is different (reflectance is usually scaled down)
# Convert reflectance to percentage
reflectance_percent = reflectance * 100 # Now the reflectance is in percentage
# Clip negative reflectance values (which should not occur)
reflectance_percent = np.clip(reflectance_percent, 0, None) # Set negative values to 0
# Set up the figure for the spectral reflectance plot
fig, (ax_image, ax_curve) = plt.subplots(1, 2, figsize=(15, 7))
# SWIR bands (Adjust the band indices based on your dataset)
swir_red_band = 100 # Example: 1500 nm (SWIR Red)
swir_green_band = 120 # Example: 1900 nm (SWIR Green)
swir_blue_band = 140 # Example: 2200 nm (SWIR Blue)
# Get FCC image (False Color Composite)
fcc_image = np.dstack((reflectance[swir_red_band, :, :],
reflectance[swir_green_band, :, :],
reflectance[swir_blue_band, :, :]))
# Normalize FCC image to [0, 1] range for imshow
fcc_image_norm = np.clip(fcc_image, 0, 1) # Ensure values are within the [0, 1] range
# Plot the initial FCC image
cax = ax_image.imshow(fcc_image_norm)
fig.colorbar(cax, ax=ax_image)
ax_image.set_title(f"FCC Image (Bands {swir_red_band + 1}, {swir_green_band + 1}, {swir_blue_band + 1})")
ax_image.axis('on')
# Plotting initial spectral reflectance for a default pixel (e.g., pixel (500, 650))
pixel_x, pixel_y = 500, 650
spectral_profile = reflectance_percent[:, pixel_y, pixel_x]
# Initial plot (default band 1)
line, = ax_curve.plot(spectral_profile, label=f"Pixel ({pixel_x}, {pixel_y})")
ax_curve.set_xlabel("Wavelength (nm)")
ax_curve.set_ylabel("Reflectance (%)")
ax_curve.set_title("Spectral Reflectance Curve")
ax_curve.grid()
ax_curve.legend(loc="upper left", bbox_to_anchor=(1.1, 1.0), borderaxespad=0.1) # Adjusted legend position
# Store the lines in a list to manage clearing operations
curves = [line]
# Function to update spectral reflectance curve for a selected pixel
def on_click(event: MouseEvent):
# Get pixel coordinates from the click event
x, y = int(event.xdata), int(event.ydata)
if x is not None and y is not None:
# Extract spectral profile for the selected pixel
spectral_profile = reflectance_percent[:, y, x]
# Plot the spectral reflectance for the new selected pixel (append the curve)
line, = ax_curve.plot(spectral_profile, label=f"Pixel ({x}, {y})")
curves.append(line) # Store the line object to manage later
# Set axis labels and title again (since the plot will be appended with new curves)
ax_curve.set_xlabel("Wavelength (nm)")
ax_curve.set_ylabel("Reflectance (%)")
ax_curve.set_title("Spectral Reflectance Curve")
ax_curve.grid()
# Update the legend and redraw the plot
update_legend()
# Redraw the image and the curve plot
plt.draw()
# Function to update the legend dynamically based on the plotted curves
def update_legend():
# Update the legend with the current curves
ax_curve.legend(loc="best", bbox_to_anchor=(1.1, 1.0), borderaxespad=0.1) # Adjusted legend position dynamically
# Function to clear all the spectral reflectance curves
def clear_all_plots(event):
# Clear all curves from the plot
ax_curve.cla() # Clear the axis
ax_curve.set_xlabel("Wavelength (nm)")
ax_curve.set_ylabel("Reflectance (%)")
ax_curve.set_title("Spectral Reflectance Curve")
ax_curve.grid()
ax_curve.legend(loc="best", bbox_to_anchor=(1.05, 0.5), borderaxespad=0.1) # Adjusted legend position dynamically
# Clear the curves list
curves.clear()
# Redraw the image
plt.draw()
# Function to clear the most recent plot
def clear_previous_plot(event):
if curves: # Check if there are curves to remove
curves[-1].remove()# Remove the last plotted curve
curves.pop() # Remove the curve from the list
# Update the legend dynamically
update_legend()
# Redraw the plot after removing the curve
plt.draw()
# Function to reset zoom to full extent
def reset_zoom(event):
# Reset the image to its full extent (original zoom level)
ax_image.set_xlim(0, reflectance.shape[2]) # Full width
ax_image.set_ylim(reflectance.shape[1], 0) # Full height (reverse y-axis)
# Redraw the image
plt.draw()
# Pan and zoom functionality class
class PanZoom:
def __init__(self, ax):
self.ax = ax
self.is_dragging = False
self.prev_x = 0
self.prev_y = 0
# Connect the mouse event listeners
self.ax.figure.canvas.mpl_connect('button_press_event', self.on_press)
self.ax.figure.canvas.mpl_connect('motion_notify_event', self.on_motion)
self.ax.figure.canvas.mpl_connect('button_release_event', self.on_release)
self.ax.figure.canvas.mpl_connect('scroll_event', self.on_scroll)
def on_press(self, event):
"""Start panning on mouse press"""
if event.button == 1:
self.is_dragging = True
self.prev_x, self.prev_y = event.x, event.y
def on_motion(self, event):
"""Pan the image on mouse drag"""
if self.is_dragging:
dx = event.x - self.prev_x
dy = event.y - self.prev_y
self.ax.set_xlim(self.ax.get_xlim()[0] - dx, self.ax.get_xlim()[1] - dx)
self.ax.set_ylim(self.ax.get_ylim()[0] + dy, self.ax.get_ylim()[1] + dy)
self.prev_x, self.prev_y = event.x, event.y
plt.draw()
def on_release(self, event):
"""Stop panning on mouse release"""
if event.button == 1:
self.is_dragging = False
def on_scroll(self, event):
"""Zoom in or out with mouse scroll"""
# Get current image limits
xlim, ylim = self.ax.get_xlim(), self.ax.get_ylim()
# Zoom direction (up or down)
zoom_factor = 1.1 if event.button == 'up' else 0.9
# Update the image limits
new_xlim = (xlim[0] * zoom_factor, xlim[1] * zoom_factor)
new_ylim = (ylim[0] * zoom_factor, ylim[1] * zoom_factor)
# Update limits only if they remain within the image bounds
self.ax.set_xlim(new_xlim)
self.ax.set_ylim(new_ylim)
# Redraw the image
plt.draw()
# Set up pan and zoom functionality
panzoom = PanZoom(ax_image)
# Set the click event handler for selecting a pixel
fig.canvas.mpl_connect('button_press_event', on_click)
# Add the Reset Zoom button below the image plot
ax_button_reset = plt.axes([0.05, 0.05, 0.1, 0.075]) # Adjust button position below the image plot
button_reset = Button(ax_button_reset, 'Reset Zoom')
button_reset.on_clicked(reset_zoom) # Link button to the reset zoom function
# Add the Clear Previous Plot button inside the spectral reflectance plot
ax_button_clear_previous = plt.axes([0.87, 0.15, 0.1, 0.075]) # Adjust button position inside the spectral reflectance plot
button_clear_previous = Button(ax_button_clear_previous, 'Clear Previous')
button_clear_previous.on_clicked(clear_previous_plot) # Link button to the clear previous function
# Add the Clear All Plots button inside the spectral reflectance plot
ax_button_clear_all = plt.axes([0.87, 0.25, 0.1, 0.075]) # Adjust button position inside the spectral reflectance plot
button_clear_all = Button(ax_button_clear_all, 'Clear All')
button_clear_all.on_clicked(clear_all_plots) # Link button to the clear all function
# Show the plot
plt.tight_layout()
plt.show()