From ee556de2fe101f4ec7ffb103a76133fdacf0e7eb Mon Sep 17 00:00:00 2001 From: kvos Date: Mon, 16 Apr 2018 10:17:36 +1000 Subject: [PATCH] Neural Network image classification NN trained to classify each pixel of the image in 4 classes ( sand, whitewater, water, other) --- functions/NeuralNet_classif.pkl | Bin 0 -> 54033 bytes functions/sds.py | 127 +++++++++++++++++++++++++++----- sds_extract.py | 25 ++++--- 3 files changed, 123 insertions(+), 29 deletions(-) create mode 100644 functions/NeuralNet_classif.pkl diff --git a/functions/NeuralNet_classif.pkl b/functions/NeuralNet_classif.pkl new file mode 100644 index 0000000000000000000000000000000000000000..375d597d21dec0d74ef0d654ecc54a957cdfdb6c GIT binary patch literal 54033 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 label = 1 + - whitewater (breaking waves and swash) --> label = 2 + - water --> label = 3 + - other (vegetation, buildings, rocks...) --> label = 0 + + The classifier is a Neural Network, trained with 7000 pixels for the class SAND and 1500 pixels for + each of the other classes. This is because the class of interest for my application is SAND and I + wanted to minimize the classification error for that class + + KV WRL 2018 + + Arguments: + ----------- + im_ms_ps: np.ndarray + Pansharpened RGB + downsampled NIR and SWIR + im_pan: + Panchromatic band + cloud_mask: np.ndarray + 2D cloud mask with True where cloud pixels are + plot_bool: boolean + True if plot is wanted + + Returns: ----------- + im_labels: np.ndarray + 2D binary image containing True where sand pixels are located + + """ + + # load classifier + clf = joblib.load('functions/NeuralNet_classif.pkl') + + # calculate features + n_features = 10 + im_features = np.zeros((im_ms_ps.shape[0], im_ms_ps.shape[1], n_features)) + im_features[:,:,[0,1,2,3,4]] = im_ms_ps + im_features[:,:,5] = im_pan + im_features[:,:,6] = nd_index(im_ms_ps[:,:,3], im_ms_ps[:,:,1], cloud_mask, False) # (NIR-G) + im_features[:,:,7] = nd_index(im_ms_ps[:,:,3], im_ms_ps[:,:,2], cloud_mask, False) # ND(NIR-R) + im_features[:,:,8] = nd_index(im_ms_ps[:,:,0], im_ms_ps[:,:,2], cloud_mask, False) # ND(B-R) + im_features[:,:,9] = nd_index(im_ms_ps[:,:,4], im_ms_ps[:,:,1], cloud_mask, False) # ND(SWIR-G) + # remove NaNs and clouds + vec_features = im_features.reshape((im_ms_ps.shape[0] * im_ms_ps.shape[1], n_features)) + vec_cloud = cloud_mask.reshape(cloud_mask.shape[0]*cloud_mask.shape[1]) + vec_nan = np.any(np.isnan(vec_features), axis=1) + vec_mask = np.logical_or(vec_cloud, vec_nan) + vec_features = vec_features[~vec_mask, :] + # predict with NN classifier + labels = clf.predict(vec_features) + # recompose image + vec_classif = np.zeros((cloud_mask.shape[0]*cloud_mask.shape[1])) + vec_classif[~vec_mask] = labels + im_classif = vec_classif.reshape((im_ms_ps.shape[0], im_ms_ps.shape[1])) +# im_classif = morphology.remove_small_objects(im_classif, min_size=min_beach_size, connectivity=2) + + if plot_bool: + im_display = rescale_image_intensity(im_ms_ps[:,:,[2,1,0]], cloud_mask, 100, False) + im = np.copy(im_display) + colours = np.array([[1,0,0],[1,1,0],[0,1,1],[0,0,1]]) + for k in range(4): + im[im_classif == k,0] = colours[k,0] + im[im_classif == k,1] = colours[k,1] + im[im_classif == k,2] = colours[k,2] + + plt.figure() + ax1 = plt.subplot(121) + plt.imshow(im_display) + plt.axis('off') + plt.title('Image') + ax2 = plt.subplot(122, sharex=ax1, sharey=ax1) + plt.imshow(im) + plt.axis('off') + plt.title('NN') + plt.draw() + + return im_classif + diff --git a/sds_extract.py b/sds_extract.py index a6f4126..74742c3 100644 --- a/sds_extract.py +++ b/sds_extract.py @@ -37,7 +37,6 @@ ee.Initialize() # parameters cloud_thresh = 0.5 # threshold for cloud cover plot_bool = True # if you want the plots -prob_high = 99.9 # upper probability to clip and rescale pixel intensity min_contour_points = 100# minimum number of points contained in each water line output_epsg = 28356 # GDA94 / MGA Zone 56 buffer_size = 10 # radius of disk for buffer (sand classif parameter) @@ -71,23 +70,26 @@ i = 0 # first image im = ee.Image(im_all[i].get('id')) # load image as np.array -im_pan, im_ms, im_cloud, crs, meta = sds.read_eeimage(im, polygon, satname, plot_bool) +im_pan, im_ms, cloud_mask, crs, meta = sds.read_eeimage(im, polygon, satname, plot_bool) -# rescale intensities -im_ms = sds.rescale_image_intensity(im_ms, im_cloud, prob_high, plot_bool) -im_pan = sds.rescale_image_intensity(im_pan, im_cloud, prob_high, plot_bool) +# mask -inf or nan values on the image and add to cloud_mask +im_inf = np.isin(im_ms[:,:,0], -np.inf) +im_nan = np.isnan(im_ms[:,:,0]) +cloud_mask = np.logical_or(np.logical_or(cloud_mask, im_inf), im_nan) +cloud_cover = sum(sum(cloud_mask.astype(int)))/(cloud_mask.shape[0]*cloud_mask.shape[1]) +print('Cloud cover : ' + str(int(round(100*cloud_cover))) + ' %') # pansharpen rgb image -im_ms_ps = sds.pansharpen(im_ms[:,:,[0,1,2]], im_pan, im_cloud, plot_bool) +im_ms_ps = sds.pansharpen(im_ms[:,:,[0,1,2]], im_pan, cloud_mask, plot_bool) # add down-sized bands for NIR and SWIR (since pansharpening is not possible) im_ms_ps = np.append(im_ms_ps, im_ms[:,:,[3,4]], axis=2) # calculate NDWI -im_ndwi = sds.nd_index(im_ms_ps[:,:,3], im_ms_ps[:,:,1], im_cloud, plot_bool) +im_ndwi = sds.nd_index(im_ms_ps[:,:,3], im_ms_ps[:,:,1], cloud_mask, plot_bool) # edge detection -wl_pix = sds.find_wl_contours(im_ndwi, im_cloud, min_contour_points, plot_bool) +wl_pix = sds.find_wl_contours(im_ndwi, cloud_mask, min_contour_points, plot_bool) plt.figure() plt.imshow(im_ms_ps[:,:,[2,1,0]]) @@ -102,5 +104,8 @@ wl_coords = sds.convert_pix2world(wl_pix, crs['crs_15m']) # convert to output epsg spatial reference wl = sds.convert_epsg(wl_coords, crs['epsg_code'], output_epsg) -# classify sand pixels -im_sand = sds.classify_sand_unsupervised(im_ms_ps, im_pan, im_cloud, wl_pix, buffer_size, min_beach_size, plot_bool) +# classify sand pixels with Kmeans +#im_sand = sds.classify_sand_unsupervised(im_ms_ps, im_pan, cloud_mask, wl_pix, buffer_size, min_beach_size, plot_bool) + +# classify image in 4 classes (sand, whitewater, water, other) with NN classifier +im_classif = sds.classify_image_NN(im_ms_ps, im_pan, cloud_mask, plot_bool) \ No newline at end of file