def mnf(data): ''' Description: Minimum Noise Fraction (MNF) wrapper for pysptools implementation Rationale: Removes noise while preserving information ''' # Convert Series to ndarray if issubclass(type(data), pd.Series) or isinstance(data, Spectra): np_data = data.to_numpy() elif issubclass(type(data), np.ndarray): np_data = data else: raise ValueError("Input for MNF must inherit from pd.Series or np.ndarray") # Ensure 3 dimensional input for MNF num_dimensions = len(np_data.shape) if num_dimensions == 2: # Add arbitrary 3rd dimension cube_data = np.expand_dims(np_data, axis=0) elif num_dimensions == 3: cube_data = np_data else: raise ValueError("Input must be 2 or 3 dimensional") # Open and apply MNF module pysp_mnf = MNF() res = pysp_mnf.apply(cube_data) # Return result in dimensionality of input if num_dimensions == 2: return np.squeeze(res, axis=0) else: return res
def test_mnf_rotation(self): '''MNF rotation should achieve an expected result.''' file_path = os.path.join(self.test_dir, 'multi7_raster.tiff') ds = gdal.Open(file_path) nodata = ds.GetRasterBand(1).GetNoDataValue() hsi = ds.ReadAsArray().transpose() hsi[hsi == nodata] = 0 mnf = MNF() hsi_post_mnf = mnf.apply(hsi) self.assertEqual(int(hsi_post_mnf.diagonal()[0].sum()), 132)
def test_endmember_search_by_maximum_angle(self): '''Should be able to search for endmembers by maximum solid angle.''' rast, gt, wkt = as_array(os.path.join(self.test_dir, 'multi7_raster.tiff')) hsi = rast.transpose() hsi[hsi==-9999] = 0 mnf = MNF() hsi_post_mnf = mnf.apply(hsi) # Test that sequence/ array type works ref_target = (342683, 4703919) result = endmembers_by_maximum_angle(hsi_post_mnf.T, self.cases['Vegetation'], ref_target, gt=gt, wkt=wkt, dd=False) self.assertTrue(isinstance(result[0], np.ndarray))
def mnf_rotation(rast, nodata=-9999): ''' Applies the MNF rotation to an HSI data cube. Arguments: rast A NumPy raster array nodata The NoData value ''' hsi = rast.copy().transpose() hsi[hsi == nodata] = 0 # Remap any lingering NoData values # Apply the Minimum Noise Fraction (MNF) rotation mnf = MNF() hsi_post_mnf = mnf.apply(hsi) hsi = None return hsi_post_mnf
def test_ppi_endmember_extraction(self): ''' Extraction by PPI, following an MNF rotation, should achieve an expected result. ''' file_path = os.path.join(self.test_dir, 'multi7_raster.tiff') ds = gdal.Open(file_path) ppi = PPI() nodata = ds.GetRasterBand(1).GetNoDataValue() hsi = ds.ReadAsArray().transpose() hsi[hsi == nodata] = 0 mnf = MNF() hsi_post_mnf = mnf.apply(hsi) members = ppi.extract(hsi_post_mnf[..., 0:3], 3, numSkewers=10000) self.assertEqual(int(members.sum()), 934)