prateeksharmacoder commited on
Commit
2376099
·
1 Parent(s): 2e80d4c

Fix color balance logic for Sentinel-2 TIFFs by using global instead of per-channel percentile stretching

Browse files
Files changed (1) hide show
  1. inference/geotiff.py +10 -46
inference/geotiff.py CHANGED
@@ -88,55 +88,19 @@ def normalize_rgb(
88
  ):
89
  """
90
  Convert Sentinel-2 reflectance/DN values to uint8 RGB.
91
-
92
- Percentile normalization is performed independently
93
- for each channel.
94
  """
95
-
96
  rgb = rgb.astype(np.float32)
 
 
 
 
97
 
98
- result = np.zeros_like(
99
- rgb,
100
- dtype=np.uint8
101
- )
102
-
103
- for channel in range(3):
104
-
105
- band = rgb[:, :, channel]
106
-
107
- low = np.percentile(
108
- band,
109
- lower_percentile
110
- )
111
-
112
- high = np.percentile(
113
- band,
114
- upper_percentile
115
- )
116
-
117
- if high <= low:
118
- result[:, :, channel] = np.clip(
119
- band,
120
- 0,
121
- 255
122
- ).astype(np.uint8)
123
-
124
- else:
125
-
126
- normalized = (
127
- (band - low) /
128
- (high - low)
129
- )
130
-
131
- normalized = np.clip(
132
- normalized,
133
- 0,
134
- 1
135
- )
136
-
137
- result[:, :, channel] = (
138
- normalized * 255
139
- ).astype(np.uint8)
140
 
141
  return result
142
 
 
88
  ):
89
  """
90
  Convert Sentinel-2 reflectance/DN values to uint8 RGB.
91
+ Global percentile normalization preserves color balance.
 
 
92
  """
 
93
  rgb = rgb.astype(np.float32)
94
+
95
+ # Calculate global percentiles across all channels to preserve color balance
96
+ low = np.percentile(rgb, lower_percentile)
97
+ high = np.percentile(rgb, upper_percentile)
98
 
99
+ if high <= low:
100
+ result = np.clip(rgb, 0, 255).astype(np.uint8)
101
+ else:
102
+ normalized = (rgb - low) / (high - low)
103
+ result = (np.clip(normalized, 0, 1) * 255).astype(np.uint8)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
  return result
106