đã áp dụng file shapefile vào train và predict
This commit is contained in:
+89
-2
@@ -36,6 +36,14 @@ class FeatureExtractor:
|
||||
'VH_db_mean', 'VV_db_mean', 'VH_VV_ratio'
|
||||
],
|
||||
'description': 'Extended aggregate features with statistics'
|
||||
},
|
||||
'odc': {
|
||||
'n_features': 8,
|
||||
'features': [
|
||||
'ndvi_mean', 'ndvi_min', 'ndvi_max', 'ndvi_std', 'ndvi_range',
|
||||
'ndwi_mean', 'ndbi_mean', 'evi_mean'
|
||||
],
|
||||
'description': 'ODC mode: 8 aggregate features (NDVI stats + NDWI/NDBI/EVI mean) - matches 01.train_ODC.ipynb'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,6 +237,80 @@ class FeatureExtractor:
|
||||
|
||||
return features
|
||||
|
||||
def extract_odc_features(
|
||||
self,
|
||||
s2_data: xr.Dataset,
|
||||
vh_data: Optional[xr.DataArray] = None,
|
||||
vv_data: Optional[xr.DataArray] = None
|
||||
) -> np.ndarray:
|
||||
"""
|
||||
Extract ODC aggregate features (8 features matching 01.train_ODC.ipynb):
|
||||
ndvi_mean, ndvi_min, ndvi_max, ndvi_std, ndvi_range, ndwi_mean, ndbi_mean, evi_mean
|
||||
|
||||
Args:
|
||||
s2_data: Sentinel-2 Dataset with B02, B03, B04, B08, B11
|
||||
vh_data: Not used in ODC mode
|
||||
vv_data: Not used in ODC mode
|
||||
|
||||
Returns:
|
||||
Feature array shape (n_pixels, 8)
|
||||
"""
|
||||
# Calculate spectral indices
|
||||
nir = s2_data["B08"].astype('float32')
|
||||
red = s2_data["B04"].astype('float32')
|
||||
green = s2_data["B03"].astype('float32')
|
||||
blue = s2_data["B02"].astype('float32')
|
||||
swir = s2_data["B11"].astype('float32') if "B11" in s2_data else s2_data["B02"]
|
||||
|
||||
# NDVI = (NIR - Red) / (NIR + Red)
|
||||
ndvi = (nir - red) / (nir + red + 1e-8)
|
||||
|
||||
# NDWI = (Green - NIR) / (Green + NIR)
|
||||
ndwi = (green - nir) / (green + nir + 1e-8)
|
||||
|
||||
# NDBI = (SWIR - NIR) / (SWIR + NIR)
|
||||
ndbi = (swir - nir) / (swir + nir + 1e-8)
|
||||
|
||||
# EVI = 2.5 * (NIR - Red) / (NIR + 6*Red - 7.5*Blue + 1)
|
||||
evi = 2.5 * (nir - red) / (nir + 6*red - 7.5*blue + 1)
|
||||
|
||||
features_list = []
|
||||
|
||||
# NDVI statistics (5 features)
|
||||
if 'time' in ndvi.dims:
|
||||
features_list.append(ndvi.mean(dim='time').values.flatten()) # ndvi_mean
|
||||
features_list.append(ndvi.min(dim='time').values.flatten()) # ndvi_min
|
||||
features_list.append(ndvi.max(dim='time').values.flatten()) # ndvi_max
|
||||
features_list.append(ndvi.std(dim='time').values.flatten()) # ndvi_std
|
||||
ndvi_range = (ndvi.max(dim='time') - ndvi.min(dim='time')).values.flatten()
|
||||
features_list.append(ndvi_range) # ndvi_range
|
||||
else:
|
||||
ndvi_flat = ndvi.values.flatten()
|
||||
features_list.extend([ndvi_flat, ndvi_flat, ndvi_flat, np.zeros_like(ndvi_flat), np.zeros_like(ndvi_flat)])
|
||||
|
||||
# NDWI mean (1 feature)
|
||||
if 'time' in ndwi.dims:
|
||||
features_list.append(ndwi.mean(dim='time').values.flatten()) # ndwi_mean
|
||||
else:
|
||||
features_list.append(ndwi.values.flatten())
|
||||
|
||||
# NDBI mean (1 feature)
|
||||
if 'time' in ndbi.dims:
|
||||
features_list.append(ndbi.mean(dim='time').values.flatten()) # ndbi_mean
|
||||
else:
|
||||
features_list.append(ndbi.values.flatten())
|
||||
|
||||
# EVI mean (1 feature)
|
||||
if 'time' in evi.dims:
|
||||
features_list.append(evi.mean(dim='time').values.flatten()) # evi_mean
|
||||
else:
|
||||
features_list.append(evi.values.flatten())
|
||||
|
||||
# Stack all features (total: 8 features)
|
||||
features = np.column_stack(features_list)
|
||||
|
||||
return features
|
||||
|
||||
def extract_extended_features(
|
||||
self,
|
||||
s2_data: xr.Dataset,
|
||||
@@ -319,7 +401,7 @@ class FeatureExtractor:
|
||||
Extract features theo mode đã chọn
|
||||
|
||||
Args:
|
||||
s2_data: Sentinel-2 Dataset (cần cho temporal và extended modes)
|
||||
s2_data: Sentinel-2 Dataset (cần cho temporal, extended, và odc modes)
|
||||
ndvi_data: NDVI DataArray (cần cho simple mode)
|
||||
vh_data: VH radar DataArray
|
||||
vv_data: VV radar DataArray
|
||||
@@ -342,6 +424,11 @@ class FeatureExtractor:
|
||||
raise ValueError("s2_data required for extended mode")
|
||||
return self.extract_extended_features(s2_data, vh_data, vv_data)
|
||||
|
||||
elif self.mode == 'odc':
|
||||
if s2_data is None:
|
||||
raise ValueError("s2_data required for odc mode")
|
||||
return self.extract_odc_features(s2_data, vh_data, vv_data)
|
||||
|
||||
else:
|
||||
raise ValueError(f"Unknown mode: {self.mode}")
|
||||
|
||||
@@ -359,7 +446,7 @@ def get_feature_extractor(mode: str = 'simple') -> FeatureExtractor:
|
||||
Factory function để tạo FeatureExtractor
|
||||
|
||||
Args:
|
||||
mode: 'simple', 'temporal', hoặc 'extended'
|
||||
mode: 'simple', 'temporal', 'extended', hoặc 'odc'
|
||||
|
||||
Returns:
|
||||
FeatureExtractor instance
|
||||
|
||||
Reference in New Issue
Block a user