├── README.md ├── notebooks ├── 0_ BandStacking.ipynb ├── 0_ Preprocessing_BandStack.ipynb ├── 1_generate_binary_mask.ipynb ├── 2_Sampling_images.ipynb ├── 3_patch_images.ipynb ├── 4_load_images_as_arrays.ipynb ├── 5_data_augmentation.ipynb ├── Georeferencing_the_results.ipynb ├── Training_random_RapidEye + DEM.ipynb ├── Training_random_RapidEye+Augmentation.ipynb ├── Training_random_RapidEye+DEM+Augmentation.ipynb ├── Training_random_RapidEye.ipynb ├── Training_regular_RapidEye+Augmentation.ipynb ├── Training_regular_RapidEye+DEM+Augmentation.ipynb ├── Training_regular_RapidEye+DEM.ipynb ├── Training_regular_RapidEye.ipynb └── utils.py └── requirements.txt /README.md: -------------------------------------------------------------------------------- 1 | Repository with the code used in the paper Landslide Segmentation with Unet: Evaluating Different Sampling Methods and Patch Sizes 2 | 3 | 4 | ### Data 5 | 6 | The data used in this research and the best models' weights are available and can be requested by sending an email to lpsoares@usp.br 7 | 8 | 9 | ### Dependencies 10 | 11 | The requirements.txt file contains all the libraries used in the preprocessing step. To install, follow the steps below: 12 | 13 | 1. cd to the directory where requirements.txt is located. 14 | 2. activate your virtualenv. 15 | 3. run: pip install -r requirements.txt in your shell. 16 | 17 | The notebooks used to train and evaluate the networks should be uploaded to Google Drive and opened in the Google Colaboraty Virtual Environment. 18 | 19 | 20 | ## Preprocessing 21 | 22 | 1. [Band Stacking](https://github.com/lpsmlgeobr/Landslide_segmentation_with_unet/blob/master/notebooks/0_%20BandStacking.ipynb) 23 | 24 | 2. [Binary Masks](https://github.com/lpsmlgeobr/Landslide_segmentation_with_unet/blob/master/notebooks/1_generate_binary_mask.ipynb) 25 | 26 | 3. [Image Sampling](https://github.com/lpsmlgeobr/Landslide_segmentation_with_unet/blob/master/notebooks/2_Sampling_images.ipynb) 27 | 28 | 4. [Load image as Arrays](https://github.com/lpsmlgeobr/Landslide_segmentation_with_unet/blob/master/notebooks/4_load_images_as_arrays.ipynb) 29 | 30 | 5. [Data Augmentation](https://github.com/lpsmlgeobr/Landslide_segmentation_with_unet/blob/master/notebooks/5_data_augmentation.ipynb) 31 | 32 | ## Training 33 | 34 | #### RapidEye 35 | 36 | 1. [Regular Sampling](https://github.com/lpsmlgeobr/Landslide_segmentation_with_unet/blob/master/notebooks/Training_regular_RapidEye.ipynb) 37 | 38 | 2. [Random Sampling](https://github.com/lpsmlgeobr/Landslide_segmentation_with_unet/blob/master/notebooks/Training_random_RapidEye.ipynb) 39 | 40 | 41 | #### RapidEye + Augmentation 42 | 43 | 1. [Regular Sampling](https://github.com/lpsmlgeobr/Landslide_segmentation_with_unet/blob/master/notebooks/Training_regular_RapidEye%2BAugmentation.ipynb) 44 | 45 | 2. [Random Sampling](https://github.com/lpsmlgeobr/Landslide_segmentation_with_unet/blob/master/notebooks/Training_random_RapidEye%2BAugmentation.ipynb) 46 | 47 | 48 | #### RapidEye + DEM 49 | 50 | 1. [Regular Sampling](https://github.com/lpsmlgeobr/Landslide_segmentation_with_unet/blob/master/notebooks/Training_regular_RapidEye%2BDEM.ipynb) 51 | 52 | 2. [Random Sampling](https://github.com/lpsmlgeobr/Landslide_segmentation_with_unet/blob/master/notebooks/Training_random_RapidEye%2BDEM.ipynb) 53 | 54 | #### RapidEye + DEM + Augmentation 55 | 56 | 1. [Regular Sampling](https://github.com/lpsmlgeobr/Landslide_segmentation_with_unet/blob/master/notebooks/Training_regular_RapidEye%2BDEM%2BAugmentation.ipynb) 57 | 58 | 2. [Random Sampling](https://github.com/lpsmlgeobr/Landslide_segmentation_with_unet/blob/master/notebooks/Training_random_RapidEye%2BDEM%2BAugmentation.ipynb) 59 | 60 | 61 | ## Results 62 | 63 | 1. [Georeferencing the Results](https://github.com/lpsmlgeobr/Landslide_segmentation_with_unet/blob/master/notebooks/Georeferencing_the_results.ipynb) 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /notebooks/0_ BandStacking.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "\n", 8 | "### Code used to stack the RapidEye (5 bands) with the Alos/PALSAR (resampled to 5 meters) image " 9 | ] 10 | }, 11 | { 12 | "cell_type": "code", 13 | "execution_count": null, 14 | "metadata": {}, 15 | "outputs": [], 16 | "source": [ 17 | "# Import rasterio library\n", 18 | "import rasterio as rio" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": null, 24 | "metadata": {}, 25 | "outputs": [], 26 | "source": [ 27 | "# Define the path to the images \n", 28 | "pathToRapidEye = \"/data/images/RapidEye/2328825_2011-08-13_RE1_3A_Analytic.tif\"\n", 29 | "pathToAlosPalsar = \"/data/images/Alos/alos_nova_friburgo_5m.tif\"\n", 30 | "\n", 31 | "# Define the path to save the stacked image\n", 32 | "pathToSave = \"/data/images/stack_RapidEye_Alos/RapidEye_and_Alos_Nova_Friburgo.tif\"" 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": null, 38 | "metadata": {}, 39 | "outputs": [], 40 | "source": [ 41 | "# Open RapidEye Bands\n", 42 | "with rio.open(pathToRapidEye) as src:\n", 43 | " band_blue = src.read(1)\n", 44 | " band_green = src.read(2)\n", 45 | " band_red = src.read(3)\n", 46 | " band_red_edge = src.read(4)\n", 47 | " band_nir = src.read(5)\n", 48 | " " 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "execution_count": null, 54 | "metadata": {}, 55 | "outputs": [], 56 | "source": [ 57 | "# Open Alos image\n", 58 | "with rio.open(pathToAlosPalsar) as alos:\n", 59 | " band_alos = alos.read(1)" 60 | ] 61 | }, 62 | { 63 | "cell_type": "code", 64 | "execution_count": null, 65 | "metadata": {}, 66 | "outputs": [], 67 | "source": [ 68 | "# Update the metadata with count = 6 (5 (RapidEye) + 1 (Alos - DEM)) and dtype = uint16\n", 69 | "kwargs = src.meta\n", 70 | "kwargs.update(\n", 71 | " dtype=rio.uint16,\n", 72 | " count = 6)" 73 | ] 74 | }, 75 | { 76 | "cell_type": "code", 77 | "execution_count": null, 78 | "metadata": {}, 79 | "outputs": [], 80 | "source": [ 81 | "# Save the stacked image\n", 82 | "with rio.open(pathToSaveStacked,\"w\",**kwargs) as dst:\n", 83 | " dst.write_band(1, band_blue.astype(rio.uint16))\n", 84 | " dst.write_band(2, band_green.astype(rio.uint16))\n", 85 | " dst.write_band(3, band_red.astype(rio.uint16))\n", 86 | " dst.write_band(4, band_red_edge.astype(rio.uint16))\n", 87 | " dst.write_band(5, band_nir.astype(rio.uint16))\n", 88 | " dst.write_band(6, band_alos.astype(rio.uint16))" 89 | ] 90 | } 91 | ], 92 | "metadata": { 93 | "kernelspec": { 94 | "display_name": "Python 3", 95 | "language": "python", 96 | "name": "python3" 97 | }, 98 | "language_info": { 99 | "codemirror_mode": { 100 | "name": "ipython", 101 | "version": 3 102 | }, 103 | "file_extension": ".py", 104 | "mimetype": "text/x-python", 105 | "name": "python", 106 | "nbconvert_exporter": "python", 107 | "pygments_lexer": "ipython3", 108 | "version": "3.7.0" 109 | } 110 | }, 111 | "nbformat": 4, 112 | "nbformat_minor": 2 113 | } 114 | -------------------------------------------------------------------------------- /notebooks/0_ Preprocessing_BandStack.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "\n", 8 | "### Code used to stack the RapidEye (5 bands) with the Alos/PALSAR (resampled to 5 meters) image " 9 | ] 10 | }, 11 | { 12 | "cell_type": "code", 13 | "execution_count": null, 14 | "metadata": {}, 15 | "outputs": [], 16 | "source": [ 17 | "# Import rasterio library\n", 18 | "import rasterio as rio" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": null, 24 | "metadata": {}, 25 | "outputs": [], 26 | "source": [ 27 | "# Define the path to the images \n", 28 | "pathToRapidEye = \"data/images/RapidEye/2328825_2011-08-13_RE1_3A_Analytic.tif\"\n", 29 | "pathToAlosPalsar = \"data/images/Alos/alos_nova_friburgo_5m.tif\"\n", 30 | "\n", 31 | "# Define the path to save the stacked image\n", 32 | "pathToSave = \"data/images/stack_RapidEye_Alos/RapidEye_and_Alos_Nova_Friburgo.tif\"" 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": null, 38 | "metadata": {}, 39 | "outputs": [], 40 | "source": [ 41 | "# Open RapidEye Bands\n", 42 | "with rio.open(pathToRapidEye) as src:\n", 43 | " band_blue = src.read(1)\n", 44 | " band_green = src.read(2)\n", 45 | " band_red = src.read(3)\n", 46 | " band_red_edge = src.read(4)\n", 47 | " band_nir = src.read(5)\n", 48 | " " 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "execution_count": null, 54 | "metadata": {}, 55 | "outputs": [], 56 | "source": [ 57 | "# Open Alos image\n", 58 | "with rio.open(pathToAlosPalsar) as alos:\n", 59 | " band_alos = alos.read(1)" 60 | ] 61 | }, 62 | { 63 | "cell_type": "code", 64 | "execution_count": null, 65 | "metadata": {}, 66 | "outputs": [], 67 | "source": [ 68 | "# Update the metadata with count = 6 (5 (RapidEye) + 1 (Alos - DEM)) and dtype = uint16\n", 69 | "kwargs = src.meta\n", 70 | "kwargs.update(\n", 71 | " dtype=rio.uint16,\n", 72 | " count = 6)" 73 | ] 74 | }, 75 | { 76 | "cell_type": "code", 77 | "execution_count": null, 78 | "metadata": {}, 79 | "outputs": [], 80 | "source": [ 81 | "# Save the stacked image\n", 82 | "with rio.open(pathToSave,\"w\",**kwargs) as dst:\n", 83 | " dst.write_band(1, band_blue.astype(rio.uint16))\n", 84 | " dst.write_band(2, band_green.astype(rio.uint16))\n", 85 | " dst.write_band(3, band_red.astype(rio.uint16))\n", 86 | " dst.write_band(4, band_red_edge.astype(rio.uint16))\n", 87 | " dst.write_band(5, band_nir.astype(rio.uint16))\n", 88 | " dst.write_band(6, band_alos.astype(rio.uint16))" 89 | ] 90 | }, 91 | { 92 | "cell_type": "code", 93 | "execution_count": null, 94 | "metadata": {}, 95 | "outputs": [], 96 | "source": [] 97 | } 98 | ], 99 | "metadata": { 100 | "kernelspec": { 101 | "display_name": "Python 3", 102 | "language": "python", 103 | "name": "python3" 104 | }, 105 | "language_info": { 106 | "codemirror_mode": { 107 | "name": "ipython", 108 | "version": 3 109 | }, 110 | "file_extension": ".py", 111 | "mimetype": "text/x-python", 112 | "name": "python", 113 | "nbconvert_exporter": "python", 114 | "pygments_lexer": "ipython3", 115 | "version": "3.7.7" 116 | } 117 | }, 118 | "nbformat": 4, 119 | "nbformat_minor": 2 120 | } 121 | -------------------------------------------------------------------------------- /notebooks/1_generate_binary_mask.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "# Load utils\n", 10 | "from utils import *" 11 | ] 12 | }, 13 | { 14 | "cell_type": "code", 15 | "execution_count": null, 16 | "metadata": {}, 17 | "outputs": [], 18 | "source": [ 19 | "# Define the path to the train and test images and geojsons\n", 20 | "\n", 21 | "# train area\n", 22 | "trainImage = \"data/images/RapidEye/2328825_2011-08-13_RE1_3A_Analytic.tif\"\n", 23 | "trainPolygons = \"data/polygons/train/train_landslides.geojson\"\n", 24 | "\n", 25 | "# test area 1\n", 26 | "test1Image = \"data/images/test/test_area_1.tif\"\n", 27 | "testArea1Polygons = \"data/polygons/test/test_area_1_landslides.geojson\"\n", 28 | "\n", 29 | "\n", 30 | "# test area 2\n", 31 | "test2Image = \"data/images/test/test_area_1.tif\"\n", 32 | "testArea2Polygons = testPolygons = \"data/polygons/test/test_area_2_landslides.geojson\"" 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": null, 38 | "metadata": {}, 39 | "outputs": [], 40 | "source": [ 41 | "# Define the folder and the name of the outputfiles\n", 42 | "\n", 43 | "# Output folder path\n", 44 | "outputTrain = \"data/train/mask\"\n", 45 | "outputTest1 = \"data/test/test_1/mask\"\n", 46 | "outputTest2 = \"data/test/test_2/mask\"\n", 47 | "\n", 48 | "# File Name\n", 49 | "saveNameTrain = \"train_mask.tif\"\n", 50 | "saveNameTest1= \"test_area_1_mask.tif\"\n", 51 | "saveNameTest2 = \"test_area_2_mask.tif\"" 52 | ] 53 | }, 54 | { 55 | "cell_type": "code", 56 | "execution_count": null, 57 | "metadata": {}, 58 | "outputs": [], 59 | "source": [ 60 | "# save the root directory\n", 61 | "owd = os.getcwd()\n", 62 | "\n", 63 | "\n", 64 | "# generate train mask (generate_mask is a fuction from the utils library)\n", 65 | "generate_mask(shape_path= trainPolygons,\n", 66 | " raster_path= trainImage,\n", 67 | " output_path=outputTrain,\n", 68 | " file_name=saveNameTrain)\n", 69 | "\n", 70 | "# back to root directory\n", 71 | "os.chdir(owd)\n", 72 | "\n", 73 | "# generate test 1 area mask\n", 74 | "generate_mask(shape_path= testArea1Polygons,\n", 75 | " raster_path= test1Image,\n", 76 | " output_path=outputTest1,\n", 77 | " file_name=saveNameTest1)\n", 78 | "\n", 79 | "# back to root directory\n", 80 | "os.chdir(owd)\n", 81 | "\n", 82 | "# generate test 2 area mask\n", 83 | "generate_mask(shape_path= testArea2Polygons,\n", 84 | " raster_path= test2Image,\n", 85 | " output_path=outputTest2,\n", 86 | " file_name=saveNameTest2)" 87 | ] 88 | }, 89 | { 90 | "cell_type": "code", 91 | "execution_count": null, 92 | "metadata": {}, 93 | "outputs": [], 94 | "source": [] 95 | } 96 | ], 97 | "metadata": { 98 | "kernelspec": { 99 | "display_name": "Python 3", 100 | "language": "python", 101 | "name": "python3" 102 | }, 103 | "language_info": { 104 | "codemirror_mode": { 105 | "name": "ipython", 106 | "version": 3 107 | }, 108 | "file_extension": ".py", 109 | "mimetype": "text/x-python", 110 | "name": "python", 111 | "nbconvert_exporter": "python", 112 | "pygments_lexer": "ipython3", 113 | "version": "3.7.7" 114 | } 115 | }, 116 | "nbformat": 4, 117 | "nbformat_minor": 2 118 | } 119 | -------------------------------------------------------------------------------- /notebooks/2_Sampling_images.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Code to sample the dataset\n", 8 | "\n", 9 | "This code was used to create square polygons to sample the dataset in two ways:\n", 10 | "\n", 11 | "- Grid;\n", 12 | "\n", 13 | "- Random.\n", 14 | "\n", 15 | "The code was adapted from keras-spatial library (https://pypi.org/project/keras-spatial/).\n", 16 | "\n", 17 | "Then, QGIS (select-by-location) was used to select the polygons that interserct the landslides." 18 | ] 19 | }, 20 | { 21 | "cell_type": "code", 22 | "execution_count": null, 23 | "metadata": {}, 24 | "outputs": [], 25 | "source": [ 26 | "# Import libraries\n", 27 | "import geopandas as gpd\n", 28 | "import numpy as np\n", 29 | "from shapely.geometry import box\n", 30 | "import os\n", 31 | "import rasterio as rio" 32 | ] 33 | }, 34 | { 35 | "cell_type": "code", 36 | "execution_count": null, 37 | "metadata": {}, 38 | "outputs": [], 39 | "source": [ 40 | "# Define the class SampleShapefile that will generate the random and regular samples.\n", 41 | "class SampleShapefile():\n", 42 | " \"\"\"\n", 43 | " Class SampleShapeFile:\n", 44 | " \n", 45 | " Attributes:\n", 46 | " imagepath (string) = path to the .tif image;\n", 47 | " \n", 48 | " Methods:\n", 49 | " generateShapefileRandomGrid => (geopandas.GeoDataFrame) \n", 50 | " generateShapefileRegularGrid =>(geopandas.GeoDataFrame)\n", 51 | " \n", 52 | " \"\"\"\n", 53 | " def __init__(self,pathToImage):\n", 54 | " # Define the imagepath variable with the path to the .tif image\n", 55 | " self.imagepath = pathToImage\n", 56 | " # Define the class atribute the image varible that opens the .tif image\n", 57 | " self.image = rio.open(self.imagepath)\n", 58 | " # Get the metadata, crs and bounds of the TifImage\n", 59 | " with self.image as TifImage:\n", 60 | " self.meta = TifImage.meta\n", 61 | " print(-self.meta[\"transform\"][4])\n", 62 | " self.crs = TifImage.crs\n", 63 | " self.xmax = TifImage.bounds[2]\n", 64 | " self.xmin = TifImage.bounds[0]\n", 65 | " self.ymax = TifImage.bounds[3]\n", 66 | " self.ymin = TifImage.bounds[1]\n", 67 | " \n", 68 | " def generateShapefileRandomGrid(self,xsize, ysize, count, save = False, savePath = None):\n", 69 | " \"\"\"\n", 70 | " # Code addapted from Keras-spatial library - https://pypi.org/project/keras-spatial/ \n", 71 | " Generate random grid over extent.\n", 72 | " Args:\n", 73 | " xmin (float): extent left boundary\n", 74 | " ymin (float): extent bottom boundary\n", 75 | " xmax (float): extent right boundary\n", 76 | " ymax (float): extent top boundary\n", 77 | " xsize (float): patch width\n", 78 | " ysize (float): patch height\n", 79 | " count (int): number of patches\n", 80 | " crs (CRS): crs to assign geodataframe \n", 81 | " Returns:\n", 82 | " :obj:`geopandas.GeoDataFrame`:\n", 83 | " \"\"\"\n", 84 | " #Define the pixel size and multiply by the xsize to get xsize in number of pixels\n", 85 | " xsize = self.meta[\"transform\"][0]*xsize\n", 86 | " ysize = self.meta[\"transform\"][4]*ysize*-1\n", 87 | " \n", 88 | " x = np.random.rand(count) * (self.xmax-self.xmin-xsize) + self.xmin\n", 89 | " y = np.random.rand(count) * (self.ymax-self.ymin-ysize) + self.ymin\n", 90 | " polys = [box(x, y, x+xsize, y+ysize) for x,y in np.nditer([x,y])]\n", 91 | "\n", 92 | " gdf = gpd.GeoDataFrame({'geometry':polys})\n", 93 | " gdf.crs = self.crs\n", 94 | " if save == False:\n", 95 | " return gdf\n", 96 | " else:\n", 97 | " os.chdir(savePath)\n", 98 | " gdf.to_file(\"random_grid\" + \".geojson\", driver=\"GeoJSON\")\n", 99 | " \n", 100 | " \n", 101 | " \n", 102 | " \n", 103 | " def generateShapefileRegularGrid(self,xsize, ysize, overlap=0,save = False, savePath = None):\n", 104 | " \"\"\"\n", 105 | " # Code addapted from Keras-spatial library - https://pypi.org/project/keras-spatial/ \n", 106 | " Generate regular grid over extent.\n", 107 | " Args:\n", 108 | " xmin (float): extent left boundary\n", 109 | " ymin (float): extent bottom boundary\n", 110 | " xmax (float): extent right boundary\n", 111 | " ymax (float): extent top boundary\n", 112 | " xsize (float): patch width\n", 113 | " ysize (float): patch height\n", 114 | " overlap (float): percentage of patch overlap (optional)\n", 115 | " crs (CRS): crs to assign geodataframe \n", 116 | " Returns:\n", 117 | " if save == false:\n", 118 | " \n", 119 | " else:\n", 120 | " geopandas.GeoDataFrame:\n", 121 | " \"\"\"\n", 122 | " #Define the pixel size and multiply by the xsize to get xsize in number of pixels\n", 123 | " xsize = self.meta[\"transform\"][0]*xsize\n", 124 | " ysize = (-self.meta[\"transform\"][4])*ysize\n", 125 | "\n", 126 | " x = np.linspace(self.xmin, self.xmax-xsize, num=(self.xmax-self.xmin)//(xsize-xsize*overlap))\n", 127 | " y = np.linspace(self.ymin, self.ymax-ysize, num=(self.ymax-self.ymin)//(ysize-ysize*overlap))\n", 128 | " X,Y = np.meshgrid(x, y)\n", 129 | " polys = [box(x, y, x+xsize, y+ysize) for x,y in np.nditer([X,Y])]\n", 130 | "\n", 131 | " gdf = gpd.GeoDataFrame({'geometry':polys})\n", 132 | " gdf.crs = self.crs\n", 133 | " if save == False:\n", 134 | " return gdf\n", 135 | " else:\n", 136 | " os.chdir(savePath)\n", 137 | " gdf.to_file(\"regular_grid.geojson\", driver=\"GeoJSON\")" 138 | ] 139 | }, 140 | { 141 | "cell_type": "code", 142 | "execution_count": null, 143 | "metadata": {}, 144 | "outputs": [], 145 | "source": [ 146 | "# save the root directory\n", 147 | "owd = os.getcwd()\n", 148 | "\n", 149 | "# define the path to the image that will be sampled \n", 150 | "pathToImage = \"data/images/RapidEye/2328825_2011-08-13_RE1_3A_Analytic.tif\"\n", 151 | "# Create an instance of SampleShapefile\n", 152 | "trainSampleShapefile = SampleShapefile(pathToImage)" 153 | ] 154 | }, 155 | { 156 | "cell_type": "code", 157 | "execution_count": null, 158 | "metadata": {}, 159 | "outputs": [], 160 | "source": [ 161 | "os.chdir(owd)\n", 162 | "# Generate grid and random shapefiles 32x32\n", 163 | "savePath = \"data/train/shapefiles/32_32/regular\"\n", 164 | "# Generate the regular grid shapefile (32x32) with 0.2 overlap \n", 165 | "# Since the pixel size have same decimal places that increase by 1 the tile size\n", 166 | "# 31 was used instead of 32\n", 167 | "trainSampleShapefile.generateShapefileRegularGrid(31,31,0.2,True,savePath)" 168 | ] 169 | }, 170 | { 171 | "cell_type": "code", 172 | "execution_count": null, 173 | "metadata": {}, 174 | "outputs": [], 175 | "source": [ 176 | "os.chdir(owd)\n", 177 | "# Generate grid and random shapefiles 32x32\n", 178 | "savePath = \"data/train/shapefiles/32_32/random\"\n", 179 | "# Generate the random grid sampling shapefile with 5000 samples\n", 180 | "trainSampleShapefile.generateShapefileRandomGrid(31,31,5000,True,savePath)" 181 | ] 182 | }, 183 | { 184 | "cell_type": "code", 185 | "execution_count": null, 186 | "metadata": {}, 187 | "outputs": [], 188 | "source": [ 189 | "os.chdir(owd)\n", 190 | "# Generate grid and random shapefiles 64x64\n", 191 | "\n", 192 | "# Define the path to save the geojson\n", 193 | "savePath = \"data/train/shapefiles/64_64/regular\"\n", 194 | "# Generate the regular grid shapefile (64x64) with 0.2 overlap \n", 195 | "# Since the pixel size have same decimal places that increase by 1 the tile size\n", 196 | "# 61 was used instead of 64\n", 197 | "trainSampleShapefile.generateShapefileRegularGrid(63,63,0.2,True,savePath)" 198 | ] 199 | }, 200 | { 201 | "cell_type": "code", 202 | "execution_count": null, 203 | "metadata": {}, 204 | "outputs": [], 205 | "source": [ 206 | "os.chdir(owd)\n", 207 | "# Generate random shapefiles 64x64\n", 208 | "\n", 209 | "# Define the path to save the geojson\n", 210 | "savePath = \"data/train/shapefiles/64_64/random\"\n", 211 | "# Generate the random grid sampling shapefile with 5000 samples\n", 212 | "trainSampleShapefile.generateShapefileRandomGrid(63,63,5000,True,savePath)" 213 | ] 214 | }, 215 | { 216 | "cell_type": "code", 217 | "execution_count": null, 218 | "metadata": {}, 219 | "outputs": [], 220 | "source": [ 221 | "os.chdir(owd)\n", 222 | "# Generate grid and random shapefiles 128x128\n", 223 | "\n", 224 | "# Define the path to save the geojson\n", 225 | "savePath = \"data/train/shapefiles/128_128/regular\"\n", 226 | "# Generate the regular grid shapefile (64x64) with 0.2 overlap \n", 227 | "# Since the pixel size have same decimal places that increase by 1 the tile size\n", 228 | "# 127 was used instead of 128\n", 229 | "trainSampleShapefile.generateShapefileRegularGrid(128,128,0.2,True,savePath)" 230 | ] 231 | }, 232 | { 233 | "cell_type": "code", 234 | "execution_count": null, 235 | "metadata": {}, 236 | "outputs": [], 237 | "source": [ 238 | "os.chdir(owd)\n", 239 | "# Generate random shapefiles 128x128\n", 240 | "\n", 241 | "# Define the path to save the geojson\n", 242 | "savePath = \"data/train/shapefiles/128_128/random\"\n", 243 | "# Generate the random grid sampling shapefile with 5000 samples\n", 244 | "trainSampleShapefile.generateShapefileRandomGrid(127,127,5000,True,savePath)" 245 | ] 246 | }, 247 | { 248 | "cell_type": "code", 249 | "execution_count": null, 250 | "metadata": {}, 251 | "outputs": [], 252 | "source": [] 253 | } 254 | ], 255 | "metadata": { 256 | "kernelspec": { 257 | "display_name": "Python 3", 258 | "language": "python", 259 | "name": "python3" 260 | }, 261 | "language_info": { 262 | "codemirror_mode": { 263 | "name": "ipython", 264 | "version": 3 265 | }, 266 | "file_extension": ".py", 267 | "mimetype": "text/x-python", 268 | "name": "python", 269 | "nbconvert_exporter": "python", 270 | "pygments_lexer": "ipython3", 271 | "version": "3.7.7" 272 | } 273 | }, 274 | "nbformat": 4, 275 | "nbformat_minor": 2 276 | } 277 | -------------------------------------------------------------------------------- /notebooks/3_patch_images.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Patch Images\n", 8 | "\n", 9 | "- Code used to patch images in 32x32, 64x64, 128x128 tiles.\n", 10 | "\n", 11 | "- The input are the square polygons that intersect the training landslides.\n" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": null, 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "import fiona\n", 21 | "import rasterio\n", 22 | "from rasterio.mask import mask\n", 23 | "import os\n", 24 | "from rasterio import plot" 25 | ] 26 | }, 27 | { 28 | "cell_type": "code", 29 | "execution_count": null, 30 | "metadata": {}, 31 | "outputs": [], 32 | "source": [ 33 | "def patchImage(shapefilePath, imagePath,savePath, fileName, size, save = False):\n", 34 | " \"\"\"\n", 35 | " Function that use polygons to patch the image.\n", 36 | " \n", 37 | " inputs:\n", 38 | " \n", 39 | " shapefilePath (string) = path to the .shp or geojson file with the polygons that will patch the image.\n", 40 | " \n", 41 | " imagePath (string) = path to the image.\n", 42 | " \n", 43 | " fileName (string) = name of the output file.\n", 44 | " \n", 45 | " Return (if save = false)\n", 46 | " \n", 47 | " (np.array) image\n", 48 | " \n", 49 | " \"\"\"\n", 50 | " owd = os.getcwd()\n", 51 | " images = []\n", 52 | " non_32 = []\n", 53 | " #Load the shapefile\n", 54 | " with fiona.open(shapefilePath, \"r\") as shapefile:\n", 55 | " #Generate a list with the geometry of the shapes\n", 56 | " shapes = [feature[\"geometry\"] for feature in shapefile]\n", 57 | " print(f\"There are {len(shapes)} polygons to patch the image.\")\n", 58 | " with rasterio.open(imagePath) as src:\n", 59 | " for i in range(len(shapes)):\n", 60 | " #patch the image based on the shapefile\n", 61 | " out_image, out_transform = rasterio.mask.mask(src, [shapes[i]], crop=True)\n", 62 | " #Get the metadata of the crop\n", 63 | " out_meta = src.meta\n", 64 | " #Evaluate if the size is the desired size\n", 65 | " if out_image.shape[1] == size and out_image.shape[2] == size:\n", 66 | " images.append(rasterio.plot.reshape_as_image(out_image))\n", 67 | " else:\n", 68 | " non_32.append(i)\n", 69 | " if save == True:\n", 70 | " os.chdir(savePath)\n", 71 | " # if want to save the tiles\n", 72 | " out_meta.update({\"driver\": \"GTiff\", \"height\": out_image.shape[1], \"width\": out_image.shape[2], \"transform\": out_transform})\n", 73 | " with rasterio.open(f\"{fileName}_{str(i)}.tif\", \"w\", **out_meta) as dest:\n", 74 | " dest.write(out_image)\n", 75 | " os.chdir(owd)\n", 76 | " \n", 77 | " print(f\"Number of shapefiles with wrong patch dimensions = {len(non_32)}\")\n", 78 | " print(f\"Number of shapefiles with correct patch dimensions = {len(images)}\")\n", 79 | " print(f\"Done! Images saved on {savePath}\")\n", 80 | " if save == False:\n", 81 | " image = np.array(images, dtype = \"float32\")\n", 82 | " return image" 83 | ] 84 | }, 85 | { 86 | "cell_type": "code", 87 | "execution_count": null, 88 | "metadata": {}, 89 | "outputs": [], 90 | "source": [ 91 | "#Train 32x32 regular grid without terrain\n", 92 | "size = 32\n", 93 | "patchMode = \"regular\"\n", 94 | "data = \"images\"\n", 95 | "\n", 96 | "patchImage(shapefilePath=f\"data/train/shapefiles/{size}_{size}/{patchMode}/{patchMode}_sampling_{size}_{size}.geojson\",\n", 97 | " imagePath=\"data/images/RapidEye/2328825_2011-08-13_RE1_3A_Analytic.tif\",\n", 98 | " savePath = f\"data/train/patch_data/non_augmented/{size}_{size}/{patchMode}/{data}\",\n", 99 | " save=True,\n", 100 | " fileName=f\"RapidEye_{size}_{patchMode}\",\n", 101 | " size = size)\n", 102 | "\n", 103 | "data = \"masks\"\n", 104 | "\n", 105 | "\n", 106 | "patchImage(shapefilePath=f\"data/train/shapefiles/{size}_{size}/{patchMode}/{patchMode}_sampling_{size}_{size}.geojson\",\n", 107 | " imagePath=\"data/train/mask/train_mask.tif\",\n", 108 | " savePath = f\"data/train/patch_data/non_augmented/{size}_{size}/{patchMode}/{data}\",\n", 109 | " save=True,\n", 110 | " fileName=f\"RapidEye_{size}_{patchMode}\",\n", 111 | " size = size)" 112 | ] 113 | }, 114 | { 115 | "cell_type": "code", 116 | "execution_count": null, 117 | "metadata": {}, 118 | "outputs": [], 119 | "source": [ 120 | "#Train 32x32 random grid without terrain\n", 121 | "size = 32\n", 122 | "patchMode = \"random\"\n", 123 | "data = \"images\"\n", 124 | "\n", 125 | "patchImage(shapefilePath=f\"data/train/shapefiles/{size}_{size}/{patchMode}/{patchMode}_sampling_{size}_{size}.geojson\",\n", 126 | " imagePath=\"data/images/RapidEye/2328825_2011-08-13_RE1_3A_Analytic.tif\",\n", 127 | " savePath = f\"data/train/patch_data/non_augmented/{size}_{size}/{patchMode}/{data}\",\n", 128 | " save=True,\n", 129 | " fileName=f\"RapidEye_{size}_{patchMode}\",\n", 130 | " size = size)\n", 131 | "\n", 132 | "data = \"masks\"\n", 133 | "\n", 134 | "\n", 135 | "patchImage(shapefilePath=f\"data/train/shapefiles/{size}_{size}/{patchMode}/{patchMode}_sampling_{size}_{size}.geojson\",\n", 136 | " imagePath=\"data/train/mask/train_mask.tif\",\n", 137 | " savePath = f\"data/train/patch_data/non_augmented/{size}_{size}/{patchMode}/{data}\",\n", 138 | " save=True,\n", 139 | " fileName=f\"RapidEye_{size}_{patchMode}\",\n", 140 | " size = size)" 141 | ] 142 | }, 143 | { 144 | "cell_type": "code", 145 | "execution_count": null, 146 | "metadata": {}, 147 | "outputs": [], 148 | "source": [ 149 | "#Train 32x32 regular grid with terain\n", 150 | "size = 32\n", 151 | "patchMode = \"regular\"\n", 152 | "data = \"images\"\n", 153 | "\n", 154 | "patchImage(shapefilePath=f\"data/train/shapefiles/{size}_{size}/{patchMode}/{patchMode}_sampling_{size}_{size}.geojson\",\n", 155 | " imagePath=\"data/images/stack_RapidEye_Alos/RapidEye_and_Alos_Nova_Friburgo.tif\",\n", 156 | " savePath = f\"data/train/patch_data/non_augmented_terrain/{size}_{size}/{patchMode}/{data}\",\n", 157 | " save=True,\n", 158 | " fileName=f\"RapidEye_{size}_{patchMode}\",\n", 159 | " size = size)\n", 160 | "\n", 161 | "data = \"masks\"\n", 162 | "\n", 163 | "\n", 164 | "patchImage(shapefilePath=f\"data/train/shapefiles/{size}_{size}/{patchMode}/{patchMode}_sampling_{size}_{size}.geojson\",\n", 165 | " imagePath=\"data/train/mask/train_mask.tif\",\n", 166 | " savePath = f\"data/train/patch_data/non_augmented_terrain/{size}_{size}/{patchMode}/{data}\",\n", 167 | " save=True,\n", 168 | " fileName=f\"RapidEye_{size}_{patchMode}\",\n", 169 | " size = size)" 170 | ] 171 | }, 172 | { 173 | "cell_type": "code", 174 | "execution_count": null, 175 | "metadata": {}, 176 | "outputs": [], 177 | "source": [ 178 | "#Train 32x32 random grid with terain\n", 179 | "size = 32\n", 180 | "patchMode = \"random\"\n", 181 | "data = \"images\"\n", 182 | "\n", 183 | "patchImage(shapefilePath=f\"data/train/shapefiles/{size}_{size}/{patchMode}/{patchMode}_sampling_{size}_{size}.geojson\",\n", 184 | " imagePath=\"data/images/stack_RapidEye_Alos/RapidEye_and_Alos_Nova_Friburgo.tif\",\n", 185 | " savePath = f\"data/train/patch_data/non_augmented_terrain/{size}_{size}/{patchMode}/{data}\",\n", 186 | " save=True,\n", 187 | " fileName=f\"RapidEye_{size}_{patchMode}\",\n", 188 | " size = size)\n", 189 | "\n", 190 | "data = \"masks\"\n", 191 | "\n", 192 | "\n", 193 | "patchImage(shapefilePath=f\"data/train/shapefiles/{size}_{size}/{patchMode}/{patchMode}_sampling_{size}_{size}.geojson\",\n", 194 | " imagePath=\"data/train/mask/train_mask.tif\",\n", 195 | " savePath = f\"data/train/patch_data/non_augmented_terrain/{size}_{size}/{patchMode}/{data}\",\n", 196 | " save=True,\n", 197 | " fileName=f\"RapidEye_{size}_{patchMode}\",\n", 198 | " size = size)" 199 | ] 200 | }, 201 | { 202 | "cell_type": "code", 203 | "execution_count": null, 204 | "metadata": {}, 205 | "outputs": [], 206 | "source": [ 207 | "#Train 64x64 regular grid without terrain\n", 208 | "size = 64\n", 209 | "patchMode = \"regular\"\n", 210 | "data = \"images\"\n", 211 | "\n", 212 | "patchImage(shapefilePath=f\"data/train/shapefiles/{size}_{size}/{patchMode}/{patchMode}_sampling_{size}_{size}.geojson\",\n", 213 | " imagePath=\"data/images/RapidEye/2328825_2011-08-13_RE1_3A_Analytic.tif\",\n", 214 | " savePath = f\"data/train/patch_data/non_augmented/{size}_{size}/{patchMode}/{data}\",\n", 215 | " save=True,\n", 216 | " fileName=f\"RapidEye_{size}_{patchMode}\",\n", 217 | " size = size)\n", 218 | "\n", 219 | "data = \"masks\"\n", 220 | "\n", 221 | "\n", 222 | "patchImage(shapefilePath=f\"data/train/shapefiles/{size}_{size}/{patchMode}/{patchMode}_sampling_{size}_{size}.geojson\",\n", 223 | " imagePath=\"data/train/mask/train_mask.tif\",\n", 224 | " savePath = f\"data/train/patch_data/non_augmented/{size}_{size}/{patchMode}/{data}\",\n", 225 | " save=True,\n", 226 | " fileName=f\"RapidEye_{size}_{patchMode}\",\n", 227 | " size = size)" 228 | ] 229 | }, 230 | { 231 | "cell_type": "code", 232 | "execution_count": null, 233 | "metadata": {}, 234 | "outputs": [], 235 | "source": [ 236 | "#Train 64x64 random grid without terrain\n", 237 | "size = 64\n", 238 | "patchMode = \"random\"\n", 239 | "data = \"images\"\n", 240 | "\n", 241 | "patchImage(shapefilePath=f\"data/train/shapefiles/{size}_{size}/{patchMode}/{patchMode}_sampling_{size}_{size}.geojson\",\n", 242 | " imagePath=\"data/images/RapidEye/2328825_2011-08-13_RE1_3A_Analytic.tif\",\n", 243 | " savePath = f\"data/train/patch_data/non_augmented/{size}_{size}/{patchMode}/{data}\",\n", 244 | " save=True,\n", 245 | " fileName=f\"RapidEye_{size}_{patchMode}\",\n", 246 | " size = size)\n", 247 | "\n", 248 | "data = \"masks\"\n", 249 | "\n", 250 | "\n", 251 | "patchImage(shapefilePath=f\"data/train/shapefiles/{size}_{size}/{patchMode}/{patchMode}_sampling_{size}_{size}.geojson\",\n", 252 | " imagePath=\"data/train/mask/train_mask.tif\",\n", 253 | " savePath = f\"data/train/patch_data/non_augmented/{size}_{size}/{patchMode}/{data}\",\n", 254 | " save=True,\n", 255 | " fileName=f\"RapidEye_{size}_{patchMode}\",\n", 256 | " size = size)" 257 | ] 258 | }, 259 | { 260 | "cell_type": "code", 261 | "execution_count": null, 262 | "metadata": {}, 263 | "outputs": [], 264 | "source": [ 265 | "#Train 64x64 regular grid with terain\n", 266 | "size = 64\n", 267 | "patchMode = \"regular\"\n", 268 | "data = \"images\"\n", 269 | "\n", 270 | "patchImage(shapefilePath=f\"data/train/shapefiles/{size}_{size}/{patchMode}/{patchMode}_sampling_{size}_{size}.geojson\",\n", 271 | " imagePath=\"data/images/stack_RapidEye_Alos/RapidEye_and_Alos_Nova_Friburgo.tif\",\n", 272 | " savePath = f\"data/train/patch_data/non_augmented_terrain/{size}_{size}/{patchMode}/{data}\",\n", 273 | " save=True,\n", 274 | " fileName=f\"RapidEye_{size}_{patchMode}\",\n", 275 | " size = size)\n", 276 | "\n", 277 | "data = \"masks\"\n", 278 | "\n", 279 | "\n", 280 | "patchImage(shapefilePath=f\"data/train/shapefiles/{size}_{size}/{patchMode}/{patchMode}_sampling_{size}_{size}.geojson\",\n", 281 | " imagePath=\"data/train/mask/train_mask.tif\",\n", 282 | " savePath = f\"data/train/patch_data/non_augmented_terrain/{size}_{size}/{patchMode}/{data}\",\n", 283 | " save=True,\n", 284 | " fileName=f\"RapidEye_{size}_{patchMode}\",\n", 285 | " size = size)" 286 | ] 287 | }, 288 | { 289 | "cell_type": "code", 290 | "execution_count": null, 291 | "metadata": {}, 292 | "outputs": [], 293 | "source": [ 294 | "#Train 64x64 random grid with terain\n", 295 | "size = 64\n", 296 | "patchMode = \"random\"\n", 297 | "data = \"images\"\n", 298 | "\n", 299 | "patchImage(shapefilePath=f\"data/train/shapefiles/{size}_{size}/{patchMode}/{patchMode}_sampling_{size}_{size}.geojson\",\n", 300 | " imagePath=\"data/images/stack_RapidEye_Alos/RapidEye_and_Alos_Nova_Friburgo.tif\",\n", 301 | " savePath = f\"data/train/patch_data/non_augmented_terrain/{size}_{size}/{patchMode}/{data}\",\n", 302 | " save=True,\n", 303 | " fileName=f\"RapidEye_{size}_{patchMode}\",\n", 304 | " size = size)\n", 305 | "\n", 306 | "data = \"masks\"\n", 307 | "\n", 308 | "\n", 309 | "patchImage(shapefilePath=f\"data/train/shapefiles/{size}_{size}/{patchMode}/{patchMode}_sampling_{size}_{size}.geojson\",\n", 310 | " imagePath=\"data/train/mask/train_mask.tif\",\n", 311 | " savePath = f\"data/train/patch_data/non_augmented_terrain/{size}_{size}/{patchMode}/{data}\",\n", 312 | " save=True,\n", 313 | " fileName=f\"RapidEye_{size}_{patchMode}\",\n", 314 | " size = size)" 315 | ] 316 | }, 317 | { 318 | "cell_type": "code", 319 | "execution_count": null, 320 | "metadata": {}, 321 | "outputs": [], 322 | "source": [ 323 | "#Train 128x128 regular grid without terrain\n", 324 | "size = 128\n", 325 | "patchMode = \"regular\"\n", 326 | "data = \"images\"\n", 327 | "\n", 328 | "patchImage(shapefilePath=f\"data/train/shapefiles/{size}_{size}/{patchMode}/{patchMode}_sampling_{size}_{size}.geojson\",\n", 329 | " imagePath=\"data/images/RapidEye/2328825_2011-08-13_RE1_3A_Analytic.tif\",\n", 330 | " savePath = f\"data/train/patch_data/non_augmented/{size}_{size}/{patchMode}/{data}\",\n", 331 | " save=True,\n", 332 | " fileName=f\"RapidEye_{size}_{patchMode}\",\n", 333 | " size = size)\n", 334 | "\n", 335 | "data = \"masks\"\n", 336 | "\n", 337 | "\n", 338 | "patchImage(shapefilePath=f\"data/train/shapefiles/{size}_{size}/{patchMode}/{patchMode}_sampling_{size}_{size}.geojson\",\n", 339 | " imagePath=\"data/train/mask/train_mask.tif\",\n", 340 | " savePath = f\"data/train/patch_data/non_augmented/{size}_{size}/{patchMode}/{data}\",\n", 341 | " save=True,\n", 342 | " fileName=f\"RapidEye_{size}_{patchMode}\",\n", 343 | " size = size)" 344 | ] 345 | }, 346 | { 347 | "cell_type": "code", 348 | "execution_count": null, 349 | "metadata": {}, 350 | "outputs": [], 351 | "source": [ 352 | "#Train 128x128 random grid without terrain\n", 353 | "size = 128\n", 354 | "patchMode = \"random\"\n", 355 | "data = \"images\"\n", 356 | "\n", 357 | "patchImage(shapefilePath=f\"data/train/shapefiles/{size}_{size}/{patchMode}/{patchMode}_sampling_{size}_{size}.geojson\",\n", 358 | " imagePath=\"data/images/RapidEye/2328825_2011-08-13_RE1_3A_Analytic.tif\",\n", 359 | " savePath = f\"data/train/patch_data/non_augmented/{size}_{size}/{patchMode}/{data}\",\n", 360 | " save=True,\n", 361 | " fileName=f\"RapidEye_{size}_{patchMode}\",\n", 362 | " size = size)\n", 363 | "\n", 364 | "data = \"masks\"\n", 365 | "\n", 366 | "\n", 367 | "patchImage(shapefilePath=f\"data/train/shapefiles/{size}_{size}/{patchMode}/{patchMode}_sampling_{size}_{size}.geojson\",\n", 368 | " imagePath=\"data/train/mask/train_mask.tif\",\n", 369 | " savePath = f\"data/train/patch_data/non_augmented/{size}_{size}/{patchMode}/{data}\",\n", 370 | " save=True,\n", 371 | " fileName=f\"RapidEye_{size}_{patchMode}\",\n", 372 | " size = size)" 373 | ] 374 | }, 375 | { 376 | "cell_type": "code", 377 | "execution_count": null, 378 | "metadata": {}, 379 | "outputs": [], 380 | "source": [ 381 | "#Train 128x128 regular grid with terrain\n", 382 | "size = 128\n", 383 | "patchMode = \"regular\"\n", 384 | "data = \"images\"\n", 385 | "\n", 386 | "patchImage(shapefilePath=f\"data/train/shapefiles/{size}_{size}/{patchMode}/{patchMode}_sampling_{size}_{size}.geojson\",\n", 387 | " imagePath=\"data/images/stack_RapidEye_Alos/RapidEye_and_Alos_Nova_Friburgo.tif\",\n", 388 | " savePath = f\"data/train/patch_data/non_augmented_terrain/{size}_{size}/{patchMode}/{data}\",\n", 389 | " save=True,\n", 390 | " fileName=f\"RapidEye_{size}_{patchMode}\",\n", 391 | " size = size)\n", 392 | "\n", 393 | "data = \"masks\"\n", 394 | "\n", 395 | "\n", 396 | "patchImage(shapefilePath=f\"data/train/shapefiles/{size}_{size}/{patchMode}/{patchMode}_sampling_{size}_{size}.geojson\",\n", 397 | " imagePath=\"data/train/mask/train_mask.tif\",\n", 398 | " savePath = f\"data/train/patch_data/non_augmented_terrain/{size}_{size}/{patchMode}/{data}\",\n", 399 | " save=True,\n", 400 | " fileName=f\"RapidEye_{size}_{patchMode}\",\n", 401 | " size = size)" 402 | ] 403 | }, 404 | { 405 | "cell_type": "code", 406 | "execution_count": null, 407 | "metadata": {}, 408 | "outputs": [], 409 | "source": [ 410 | "#Train 128x128 random grid with terrain\n", 411 | "size = 128\n", 412 | "patchMode = \"random\"\n", 413 | "data = \"images\"\n", 414 | "\n", 415 | "patchImage(shapefilePath=f\"data/train/shapefiles/{size}_{size}/{patchMode}/{patchMode}_sampling_{size}_{size}.geojson\",\n", 416 | " imagePath=\"data/images/stack_RapidEye_Alos/RapidEye_and_Alos_Nova_Friburgo.tif\",\n", 417 | " savePath = f\"data/train/patch_data/non_augmented_terrain/{size}_{size}/{patchMode}/{data}\",\n", 418 | " save=True,\n", 419 | " fileName=f\"RapidEye_{size}_{patchMode}\",\n", 420 | " size = size)\n", 421 | "\n", 422 | "data = \"masks\"\n", 423 | "\n", 424 | "\n", 425 | "patchImage(shapefilePath=f\"data/train/shapefiles/{size}_{size}/{patchMode}/{patchMode}_sampling_{size}_{size}.geojson\",\n", 426 | " imagePath=\"data/train/mask/train_mask.tif\",\n", 427 | " savePath = f\"data/train/patch_data/non_augmented_terrain/{size}_{size}/{patchMode}/{data}\",\n", 428 | " save=True,\n", 429 | " fileName=f\"RapidEye_{size}_{patchMode}\",\n", 430 | " size = size)" 431 | ] 432 | }, 433 | { 434 | "cell_type": "code", 435 | "execution_count": null, 436 | "metadata": {}, 437 | "outputs": [], 438 | "source": [] 439 | } 440 | ], 441 | "metadata": { 442 | "kernelspec": { 443 | "display_name": "Python 3", 444 | "language": "python", 445 | "name": "python3" 446 | }, 447 | "language_info": { 448 | "codemirror_mode": { 449 | "name": "ipython", 450 | "version": 3 451 | }, 452 | "file_extension": ".py", 453 | "mimetype": "text/x-python", 454 | "name": "python", 455 | "nbconvert_exporter": "python", 456 | "pygments_lexer": "ipython3", 457 | "version": "3.7.7" 458 | } 459 | }, 460 | "nbformat": 4, 461 | "nbformat_minor": 2 462 | } 463 | -------------------------------------------------------------------------------- /notebooks/4_load_images_as_arrays.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Code used to load the .tif images as arrays" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": null, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "from utils import *" 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": null, 22 | "metadata": {}, 23 | "outputs": [], 24 | "source": [ 25 | "#Function to convert the images to arrays (each channel was normalized (values between 0 - 1) individualy)\n", 26 | "# The function get_non_zero_files double check if the data still have masks and images without the positive class.\n", 27 | "# If they still exists, the function will delete those files. \n", 28 | "\n", 29 | "def Image_to_Array(imagesFolder, maskFolder,saveFolder,saveFileNameX, saveFileNameY,size):\n", 30 | " \"\"\"Functions that converts .tif images from a folder to a numpy array.\n", 31 | " \n", 32 | " # Parameters:\n", 33 | " \n", 34 | " imagesFolder (string) = Path to the folder where the image files are located.\n", 35 | " \n", 36 | " maskFolder (string) = Path to the folder where the mask files are located.\n", 37 | " \n", 38 | " saveFolder (string) = Path to the folder where the array files will be saved.\n", 39 | " \n", 40 | " saveFileNameX (string) = Name of the array file that will contain the images.\n", 41 | " \n", 42 | " saveFileNameY (string) = Name of the array file that will contain the labels.\n", 43 | " \n", 44 | " size (int) = size of the desired width and height of the images.\n", 45 | " \"\"\"\n", 46 | " # Add the variables\n", 47 | " print(\"Loading Images.... \")\n", 48 | " imagesFolder = imagesFolder\n", 49 | " maskFolder = maskFolder\n", 50 | " saveArrayFolder = saveFolder +\"/\"\n", 51 | " saveFileNameX = saveFileNameX\n", 52 | " size = size\n", 53 | " # get the files from a folder\n", 54 | " list_of_images = get_list_file_names(imagesFolder)\n", 55 | " \n", 56 | " # Confirm if the sizes of the images and masks in a folder are the same\n", 57 | " print(\"#\"*15 +\"Asserting the dimension of the images\" + \"#\"*15)\n", 58 | " images, masks = get_list_of_images_and_masks_with_same_dimension(list_of_images, images_path =imagesFolder +\"/\" ,masks_path = maskFolder+\"/\", size = size)\n", 59 | " #Remove masks with only 0(background) values\n", 60 | " images, masks = get_nonzero_files(images,masks)\n", 61 | " #Normalize each channel of the image\n", 62 | " print(\"#\"*15 +\"Normalizing Images\" + \"#\"*15)\n", 63 | " for i in range(images.shape[3]):\n", 64 | " print(\"Max Value Band {} - Before Normalization: {}\".format(i,images[:,:,:,i].max()))\n", 65 | " images[:,:,:,i] = images[:,:,:,i]/images[:,:,:,i].max()\n", 66 | " print(\"Max Value Band {} - After Normalization: {}\".format(i,images[:,:,:,i].max()))\n", 67 | " #Normalize each channel of the mask\n", 68 | " print(\"#\"*15 +\"Normalizing Masks\" + \"#\"*15)\n", 69 | " for i in range(masks.shape[3]):\n", 70 | " print(\"Max Value Band {} - Before Normalization: {}\".format(i,masks[:,:,:,i].max()))\n", 71 | " masks[:,:,:,i] = masks[:,:,:,i]/masks[:,:,:,i].max()\n", 72 | " print(\"Max Value Band {} - After Normalization: {}\".format(i,masks[:,:,:,i].max()))\n", 73 | " print(\"#\"*15 +\"saving images array\" + \"#\"*15)\n", 74 | " save_array(images, saveFileNameX, saveArrayFolder)\n", 75 | " print(\"#\"*15 +\"saving masks array\" + \"#\"*15)\n", 76 | " save_array(masks, saveFileNameY, saveArrayFolder)\n", 77 | " " 78 | ] 79 | }, 80 | { 81 | "cell_type": "code", 82 | "execution_count": null, 83 | "metadata": {}, 84 | "outputs": [], 85 | "source": [ 86 | "# Random Grid - 32x32 - non augmented\n", 87 | "\n", 88 | "patchSize = 32\n", 89 | "patchMode = \"random\"\n", 90 | "\n", 91 | "\n", 92 | "imagesFolder = f\"data/train/patch_data/non_augmented/{patchSize}_{patchSize}/{patchMode}/images\"\n", 93 | "maskFolder = f\"data/train/patch_data/non_augmented/{patchSize}_{patchSize}/{patchMode}/masks\"\n", 94 | "saveFolder = f\"data/train/patch_data/non_augmented/{patchSize}_{patchSize}/{patchMode}/arrays\"\n", 95 | "saveFileNameX = f\"X_train_{patchSize}_{patchMode}\"\n", 96 | "saveFileNameY = f\"Y_train_{patchSize}_{patchMode}\"\n", 97 | "size = patchSize\n", 98 | "Image_to_Array(imagesFolder=imagesFolder,\n", 99 | " maskFolder=maskFolder,\n", 100 | " saveFolder=saveFolder,\n", 101 | " saveFileNameX=saveFileNameX,\n", 102 | " saveFileNameY=saveFileNameY,\n", 103 | " size=size)\n", 104 | "\n", 105 | "# Regular Grid - 32x32 - non augmented\n", 106 | "\n", 107 | "patchMode = \"regular\"\n", 108 | "\n", 109 | "\n", 110 | "imagesFolder = f\"data/train/patch_data/non_augmented/{patchSize}_{patchSize}/{patchMode}/images\"\n", 111 | "maskFolder = f\"data/train/patch_data/non_augmented/{patchSize}_{patchSize}/{patchMode}/masks\"\n", 112 | "saveFolder = f\"data/train/patch_data/non_augmented/{patchSize}_{patchSize}/{patchMode}/arrays\"\n", 113 | "saveFileNameX = f\"X_train_{patchSize}_{patchMode}\"\n", 114 | "saveFileNameY = f\"Y_train_{patchSize}_{patchMode}\"\n", 115 | "size = patchSize\n", 116 | "Image_to_Array(imagesFolder=imagesFolder,\n", 117 | " maskFolder=maskFolder,\n", 118 | " saveFolder=saveFolder,\n", 119 | " saveFileNameX=saveFileNameX,\n", 120 | " saveFileNameY=saveFileNameY,\n", 121 | " size=size)" 122 | ] 123 | }, 124 | { 125 | "cell_type": "code", 126 | "execution_count": null, 127 | "metadata": {}, 128 | "outputs": [], 129 | "source": [ 130 | "# Random Grid - 32x32 - non augmented terrain\n", 131 | "\n", 132 | "patchSize = 32\n", 133 | "patchMode = \"random\"\n", 134 | "\n", 135 | "\n", 136 | "imagesFolder = f\"data/train/patch_data/non_augmented_terrain/{patchSize}_{patchSize}/{patchMode}/images\"\n", 137 | "maskFolder = f\"data/train/patch_data/non_augmented_terrain/{patchSize}_{patchSize}/{patchMode}/masks\"\n", 138 | "saveFolder = f\"data/train/patch_data/non_augmented_terrain/{patchSize}_{patchSize}/{patchMode}/arrays\"\n", 139 | "saveFileName = f\"X_train_{patchSize}_{patchMode}\"\n", 140 | "size = patchSize\n", 141 | "saveFileNameX = f\"X_train_{patchSize}_{patchMode}\"\n", 142 | "saveFileNameY = f\"Y_train_{patchSize}_{patchMode}\"\n", 143 | "Image_to_Array(imagesFolder=imagesFolder,\n", 144 | " maskFolder=maskFolder,\n", 145 | " saveFolder=saveFolder,\n", 146 | " saveFileNameX=saveFileNameX,\n", 147 | " saveFileNameY=saveFileNameY,\n", 148 | " size=size)\n", 149 | "\n", 150 | "# Regular Grid - 32x32 - non augmented terrain\n", 151 | "\n", 152 | "patchMode = \"regular\"\n", 153 | "\n", 154 | "\n", 155 | "imagesFolder = f\"data/train/patch_data/non_augmented_terrain/{patchSize}_{patchSize}/{patchMode}/images\"\n", 156 | "maskFolder = f\"data/train/patch_data/non_augmented_terrain/{patchSize}_{patchSize}/{patchMode}/masks\"\n", 157 | "saveFolder = f\"data/train/patch_data/non_augmented_terrain/{patchSize}_{patchSize}/{patchMode}/arrays\"\n", 158 | "size = patchSize\n", 159 | "saveFileNameX = f\"X_train_{patchSize}_{patchMode}\"\n", 160 | "saveFileNameY = f\"Y_train_{patchSize}_{patchMode}\"\n", 161 | "Image_to_Array(imagesFolder=imagesFolder,\n", 162 | " maskFolder=maskFolder,\n", 163 | " saveFolder=saveFolder,\n", 164 | " saveFileNameX=saveFileNameX,\n", 165 | " saveFileNameY=saveFileNameY,\n", 166 | " size=size)" 167 | ] 168 | }, 169 | { 170 | "cell_type": "code", 171 | "execution_count": null, 172 | "metadata": {}, 173 | "outputs": [], 174 | "source": [ 175 | "# Random Grid - 64x64 - non augmented\n", 176 | "\n", 177 | "patchSize = 64\n", 178 | "patchMode = \"random\"\n", 179 | "\n", 180 | "\n", 181 | "imagesFolder = f\"data/train/patch_data/non_augmented/{patchSize}_{patchSize}/{patchMode}/images\"\n", 182 | "maskFolder = f\"data/train/patch_data/non_augmented/{patchSize}_{patchSize}/{patchMode}/masks\"\n", 183 | "saveFolder = f\"data/train/patch_data/non_augmented/{patchSize}_{patchSize}/{patchMode}/arrays\"\n", 184 | "size = patchSize\n", 185 | "saveFileNameX = f\"X_train_{patchSize}_{patchMode}\"\n", 186 | "saveFileNameY = f\"Y_train_{patchSize}_{patchMode}\"\n", 187 | "Image_to_Array(imagesFolder=imagesFolder,\n", 188 | " maskFolder=maskFolder,\n", 189 | " saveFolder=saveFolder,\n", 190 | " saveFileNameX=saveFileNameX,\n", 191 | " saveFileNameY=saveFileNameY,\n", 192 | " size=size)\n", 193 | "\n", 194 | "# Regular Grid - 64x64 - non augmented\n", 195 | "\n", 196 | "patchMode = \"regular\"\n", 197 | "\n", 198 | "\n", 199 | "imagesFolder = f\"data/train/patch_data/non_augmented/{patchSize}_{patchSize}/{patchMode}/images\"\n", 200 | "maskFolder = f\"data/train/patch_data/non_augmented/{patchSize}_{patchSize}/{patchMode}/masks\"\n", 201 | "saveFolder = f\"data/train/patch_data/non_augmented/{patchSize}_{patchSize}/{patchMode}/arrays\"\n", 202 | "size = patchSize\n", 203 | "saveFileNameX = f\"X_train_{patchSize}_{patchMode}\"\n", 204 | "saveFileNameY = f\"Y_train_{patchSize}_{patchMode}\"\n", 205 | "Image_to_Array(imagesFolder=imagesFolder,\n", 206 | " maskFolder=maskFolder,\n", 207 | " saveFolder=saveFolder,\n", 208 | " saveFileNameX=saveFileNameX,\n", 209 | " saveFileNameY=saveFileNameY,\n", 210 | " size=size)" 211 | ] 212 | }, 213 | { 214 | "cell_type": "code", 215 | "execution_count": null, 216 | "metadata": {}, 217 | "outputs": [], 218 | "source": [ 219 | "# Random Grid - 64x64 - non augmented terrain\n", 220 | "\n", 221 | "patchSize = 64\n", 222 | "patchMode = \"random\"\n", 223 | "\n", 224 | "\n", 225 | "imagesFolder = f\"data/train/patch_data/non_augmented_terrain/{patchSize}_{patchSize}/{patchMode}/images\"\n", 226 | "maskFolder = f\"data/train/patch_data/non_augmented_terrain/{patchSize}_{patchSize}/{patchMode}/masks\"\n", 227 | "saveFolder = f\"data/train/patch_data/non_augmented_terrain/{patchSize}_{patchSize}/{patchMode}/arrays\"\n", 228 | "size = patchSize\n", 229 | "saveFileNameX = f\"X_train_{patchSize}_{patchMode}\"\n", 230 | "saveFileNameY = f\"Y_train_{patchSize}_{patchMode}\"\n", 231 | "Image_to_Array(imagesFolder=imagesFolder,\n", 232 | " maskFolder=maskFolder,\n", 233 | " saveFolder=saveFolder,\n", 234 | " saveFileNameX=saveFileNameX,\n", 235 | " saveFileNameY=saveFileNameY,\n", 236 | " size=size)\n", 237 | "\n", 238 | "# Regular Grid - 64x64 - non augmented terrain\n", 239 | "\n", 240 | "patchMode = \"regular\"\n", 241 | "\n", 242 | "\n", 243 | "imagesFolder = f\"data/train/patch_data/non_augmented_terrain/{patchSize}_{patchSize}/{patchMode}/images\"\n", 244 | "maskFolder = f\"data/train/patch_data/non_augmented_terrain/{patchSize}_{patchSize}/{patchMode}/masks\"\n", 245 | "saveFolder = f\"data/train/patch_data/non_augmented_terrain/{patchSize}_{patchSize}/{patchMode}/arrays\"\n", 246 | "saveFileNameX = f\"X_train_{patchSize}_{patchMode}\"\n", 247 | "saveFileNameY = f\"Y_train_{patchSize}_{patchMode}\"\n", 248 | "size = patchSize\n", 249 | "Image_to_Array(imagesFolder=imagesFolder,\n", 250 | " maskFolder=maskFolder,\n", 251 | " saveFolder=saveFolder,\n", 252 | " saveFileNameX=saveFileNameX,\n", 253 | " saveFileNameY=saveFileNameY,\n", 254 | " size=size)" 255 | ] 256 | }, 257 | { 258 | "cell_type": "code", 259 | "execution_count": null, 260 | "metadata": {}, 261 | "outputs": [], 262 | "source": [ 263 | "# Random Grid - 128x128 - non augmented\n", 264 | "\n", 265 | "patchSize = 128\n", 266 | "patchMode = \"random\"\n", 267 | "\n", 268 | "\n", 269 | "imagesFolder = f\"data/train/patch_data/non_augmented/{patchSize}_{patchSize}/{patchMode}/images\"\n", 270 | "maskFolder = f\"data/train/patch_data/non_augmented/{patchSize}_{patchSize}/{patchMode}/masks\"\n", 271 | "saveFolder = f\"data/train/patch_data/non_augmented/{patchSize}_{patchSize}/{patchMode}/arrays\"\n", 272 | "size = patchSize\n", 273 | "saveFileNameX = f\"X_train_{patchSize}_{patchMode}\"\n", 274 | "saveFileNameY = f\"Y_train_{patchSize}_{patchMode}\"\n", 275 | "Image_to_Array(imagesFolder=imagesFolder,\n", 276 | " maskFolder=maskFolder,\n", 277 | " saveFolder=saveFolder,\n", 278 | " saveFileNameX=saveFileNameX,\n", 279 | " saveFileNameY = saveFileNameY,\n", 280 | " size=size)\n", 281 | "\n", 282 | "# Regular Grid - 128x128 - non augmented\n", 283 | "\n", 284 | "patchMode = \"regular\"\n", 285 | "\n", 286 | "\n", 287 | "imagesFolder = f\"data/train/patch_data/non_augmented/{patchSize}_{patchSize}/{patchMode}/images\"\n", 288 | "maskFolder = f\"data/train/patch_data/non_augmented/{patchSize}_{patchSize}/{patchMode}/masks\"\n", 289 | "saveFolder = f\"data/train/patch_data/non_augmented/{patchSize}_{patchSize}/{patchMode}/arrays\"\n", 290 | "size = patchSize\n", 291 | "saveFileNameX = f\"X_train_{patchSize}_{patchMode}\"\n", 292 | "saveFileNameY = f\"Y_train_{patchSize}_{patchMode}\"\n", 293 | "Image_to_Array(imagesFolder=imagesFolder,\n", 294 | " maskFolder=maskFolder,\n", 295 | " saveFolder=saveFolder,\n", 296 | " saveFileNameX=saveFileNameX,\n", 297 | " saveFileNameY = saveFileNameY,\n", 298 | " size=size)" 299 | ] 300 | }, 301 | { 302 | "cell_type": "code", 303 | "execution_count": null, 304 | "metadata": {}, 305 | "outputs": [], 306 | "source": [ 307 | "# Random Grid - 128x128 - non augmented terrain\n", 308 | "\n", 309 | "patchSize = 128\n", 310 | "patchMode = \"random\"\n", 311 | "\n", 312 | "\n", 313 | "imagesFolder = f\"data/train/patch_data/non_augmented_terrain/{patchSize}_{patchSize}/{patchMode}/images\"\n", 314 | "maskFolder = f\"data/train/patch_data/non_augmented_terrain/{patchSize}_{patchSize}/{patchMode}/masks\"\n", 315 | "saveFolder = f\"data/train/patch_data/non_augmented_terrain/{patchSize}_{patchSize}/{patchMode}/arrays\"\n", 316 | "size = patchSize\n", 317 | "saveFileNameX = f\"X_train_{patchSize}_{patchMode}\"\n", 318 | "saveFileNameY = f\"Y_train_{patchSize}_{patchMode}\"\n", 319 | "Image_to_Array(imagesFolder=imagesFolder,\n", 320 | " maskFolder=maskFolder,\n", 321 | " saveFolder=saveFolder,\n", 322 | " saveFileNameX=saveFileNameX,\n", 323 | " saveFileNameY=saveFileNameY,\n", 324 | " size=size)\n", 325 | "\n", 326 | "# Regular Grid - 128x128 - non augmented terrain\n", 327 | "\n", 328 | "patchMode = \"regular\"\n", 329 | "\n", 330 | "\n", 331 | "imagesFolder = f\"data/train/patch_data/non_augmented_terrain/{patchSize}_{patchSize}/{patchMode}/images\"\n", 332 | "maskFolder = f\"data/train/patch_data/non_augmented_terrain/{patchSize}_{patchSize}/{patchMode}/masks\"\n", 333 | "saveFolder = f\"data/train/patch_data/non_augmented_terrain/{patchSize}_{patchSize}/{patchMode}/arrays\"\n", 334 | "saveFileNameX = f\"X_train_{patchSize}_{patchMode}\"\n", 335 | "saveFileNameY = f\"Y_train_{patchSize}_{patchMode}\"\n", 336 | "size = patchSize\n", 337 | "Image_to_Array(imagesFolder=imagesFolder,\n", 338 | " maskFolder=maskFolder,\n", 339 | " saveFolder=saveFolder,\n", 340 | " saveFileNameX=saveFileNameX,\n", 341 | " saveFileNameY=saveFileNameY,\n", 342 | " size=size)" 343 | ] 344 | }, 345 | { 346 | "cell_type": "code", 347 | "execution_count": null, 348 | "metadata": {}, 349 | "outputs": [], 350 | "source": [ 351 | "# Teste area 1 \n", 352 | "\n", 353 | "patchSize = 1024\n", 354 | "\n", 355 | "\n", 356 | "imagesFolder = f\"data/test/test_without_terrain/test_1/image\"\n", 357 | "maskFolder = f\"data/test/test_without_terrain/test_1/mask\"\n", 358 | "saveFolder = f\"data/test/test_without_terrain/test_1/arrays\"\n", 359 | "size = patchSize\n", 360 | "saveFileNameX = f\"X_test_area_1\"\n", 361 | "saveFileNameY = f\"Y_test_area_1\"\n", 362 | "Image_to_Array(imagesFolder=imagesFolder,\n", 363 | " maskFolder=maskFolder,\n", 364 | " saveFolder=saveFolder,\n", 365 | " saveFileNameX=saveFileNameX,\n", 366 | " saveFileNameY=saveFileNameY,\n", 367 | " size=size)\n", 368 | "\n", 369 | "# Test Area 1 with terrain\n", 370 | "\n", 371 | "patchSize = 1024\n", 372 | "\n", 373 | "\n", 374 | "imagesFolder = f\"data/test/test_with_terrain/test_1/images\"\n", 375 | "maskFolder = f\"data/test/test_with_terrain/test_1/mask\"\n", 376 | "saveFolder = f\"data/test/test_with_terrain/test_1/arrays\"\n", 377 | "size = patchSize\n", 378 | "saveFileNameX = f\"X_test_area_1\"\n", 379 | "saveFileNameY = f\"Y_test_area_1\"\n", 380 | "Image_to_Array(imagesFolder=imagesFolder,\n", 381 | " maskFolder=maskFolder,\n", 382 | " saveFolder=saveFolder,\n", 383 | " saveFileNameX=saveFileNameX,\n", 384 | " saveFileNameY=saveFileNameY,\n", 385 | " size=size)" 386 | ] 387 | }, 388 | { 389 | "cell_type": "code", 390 | "execution_count": null, 391 | "metadata": {}, 392 | "outputs": [], 393 | "source": [ 394 | "# Teste area 2 \n", 395 | "\n", 396 | "patchSize = 1024\n", 397 | "\n", 398 | "\n", 399 | "imagesFolder = f\"data/test/test_without_terrain/test_2/image\"\n", 400 | "maskFolder = f\"data/test/test_without_terrain/test_2/mask\"\n", 401 | "saveFolder = f\"data/test/test_without_terrain/test_2/arrays\"\n", 402 | "size = patchSize\n", 403 | "saveFileNameX = f\"X_test_area_2\"\n", 404 | "saveFileNameY = f\"Y_test_area_2\"\n", 405 | "Image_to_Array(imagesFolder=imagesFolder,\n", 406 | " maskFolder=maskFolder,\n", 407 | " saveFolder=saveFolder,\n", 408 | " saveFileNameX=saveFileNameX,\n", 409 | " saveFileNameY=saveFileNameY,\n", 410 | " size=size)\n", 411 | "\n", 412 | "# Test Area 2 with terrain\n", 413 | "\n", 414 | "patchSize = 1024\n", 415 | "\n", 416 | "\n", 417 | "imagesFolder = f\"data/test/test_with_terrain/test_2/images\"\n", 418 | "maskFolder = f\"data/test/test_with_terrain/test_2/mask\"\n", 419 | "saveFolder = f\"data/test/test_with_terrain/test_2/arrays\"\n", 420 | "size = patchSize\n", 421 | "saveFileNameX = f\"X_test_area_2\"\n", 422 | "saveFileNameY = f\"Y_test_area_2\"\n", 423 | "Image_to_Array(imagesFolder=imagesFolder,\n", 424 | " maskFolder=maskFolder,\n", 425 | " saveFolder=saveFolder,\n", 426 | " saveFileNameX=saveFileNameX,\n", 427 | " saveFileNameY=saveFileNameY,\n", 428 | " size=size)" 429 | ] 430 | }, 431 | { 432 | "cell_type": "code", 433 | "execution_count": null, 434 | "metadata": {}, 435 | "outputs": [], 436 | "source": [] 437 | } 438 | ], 439 | "metadata": { 440 | "kernelspec": { 441 | "display_name": "Python 3", 442 | "language": "python", 443 | "name": "python3" 444 | }, 445 | "language_info": { 446 | "codemirror_mode": { 447 | "name": "ipython", 448 | "version": 3 449 | }, 450 | "file_extension": ".py", 451 | "mimetype": "text/x-python", 452 | "name": "python", 453 | "nbconvert_exporter": "python", 454 | "pygments_lexer": "ipython3", 455 | "version": "3.7.7" 456 | } 457 | }, 458 | "nbformat": 4, 459 | "nbformat_minor": 2 460 | } 461 | -------------------------------------------------------------------------------- /notebooks/5_data_augmentation.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Code used to augmented the dataset\n", 8 | "\n", 9 | "Data were augmented with:\n", 10 | "\n", 11 | "- Horizontal Flips;\n", 12 | "\n", 13 | "- Vertical Flips;\n", 14 | "\n", 15 | "- Random rotations around 90 degrees." 16 | ] 17 | }, 18 | { 19 | "cell_type": "code", 20 | "execution_count": null, 21 | "metadata": {}, 22 | "outputs": [], 23 | "source": [ 24 | "#import libraries\n", 25 | "%matplotlib inline\n", 26 | "import numpy as np\n", 27 | "from matplotlib import pyplot as plt\n", 28 | "from albumentations import (\n", 29 | " PadIfNeeded,\n", 30 | " HorizontalFlip,\n", 31 | " VerticalFlip, \n", 32 | " CenterCrop, \n", 33 | " Crop,\n", 34 | " Compose,\n", 35 | " ChannelShuffle,\n", 36 | " Rotate,\n", 37 | " Transpose,\n", 38 | " RandomRotate90,\n", 39 | " ElasticTransform,\n", 40 | " GridDistortion, \n", 41 | " OpticalDistortion,\n", 42 | " RandomSizedCrop,\n", 43 | " OneOf,\n", 44 | " CLAHE,\n", 45 | " RandomBrightnessContrast, \n", 46 | " RandomGamma \n", 47 | ")\n", 48 | "from sklearn.model_selection import train_test_split" 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "execution_count": null, 54 | "metadata": {}, 55 | "outputs": [], 56 | "source": [ 57 | "# Augmentation 32x32 - random\n", 58 | "\n", 59 | "# Define the patch size that will be loaded\n", 60 | "patchSize = 32\n", 61 | "# Define the patch mode\n", 62 | "patchMode = \"random\"\n", 63 | "\n", 64 | "# Load the data\n", 65 | "X_data = np.load(f\"data/train/patch_data/non_augmented/{patchSize}_{patchSize}/{patchMode}/arrays/X_train_{patchSize}_{patchMode}.npy\")\n", 66 | "Y_data = np.load(f\"data/train/patch_data/non_augmented/{patchSize}_{patchSize}/{patchMode}/arrays/Y_train_{patchSize}_{patchMode}.npy\")\n", 67 | "\n", 68 | "# Split 30% of the validation data before the augmentation\n", 69 | "X_train, X_val, Y_train, Y_val = train_test_split(X_data,Y_data, test_size=0.3, random_state = 40)\n", 70 | "\n", 71 | "# Horizontal flip\n", 72 | "aug = HorizontalFlip(p=1)\n", 73 | "augmented = aug(image=X_train, mask=Y_train)\n", 74 | "image_h_flipped = augmented['image']\n", 75 | "mask_h_flipped = augmented['mask']\n", 76 | "\n", 77 | "# Vertical flip\n", 78 | "aug = VerticalFlip(p=1)\n", 79 | "augmented = aug(image=X_train, mask=Y_train)\n", 80 | "image_v_flipped = augmented['image']\n", 81 | "mask_v_flipped = augmented['mask']\n", 82 | "\n", 83 | "# Random Rotation around 90\n", 84 | "aug = RandomRotate90(p=1)\n", 85 | "augmented = aug(image=X_train, mask=Y_train)\n", 86 | "image_rot90 = augmented['image']\n", 87 | "mask_rot90 = augmented['mask']\n", 88 | "\n", 89 | "\n", 90 | "# Stack the results\n", 91 | "X_train_aug = np.vstack((X_train,image_h_flipped,image_v_flipped,image_rot90))\n", 92 | "Y_train_aug = np.vstack((Y_train,mask_h_flipped,mask_v_flipped,mask_rot90))\n", 93 | "\n", 94 | "# Save augmented training data\n", 95 | "np.save(f\"data/train/patch_data/augmented/{patchSize}_{patchSize}/{patchMode}/arrays/X_train_{patchSize}_{patchMode}_aug.npy\",X_train_aug)\n", 96 | "np.save(f\"data/train/patch_data/augmented/{patchSize}_{patchSize}/{patchMode}/arrays/Y_train_{patchSize}_{patchMode}.npy\",Y_train_aug)\n", 97 | "\n", 98 | "# Save validation data \n", 99 | "np.save(f\"data/train/patch_data/augmented/{patchSize}_{patchSize}/{patchMode}/arrays/X_val.npy\",X_val)\n", 100 | "np.save(f\"data/train/patch_data/augmented/{patchSize}_{patchSize}/{patchMode}/arrays/X_val.npy\",Y_val)" 101 | ] 102 | }, 103 | { 104 | "cell_type": "code", 105 | "execution_count": null, 106 | "metadata": {}, 107 | "outputs": [], 108 | "source": [ 109 | "# Augmentation 32x32 - regular\n", 110 | "\n", 111 | "# Define the patch size that will be loaded\n", 112 | "patchSize = 32\n", 113 | "# Define the patch mode\n", 114 | "patchMode = \"regular\"\n", 115 | "\n", 116 | "# Load the data\n", 117 | "X_data = np.load(f\"data/train/patch_data/non_augmented/{patchSize}_{patchSize}/{patchMode}/arrays/X_train_{patchSize}_{patchMode}.npy\")\n", 118 | "Y_data = np.load(f\"data/train/patch_data/non_augmented/{patchSize}_{patchSize}/{patchMode}/arrays/Y_train_{patchSize}_{patchMode}.npy\")\n", 119 | "\n", 120 | "# Split 30% of the validation data before the augmentation\n", 121 | "X_train, X_val, Y_train, Y_val = train_test_split(X_data,Y_data, test_size=0.3, random_state = 40)\n", 122 | "\n", 123 | "# Horizontal flip\n", 124 | "aug = HorizontalFlip(p=1)\n", 125 | "augmented = aug(image=X_train, mask=Y_train)\n", 126 | "image_h_flipped = augmented['image']\n", 127 | "mask_h_flipped = augmented['mask']\n", 128 | "\n", 129 | "# Vertical flip\n", 130 | "aug = VerticalFlip(p=1)\n", 131 | "augmented = aug(image=X_train, mask=Y_train)\n", 132 | "image_v_flipped = augmented['image']\n", 133 | "mask_v_flipped = augmented['mask']\n", 134 | "\n", 135 | "# Random Rotation around 90\n", 136 | "aug = RandomRotate90(p=1)\n", 137 | "augmented = aug(image=X_train, mask=Y_train)\n", 138 | "image_rot90 = augmented['image']\n", 139 | "mask_rot90 = augmented['mask']\n", 140 | "\n", 141 | "\n", 142 | "# Stack the results\n", 143 | "X_train_aug = np.vstack((X_train,image_h_flipped,image_v_flipped,image_rot90))\n", 144 | "Y_train_aug = np.vstack((Y_train,mask_h_flipped,mask_v_flipped,mask_rot90))\n", 145 | "\n", 146 | "# Save augmented training data\n", 147 | "np.save(f\"data/train/patch_data/augmented/{patchSize}_{patchSize}/{patchMode}/arrays/X_train_{patchSize}_{patchMode}_aug.npy\",X_train_aug)\n", 148 | "np.save(f\"data/train/patch_data/augmented/{patchSize}_{patchSize}/{patchMode}/arrays/Y_train_{patchSize}_{patchMode}.npy\",Y_train_aug)\n", 149 | "\n", 150 | "# Save validation data \n", 151 | "np.save(f\"data/train/patch_data/augmented/{patchSize}_{patchSize}/{patchMode}/arrays/X_val.npy\",X_val)\n", 152 | "np.save(f\"data/train/patch_data/augmented/{patchSize}_{patchSize}/{patchMode}/arrays/X_val.npy\",Y_val)" 153 | ] 154 | }, 155 | { 156 | "cell_type": "code", 157 | "execution_count": null, 158 | "metadata": {}, 159 | "outputs": [], 160 | "source": [ 161 | "# Augmentation 32x32 - random terrain\n", 162 | "\n", 163 | "# Define the patch size that will be loaded\n", 164 | "patchSize = 32\n", 165 | "# Define the patch mode\n", 166 | "patchMode = \"random\"\n", 167 | "\n", 168 | "# Load the data\n", 169 | "X_data = np.load(f\"data/train/patch_data/non_augmented_terrain/{patchSize}_{patchSize}/{patchMode}/arrays/X_train_{patchSize}_{patchMode}.npy\")\n", 170 | "Y_data = np.load(f\"data/train/patch_data/non_augmented_terrain/{patchSize}_{patchSize}/{patchMode}/arrays/Y_train_{patchSize}_{patchMode}.npy\")\n", 171 | "\n", 172 | "# Split 30% of the validation data before the augmentation\n", 173 | "X_train, X_val, Y_train, Y_val = train_test_split(X_data,Y_data, test_size=0.3, random_state = 40)\n", 174 | "\n", 175 | "# Horizontal flip\n", 176 | "aug = HorizontalFlip(p=1)\n", 177 | "augmented = aug(image=X_train, mask=Y_train)\n", 178 | "image_h_flipped = augmented['image']\n", 179 | "mask_h_flipped = augmented['mask']\n", 180 | "\n", 181 | "# Vertical flip\n", 182 | "aug = VerticalFlip(p=1)\n", 183 | "augmented = aug(image=X_train, mask=Y_train)\n", 184 | "image_v_flipped = augmented['image']\n", 185 | "mask_v_flipped = augmented['mask']\n", 186 | "\n", 187 | "# Random Rotation around 90\n", 188 | "aug = RandomRotate90(p=1)\n", 189 | "augmented = aug(image=X_train, mask=Y_train)\n", 190 | "image_rot90 = augmented['image']\n", 191 | "mask_rot90 = augmented['mask']\n", 192 | "\n", 193 | "\n", 194 | "# Stack the results\n", 195 | "X_train_aug = np.vstack((X_train,image_h_flipped,image_v_flipped,image_rot90))\n", 196 | "Y_train_aug = np.vstack((Y_train,mask_h_flipped,mask_v_flipped,mask_rot90))\n", 197 | "\n", 198 | "# Save augmented training data\n", 199 | "np.save(f\"data/train/patch_data/augmented_terrain/{patchSize}_{patchSize}/{patchMode}/arrays/X_train_{patchSize}_{patchMode}_aug.npy\",X_train_aug)\n", 200 | "np.save(f\"data/train/patch_data/augmented_terrain/{patchSize}_{patchSize}/{patchMode}/arrays/Y_train_{patchSize}_{patchMode}.npy\",Y_train_aug)\n", 201 | "\n", 202 | "# Save validation data \n", 203 | "np.save(f\"data/train/patch_data/augmented_terrain/{patchSize}_{patchSize}/{patchMode}/arrays/X_val.npy\",X_val)\n", 204 | "np.save(f\"data/train/patch_data/augmented_terrain/{patchSize}_{patchSize}/{patchMode}/arrays/X_val.npy\",Y_val)" 205 | ] 206 | }, 207 | { 208 | "cell_type": "code", 209 | "execution_count": null, 210 | "metadata": {}, 211 | "outputs": [], 212 | "source": [ 213 | "# Augmentation 32x32 - regular terrain\n", 214 | "\n", 215 | "# Define the patch size that will be loaded\n", 216 | "patchSize = 32\n", 217 | "# Define the patch mode\n", 218 | "patchMode = \"regular\"\n", 219 | "\n", 220 | "# Load the data\n", 221 | "X_data = np.load(f\"data/train/patch_data/non_augmented_terrain/{patchSize}_{patchSize}/{patchMode}/arrays/X_train_{patchSize}_{patchMode}.npy\")\n", 222 | "Y_data = np.load(f\"data/train/patch_data/non_augmented_terrain/{patchSize}_{patchSize}/{patchMode}/arrays/Y_train_{patchSize}_{patchMode}.npy\")\n", 223 | "\n", 224 | "# Split 30% of the validation data before the augmentation\n", 225 | "X_train, X_val, Y_train, Y_val = train_test_split(X_data,Y_data, test_size=0.3, random_state = 40)\n", 226 | "\n", 227 | "# Horizontal flip\n", 228 | "aug = HorizontalFlip(p=1)\n", 229 | "augmented = aug(image=X_train, mask=Y_train)\n", 230 | "image_h_flipped = augmented['image']\n", 231 | "mask_h_flipped = augmented['mask']\n", 232 | "\n", 233 | "# Vertical flip\n", 234 | "aug = VerticalFlip(p=1)\n", 235 | "augmented = aug(image=X_train, mask=Y_train)\n", 236 | "image_v_flipped = augmented['image']\n", 237 | "mask_v_flipped = augmented['mask']\n", 238 | "\n", 239 | "# Random Rotation around 90\n", 240 | "aug = RandomRotate90(p=1)\n", 241 | "augmented = aug(image=X_train, mask=Y_train)\n", 242 | "image_rot90 = augmented['image']\n", 243 | "mask_rot90 = augmented['mask']\n", 244 | "\n", 245 | "\n", 246 | "# Stack the results\n", 247 | "X_train_aug = np.vstack((X_train,image_h_flipped,image_v_flipped,image_rot90))\n", 248 | "Y_train_aug = np.vstack((Y_train,mask_h_flipped,mask_v_flipped,mask_rot90))\n", 249 | "\n", 250 | "# Save augmented training data\n", 251 | "np.save(f\"data/train/patch_data/augmented_terrain/{patchSize}_{patchSize}/{patchMode}/arrays/X_train_{patchSize}_{patchMode}_aug.npy\",X_train_aug)\n", 252 | "np.save(f\"data/train/patch_data/augmented_terrain/{patchSize}_{patchSize}/{patchMode}/arrays/Y_train_{patchSize}_{patchMode}.npy\",Y_train_aug)\n", 253 | "\n", 254 | "# Save validation data \n", 255 | "np.save(f\"data/train/patch_data/augmented_terrain/{patchSize}_{patchSize}/{patchMode}/arrays/X_val.npy\",X_val)\n", 256 | "np.save(f\"data/train/patch_data/augmented_terrain/{patchSize}_{patchSize}/{patchMode}/arrays/X_val.npy\",Y_val)" 257 | ] 258 | }, 259 | { 260 | "cell_type": "code", 261 | "execution_count": null, 262 | "metadata": {}, 263 | "outputs": [], 264 | "source": [ 265 | "# Augmentation 64x64 - random\n", 266 | "\n", 267 | "# Define the patch size that will be loaded\n", 268 | "patchSize = 64\n", 269 | "# Define the patch mode\n", 270 | "patchMode = \"random\"\n", 271 | "\n", 272 | "# Load the data\n", 273 | "X_data = np.load(f\"data/train/patch_data/non_augmented/{patchSize}_{patchSize}/{patchMode}/arrays/X_train_{patchSize}_{patchMode}.npy\")\n", 274 | "Y_data = np.load(f\"data/train/patch_data/non_augmented/{patchSize}_{patchSize}/{patchMode}/arrays/Y_train_{patchSize}_{patchMode}.npy\")\n", 275 | "\n", 276 | "# Split 30% of the validation data before the augmentation\n", 277 | "X_train, X_val, Y_train, Y_val = train_test_split(X_data,Y_data, test_size=0.3, random_state = 40)\n", 278 | "\n", 279 | "# Horizontal flip\n", 280 | "aug = HorizontalFlip(p=1)\n", 281 | "augmented = aug(image=X_train, mask=Y_train)\n", 282 | "image_h_flipped = augmented['image']\n", 283 | "mask_h_flipped = augmented['mask']\n", 284 | "\n", 285 | "# Vertical flip\n", 286 | "aug = VerticalFlip(p=1)\n", 287 | "augmented = aug(image=X_train, mask=Y_train)\n", 288 | "image_v_flipped = augmented['image']\n", 289 | "mask_v_flipped = augmented['mask']\n", 290 | "\n", 291 | "# Random Rotation around 90\n", 292 | "aug = RandomRotate90(p=1)\n", 293 | "augmented = aug(image=X_train, mask=Y_train)\n", 294 | "image_rot90 = augmented['image']\n", 295 | "mask_rot90 = augmented['mask']\n", 296 | "\n", 297 | "\n", 298 | "# Stack the results\n", 299 | "X_train_aug = np.vstack((X_train,image_h_flipped,image_v_flipped,image_rot90))\n", 300 | "Y_train_aug = np.vstack((Y_train,mask_h_flipped,mask_v_flipped,mask_rot90))\n", 301 | "\n", 302 | "# Save augmented training data\n", 303 | "np.save(f\"data/train/patch_data/augmented/{patchSize}_{patchSize}/{patchMode}/arrays/X_train_{patchSize}_{patchMode}_aug.npy\",X_train_aug)\n", 304 | "np.save(f\"data/train/patch_data/augmented/{patchSize}_{patchSize}/{patchMode}/arrays/Y_train_{patchSize}_{patchMode}.npy\",Y_train_aug)\n", 305 | "\n", 306 | "# Save validation data \n", 307 | "np.save(f\"data/train/patch_data/augmented/{patchSize}_{patchSize}/{patchMode}/arrays/X_val.npy\",X_val)\n", 308 | "np.save(f\"data/train/patch_data/augmented/{patchSize}_{patchSize}/{patchMode}/arrays/X_val.npy\",Y_val)" 309 | ] 310 | }, 311 | { 312 | "cell_type": "code", 313 | "execution_count": null, 314 | "metadata": {}, 315 | "outputs": [], 316 | "source": [ 317 | "# Augmentation 64x64 - regular\n", 318 | "\n", 319 | "# Define the patch size that will be loaded\n", 320 | "patchSize = 64\n", 321 | "# Define the patch mode\n", 322 | "patchMode = \"regular\"\n", 323 | "\n", 324 | "# Load the data\n", 325 | "X_data = np.load(f\"data/train/patch_data/non_augmented/{patchSize}_{patchSize}/{patchMode}/arrays/X_train_{patchSize}_{patchMode}.npy\")\n", 326 | "Y_data = np.load(f\"data/train/patch_data/non_augmented/{patchSize}_{patchSize}/{patchMode}/arrays/Y_train_{patchSize}_{patchMode}.npy\")\n", 327 | "\n", 328 | "# Split 30% of the validation data before the augmentation\n", 329 | "X_train, X_val, Y_train, Y_val = train_test_split(X_data,Y_data, test_size=0.3, random_state = 40)\n", 330 | "\n", 331 | "# Horizontal flip\n", 332 | "aug = HorizontalFlip(p=1)\n", 333 | "augmented = aug(image=X_train, mask=Y_train)\n", 334 | "image_h_flipped = augmented['image']\n", 335 | "mask_h_flipped = augmented['mask']\n", 336 | "\n", 337 | "# Vertical flip\n", 338 | "aug = VerticalFlip(p=1)\n", 339 | "augmented = aug(image=X_train, mask=Y_train)\n", 340 | "image_v_flipped = augmented['image']\n", 341 | "mask_v_flipped = augmented['mask']\n", 342 | "\n", 343 | "# Random Rotation around 90\n", 344 | "aug = RandomRotate90(p=1)\n", 345 | "augmented = aug(image=X_train, mask=Y_train)\n", 346 | "image_rot90 = augmented['image']\n", 347 | "mask_rot90 = augmented['mask']\n", 348 | "\n", 349 | "\n", 350 | "# Stack the results\n", 351 | "X_train_aug = np.vstack((X_train,image_h_flipped,image_v_flipped,image_rot90))\n", 352 | "Y_train_aug = np.vstack((Y_train,mask_h_flipped,mask_v_flipped,mask_rot90))\n", 353 | "\n", 354 | "# Save augmented training data\n", 355 | "np.save(f\"data/train/patch_data/augmented/{patchSize}_{patchSize}/{patchMode}/arrays/X_train_{patchSize}_{patchMode}_aug.npy\",X_train_aug)\n", 356 | "np.save(f\"data/train/patch_data/augmented/{patchSize}_{patchSize}/{patchMode}/arrays/Y_train_{patchSize}_{patchMode}.npy\",Y_train_aug)\n", 357 | "\n", 358 | "# Save validation data \n", 359 | "np.save(f\"data/train/patch_data/augmented/{patchSize}_{patchSize}/{patchMode}/arrays/X_val.npy\",X_val)\n", 360 | "np.save(f\"data/train/patch_data/augmented/{patchSize}_{patchSize}/{patchMode}/arrays/X_val.npy\",Y_val)" 361 | ] 362 | }, 363 | { 364 | "cell_type": "code", 365 | "execution_count": null, 366 | "metadata": {}, 367 | "outputs": [], 368 | "source": [ 369 | "# Augmentation 64x64 - random terrain\n", 370 | "\n", 371 | "# Define the patch size that will be loaded\n", 372 | "patchSize = 64\n", 373 | "# Define the patch mode\n", 374 | "patchMode = \"random\"\n", 375 | "\n", 376 | "# Load the data\n", 377 | "X_data = np.load(f\"data/train/patch_data/non_augmented_terrain/{patchSize}_{patchSize}/{patchMode}/arrays/X_train_{patchSize}_{patchMode}.npy\")\n", 378 | "Y_data = np.load(f\"data/train/patch_data/non_augmented_terrain/{patchSize}_{patchSize}/{patchMode}/arrays/Y_train_{patchSize}_{patchMode}.npy\")\n", 379 | "\n", 380 | "# Split 30% of the validation data before the augmentation\n", 381 | "X_train, X_val, Y_train, Y_val = train_test_split(X_data,Y_data, test_size=0.3, random_state = 40)\n", 382 | "\n", 383 | "# Horizontal flip\n", 384 | "aug = HorizontalFlip(p=1)\n", 385 | "augmented = aug(image=X_train, mask=Y_train)\n", 386 | "image_h_flipped = augmented['image']\n", 387 | "mask_h_flipped = augmented['mask']\n", 388 | "\n", 389 | "# Vertical flip\n", 390 | "aug = VerticalFlip(p=1)\n", 391 | "augmented = aug(image=X_train, mask=Y_train)\n", 392 | "image_v_flipped = augmented['image']\n", 393 | "mask_v_flipped = augmented['mask']\n", 394 | "\n", 395 | "# Random Rotation around 90\n", 396 | "aug = RandomRotate90(p=1)\n", 397 | "augmented = aug(image=X_train, mask=Y_train)\n", 398 | "image_rot90 = augmented['image']\n", 399 | "mask_rot90 = augmented['mask']\n", 400 | "\n", 401 | "\n", 402 | "# Stack the results\n", 403 | "X_train_aug = np.vstack((X_train,image_h_flipped,image_v_flipped,image_rot90))\n", 404 | "Y_train_aug = np.vstack((Y_train,mask_h_flipped,mask_v_flipped,mask_rot90))\n", 405 | "\n", 406 | "# Save augmented training data\n", 407 | "np.save(f\"data/train/patch_data/augmented_terrain/{patchSize}_{patchSize}/{patchMode}/arrays/X_train_{patchSize}_{patchMode}_aug.npy\",X_train_aug)\n", 408 | "np.save(f\"data/train/patch_data/augmented_terrain/{patchSize}_{patchSize}/{patchMode}/arrays/Y_train_{patchSize}_{patchMode}.npy\",Y_train_aug)\n", 409 | "\n", 410 | "# Save validation data \n", 411 | "np.save(f\"data/train/patch_data/augmented_terrain/{patchSize}_{patchSize}/{patchMode}/arrays/X_val.npy\",X_val)\n", 412 | "np.save(f\"data/train/patch_data/augmented_terrain/{patchSize}_{patchSize}/{patchMode}/arrays/X_val.npy\",Y_val)" 413 | ] 414 | }, 415 | { 416 | "cell_type": "code", 417 | "execution_count": null, 418 | "metadata": {}, 419 | "outputs": [], 420 | "source": [ 421 | "# Augmentation 64x64 - regular terrain\n", 422 | "\n", 423 | "# Define the patch size that will be loaded\n", 424 | "patchSize = 64\n", 425 | "# Define the patch mode\n", 426 | "patchMode = \"regular\"\n", 427 | "\n", 428 | "# Load the data\n", 429 | "X_data = np.load(f\"data/train/patch_data/non_augmented_terrain/{patchSize}_{patchSize}/{patchMode}/arrays/X_train_{patchSize}_{patchMode}.npy\")\n", 430 | "Y_data = np.load(f\"data/train/patch_data/non_augmented_terrain/{patchSize}_{patchSize}/{patchMode}/arrays/Y_train_{patchSize}_{patchMode}.npy\")\n", 431 | "\n", 432 | "# Split 30% of the validation data before the augmentation\n", 433 | "X_train, X_val, Y_train, Y_val = train_test_split(X_data,Y_data, test_size=0.3, random_state = 40)\n", 434 | "\n", 435 | "# Horizontal flip\n", 436 | "aug = HorizontalFlip(p=1)\n", 437 | "augmented = aug(image=X_train, mask=Y_train)\n", 438 | "image_h_flipped = augmented['image']\n", 439 | "mask_h_flipped = augmented['mask']\n", 440 | "\n", 441 | "# Vertical flip\n", 442 | "aug = VerticalFlip(p=1)\n", 443 | "augmented = aug(image=X_train, mask=Y_train)\n", 444 | "image_v_flipped = augmented['image']\n", 445 | "mask_v_flipped = augmented['mask']\n", 446 | "\n", 447 | "# Random Rotation around 90\n", 448 | "aug = RandomRotate90(p=1)\n", 449 | "augmented = aug(image=X_train, mask=Y_train)\n", 450 | "image_rot90 = augmented['image']\n", 451 | "mask_rot90 = augmented['mask']\n", 452 | "\n", 453 | "\n", 454 | "# Stack the results\n", 455 | "X_train_aug = np.vstack((X_train,image_h_flipped,image_v_flipped,image_rot90))\n", 456 | "Y_train_aug = np.vstack((Y_train,mask_h_flipped,mask_v_flipped,mask_rot90))\n", 457 | "\n", 458 | "# Save augmented training data\n", 459 | "np.save(f\"data/train/patch_data/augmented_terrain/{patchSize}_{patchSize}/{patchMode}/arrays/X_train_{patchSize}_{patchMode}_aug.npy\",X_train_aug)\n", 460 | "np.save(f\"data/train/patch_data/augmented_terrain/{patchSize}_{patchSize}/{patchMode}/arrays/Y_train_{patchSize}_{patchMode}.npy\",Y_train_aug)\n", 461 | "\n", 462 | "# Save validation data \n", 463 | "np.save(f\"data/train/patch_data/augmented_terrain/{patchSize}_{patchSize}/{patchMode}/arrays/X_val.npy\",X_val)\n", 464 | "np.save(f\"data/train/patch_data/augmented_terrain/{patchSize}_{patchSize}/{patchMode}/arrays/X_val.npy\",Y_val)" 465 | ] 466 | }, 467 | { 468 | "cell_type": "code", 469 | "execution_count": null, 470 | "metadata": {}, 471 | "outputs": [], 472 | "source": [ 473 | "# Augmentation 128x128 - random\n", 474 | "\n", 475 | "# Define the patch size that will be loaded\n", 476 | "patchSize = 128\n", 477 | "# Define the patch mode\n", 478 | "patchMode = \"random\"\n", 479 | "\n", 480 | "# Load the data\n", 481 | "X_data = np.load(f\"data/train/patch_data/non_augmented/{patchSize}_{patchSize}/{patchMode}/arrays/X_train_{patchSize}_{patchMode}.npy\")\n", 482 | "Y_data = np.load(f\"data/train/patch_data/non_augmented/{patchSize}_{patchSize}/{patchMode}/arrays/Y_train_{patchSize}_{patchMode}.npy\")\n", 483 | "\n", 484 | "# Split 30% of the validation data before the augmentation\n", 485 | "X_train, X_val, Y_train, Y_val = train_test_split(X_data,Y_data, test_size=0.3, random_state = 40)\n", 486 | "\n", 487 | "# Horizontal flip\n", 488 | "aug = HorizontalFlip(p=1)\n", 489 | "augmented = aug(image=X_train, mask=Y_train)\n", 490 | "image_h_flipped = augmented['image']\n", 491 | "mask_h_flipped = augmented['mask']\n", 492 | "\n", 493 | "# Vertical flip\n", 494 | "aug = VerticalFlip(p=1)\n", 495 | "augmented = aug(image=X_train, mask=Y_train)\n", 496 | "image_v_flipped = augmented['image']\n", 497 | "mask_v_flipped = augmented['mask']\n", 498 | "\n", 499 | "# Random Rotation around 90\n", 500 | "aug = RandomRotate90(p=1)\n", 501 | "augmented = aug(image=X_train, mask=Y_train)\n", 502 | "image_rot90 = augmented['image']\n", 503 | "mask_rot90 = augmented['mask']\n", 504 | "\n", 505 | "\n", 506 | "# Stack the results\n", 507 | "X_train_aug = np.vstack((X_train,image_h_flipped,image_v_flipped,image_rot90))\n", 508 | "Y_train_aug = np.vstack((Y_train,mask_h_flipped,mask_v_flipped,mask_rot90))\n", 509 | "\n", 510 | "# Save augmented training data\n", 511 | "np.save(f\"data/train/patch_data/augmented/{patchSize}_{patchSize}/{patchMode}/arrays/X_train_{patchSize}_{patchMode}_aug.npy\",X_train_aug)\n", 512 | "np.save(f\"data/train/patch_data/augmented/{patchSize}_{patchSize}/{patchMode}/arrays/Y_train_{patchSize}_{patchMode}.npy\",Y_train_aug)\n", 513 | "\n", 514 | "# Save validation data \n", 515 | "np.save(f\"data/train/patch_data/augmented/{patchSize}_{patchSize}/{patchMode}/arrays/X_val.npy\",X_val)\n", 516 | "np.save(f\"data/train/patch_data/augmented/{patchSize}_{patchSize}/{patchMode}/arrays/X_val.npy\",Y_val)" 517 | ] 518 | }, 519 | { 520 | "cell_type": "code", 521 | "execution_count": null, 522 | "metadata": {}, 523 | "outputs": [], 524 | "source": [ 525 | "# Augmentation 128x128 - regular\n", 526 | "\n", 527 | "# Define the patch size that will be loaded\n", 528 | "patchSize = 128\n", 529 | "# Define the patch mode\n", 530 | "patchMode = \"regular\"\n", 531 | "\n", 532 | "# Load the data\n", 533 | "X_data = np.load(f\"data/train/patch_data/non_augmented/{patchSize}_{patchSize}/{patchMode}/arrays/X_train_{patchSize}_{patchMode}.npy\")\n", 534 | "Y_data = np.load(f\"data/train/patch_data/non_augmented/{patchSize}_{patchSize}/{patchMode}/arrays/Y_train_{patchSize}_{patchMode}.npy\")\n", 535 | "\n", 536 | "# Split 30% of the validation data before the augmentation\n", 537 | "X_train, X_val, Y_train, Y_val = train_test_split(X_data,Y_data, test_size=0.3, random_state = 40)\n", 538 | "\n", 539 | "# Horizontal flip\n", 540 | "aug = HorizontalFlip(p=1)\n", 541 | "augmented = aug(image=X_train, mask=Y_train)\n", 542 | "image_h_flipped = augmented['image']\n", 543 | "mask_h_flipped = augmented['mask']\n", 544 | "\n", 545 | "# Vertical flip\n", 546 | "aug = VerticalFlip(p=1)\n", 547 | "augmented = aug(image=X_train, mask=Y_train)\n", 548 | "image_v_flipped = augmented['image']\n", 549 | "mask_v_flipped = augmented['mask']\n", 550 | "\n", 551 | "# Random Rotation around 90\n", 552 | "aug = RandomRotate90(p=1)\n", 553 | "augmented = aug(image=X_train, mask=Y_train)\n", 554 | "image_rot90 = augmented['image']\n", 555 | "mask_rot90 = augmented['mask']\n", 556 | "\n", 557 | "\n", 558 | "# Stack the results\n", 559 | "X_train_aug = np.vstack((X_train,image_h_flipped,image_v_flipped,image_rot90))\n", 560 | "Y_train_aug = np.vstack((Y_train,mask_h_flipped,mask_v_flipped,mask_rot90))\n", 561 | "\n", 562 | "# Save augmented training data\n", 563 | "np.save(f\"data/train/patch_data/augmented/{patchSize}_{patchSize}/{patchMode}/arrays/X_train_{patchSize}_{patchMode}_aug.npy\",X_train_aug)\n", 564 | "np.save(f\"data/train/patch_data/augmented/{patchSize}_{patchSize}/{patchMode}/arrays/Y_train_{patchSize}_{patchMode}.npy\",Y_train_aug)\n", 565 | "\n", 566 | "# Save validation data \n", 567 | "np.save(f\"data/train/patch_data/augmented/{patchSize}_{patchSize}/{patchMode}/arrays/X_val.npy\",X_val)\n", 568 | "np.save(f\"data/train/patch_data/augmented/{patchSize}_{patchSize}/{patchMode}/arrays/X_val.npy\",Y_val)" 569 | ] 570 | }, 571 | { 572 | "cell_type": "code", 573 | "execution_count": null, 574 | "metadata": {}, 575 | "outputs": [], 576 | "source": [ 577 | "# Augmentation 128x128 - random terrain\n", 578 | "\n", 579 | "# Define the patch size that will be loaded\n", 580 | "patchSize = 128\n", 581 | "# Define the patch mode\n", 582 | "patchMode = \"random\"\n", 583 | "\n", 584 | "# Load the data\n", 585 | "X_data = np.load(f\"data/train/patch_data/non_augmented_terrain/{patchSize}_{patchSize}/{patchMode}/arrays/X_train_{patchSize}_{patchMode}.npy\")\n", 586 | "Y_data = np.load(f\"data/train/patch_data/non_augmented_terrain/{patchSize}_{patchSize}/{patchMode}/arrays/Y_train_{patchSize}_{patchMode}.npy\")\n", 587 | "\n", 588 | "# Split 30% of the validation data before the augmentation\n", 589 | "X_train, X_val, Y_train, Y_val = train_test_split(X_data,Y_data, test_size=0.3, random_state = 40)\n", 590 | "\n", 591 | "# Horizontal flip\n", 592 | "aug = HorizontalFlip(p=1)\n", 593 | "augmented = aug(image=X_train, mask=Y_train)\n", 594 | "image_h_flipped = augmented['image']\n", 595 | "mask_h_flipped = augmented['mask']\n", 596 | "\n", 597 | "# Vertical flip\n", 598 | "aug = VerticalFlip(p=1)\n", 599 | "augmented = aug(image=X_train, mask=Y_train)\n", 600 | "image_v_flipped = augmented['image']\n", 601 | "mask_v_flipped = augmented['mask']\n", 602 | "\n", 603 | "# Random Rotation around 90\n", 604 | "aug = RandomRotate90(p=1)\n", 605 | "augmented = aug(image=X_train, mask=Y_train)\n", 606 | "image_rot90 = augmented['image']\n", 607 | "mask_rot90 = augmented['mask']\n", 608 | "\n", 609 | "\n", 610 | "# Stack the results\n", 611 | "X_train_aug = np.vstack((X_train,image_h_flipped,image_v_flipped,image_rot90))\n", 612 | "Y_train_aug = np.vstack((Y_train,mask_h_flipped,mask_v_flipped,mask_rot90))\n", 613 | "\n", 614 | "# Save augmented training data\n", 615 | "np.save(f\"data/train/patch_data/augmented_terrain/{patchSize}_{patchSize}/{patchMode}/arrays/X_train_{patchSize}_{patchMode}_aug.npy\",X_train_aug)\n", 616 | "np.save(f\"data/train/patch_data/augmented_terrain/{patchSize}_{patchSize}/{patchMode}/arrays/Y_train_{patchSize}_{patchMode}.npy\",Y_train_aug)\n", 617 | "\n", 618 | "# Save validation data \n", 619 | "np.save(f\"data/train/patch_data/augmented_terrain/{patchSize}_{patchSize}/{patchMode}/arrays/X_val.npy\",X_val)\n", 620 | "np.save(f\"data/train/patch_data/augmented_terrain/{patchSize}_{patchSize}/{patchMode}/arrays/X_val.npy\",Y_val)" 621 | ] 622 | }, 623 | { 624 | "cell_type": "code", 625 | "execution_count": null, 626 | "metadata": {}, 627 | "outputs": [], 628 | "source": [ 629 | "# Augmentation 128x128 - regular terrain\n", 630 | "\n", 631 | "# Define the patch size that will be loaded\n", 632 | "patchSize = 128\n", 633 | "# Define the patch mode\n", 634 | "patchMode = \"regular\"\n", 635 | "\n", 636 | "# Load the data\n", 637 | "X_data = np.load(f\"data/train/patch_data/non_augmented_terrain/{patchSize}_{patchSize}/{patchMode}/arrays/X_train_{patchSize}_{patchMode}.npy\")\n", 638 | "Y_data = np.load(f\"data/train/patch_data/non_augmented_terrain/{patchSize}_{patchSize}/{patchMode}/arrays/Y_train_{patchSize}_{patchMode}.npy\")\n", 639 | "\n", 640 | "# Split 30% of the validation data before the augmentation\n", 641 | "X_train, X_val, Y_train, Y_val = train_test_split(X_data,Y_data, test_size=0.3, random_state = 40)\n", 642 | "\n", 643 | "# Horizontal flip\n", 644 | "aug = HorizontalFlip(p=1)\n", 645 | "augmented = aug(image=X_train, mask=Y_train)\n", 646 | "image_h_flipped = augmented['image']\n", 647 | "mask_h_flipped = augmented['mask']\n", 648 | "\n", 649 | "# Vertical flip\n", 650 | "aug = VerticalFlip(p=1)\n", 651 | "augmented = aug(image=X_train, mask=Y_train)\n", 652 | "image_v_flipped = augmented['image']\n", 653 | "mask_v_flipped = augmented['mask']\n", 654 | "\n", 655 | "# Random Rotation around 90\n", 656 | "aug = RandomRotate90(p=1)\n", 657 | "augmented = aug(image=X_train, mask=Y_train)\n", 658 | "image_rot90 = augmented['image']\n", 659 | "mask_rot90 = augmented['mask']\n", 660 | "\n", 661 | "\n", 662 | "# Stack the results\n", 663 | "X_train_aug = np.vstack((X_train,image_h_flipped,image_v_flipped,image_rot90))\n", 664 | "Y_train_aug = np.vstack((Y_train,mask_h_flipped,mask_v_flipped,mask_rot90))\n", 665 | "\n", 666 | "# Save augmented training data\n", 667 | "np.save(f\"data/train/patch_data/augmented_terrain/{patchSize}_{patchSize}/{patchMode}/arrays/X_train_{patchSize}_{patchMode}_aug.npy\",X_train_aug)\n", 668 | "np.save(f\"data/train/patch_data/augmented_terrain/{patchSize}_{patchSize}/{patchMode}/arrays/Y_train_{patchSize}_{patchMode}.npy\",Y_train_aug)\n", 669 | "\n", 670 | "# Save validation data \n", 671 | "np.save(f\"data/train/patch_data/augmented_terrain/{patchSize}_{patchSize}/{patchMode}/arrays/X_val.npy\",X_val)\n", 672 | "np.save(f\"data/train/patch_data/augmented_terrain/{patchSize}_{patchSize}/{patchMode}/arrays/X_val.npy\",Y_val)" 673 | ] 674 | } 675 | ], 676 | "metadata": { 677 | "kernelspec": { 678 | "display_name": "Python 3", 679 | "language": "python", 680 | "name": "python3" 681 | }, 682 | "language_info": { 683 | "codemirror_mode": { 684 | "name": "ipython", 685 | "version": 3 686 | }, 687 | "file_extension": ".py", 688 | "mimetype": "text/x-python", 689 | "name": "python", 690 | "nbconvert_exporter": "python", 691 | "pygments_lexer": "ipython3", 692 | "version": "3.7.7" 693 | } 694 | }, 695 | "nbformat": 4, 696 | "nbformat_minor": 2 697 | } 698 | -------------------------------------------------------------------------------- /notebooks/Georeferencing_the_results.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Code used to georefence and evaluate the results " 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": null, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "# import libraries\n", 17 | "import numpy as np\n", 18 | "import tensorflow as tf\n", 19 | "from __future__ import absolute_import\n", 20 | "from __future__ import division\n", 21 | "from __future__ import print_function\n", 22 | "\n", 23 | "from datetime import datetime\n", 24 | "from packaging import version\n", 25 | "\n", 26 | "%tensorflow_version 2.x\n", 27 | "from tensorflow import keras\n", 28 | "from tensorflow.keras.models import *\n", 29 | "from tensorflow.keras.layers import *\n", 30 | "from tensorflow.keras.optimizers import *\n", 31 | "from sklearn.model_selection import train_test_split\n", 32 | "\n", 33 | "import numpy as np\n", 34 | "import pandas as pd\n", 35 | "\n", 36 | "print(\"TensorFlow version: \", tf.__version__)\n", 37 | "assert version.parse(tf.__version__).release[0] >= 2, \\\n", 38 | " \"This notebook requires TensorFlow 2.0 or above.\"" 39 | ] 40 | }, 41 | { 42 | "cell_type": "code", 43 | "execution_count": null, 44 | "metadata": {}, 45 | "outputs": [], 46 | "source": [ 47 | "# Install segmentation_models\n", 48 | "pip install segmentation_models" 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "execution_count": null, 54 | "metadata": {}, 55 | "outputs": [], 56 | "source": [ 57 | "import segmentation_models as sm" 58 | ] 59 | }, 60 | { 61 | "cell_type": "code", 62 | "execution_count": null, 63 | "metadata": {}, 64 | "outputs": [], 65 | "source": [ 66 | "# Load data\n", 67 | "X_test = np.load(\"/content/drive/My Drive/Mestrado/artigo/artigo_final/data/test/test_with_terrain/area_1/arrays/X_test_area_1.npy\")\n", 68 | "Y_test = np.load(\"/content/drive/My Drive/Mestrado/artigo/artigo_final/data/test/test_with_terrain/area_1/arrays/Y_test_area_1.npy\")\n", 69 | "original_image_path = \"/content/drive/My Drive/Mestrado/artigo/artigo_final/data/test/test_with_terrain/area_1/images/test_area_1.tif\"" 70 | ] 71 | }, 72 | { 73 | "cell_type": "code", 74 | "execution_count": null, 75 | "metadata": {}, 76 | "outputs": [], 77 | "source": [ 78 | "# Define TP metric\n", 79 | "def true_positive(y_true, y_pred):\n", 80 | " y_pred_pos = tf.keras.backend.round(tf.keras.backend.clip(y_pred, 0, 1))\n", 81 | " y_pred_neg = 1 - y_pred_pos\n", 82 | "\n", 83 | " y_pos = tf.keras.backend.round(tf.keras.backend.clip(y_true, 0, 1))\n", 84 | " y_neg = 1 - y_pos\n", 85 | "\n", 86 | " tp = tf.keras.backend.sum(y_pos * y_pred_pos)\n", 87 | "\n", 88 | "\n", 89 | " return tp * (0.005**2)" 90 | ] 91 | }, 92 | { 93 | "cell_type": "code", 94 | "execution_count": null, 95 | "metadata": {}, 96 | "outputs": [], 97 | "source": [ 98 | "# Define TN metrics\n", 99 | "def true_negative(y_true, y_pred):\n", 100 | " y_pred_pos = tf.keras.backend.round(tf.keras.backend.clip(y_pred, 0, 1))\n", 101 | " y_pred_neg = 1 - y_pred_pos\n", 102 | "\n", 103 | " y_pos = tf.keras.backend.round(tf.keras.backend.clip(y_true, 0, 1))\n", 104 | " y_neg = 1 - y_pos\n", 105 | "\n", 106 | " \n", 107 | " tn = tf.keras.backend.sum(y_neg * y_pred_neg)\n", 108 | "\n", 109 | "\n", 110 | " return tn * (0.005**2)" 111 | ] 112 | }, 113 | { 114 | "cell_type": "code", 115 | "execution_count": null, 116 | "metadata": {}, 117 | "outputs": [], 118 | "source": [ 119 | "# Define FP metrics\n", 120 | "def false_positve(y_true, y_pred):\n", 121 | " y_pred_pos = tf.keras.backend.round(tf.keras.backend.clip(y_pred, 0, 1))\n", 122 | " y_pred_neg = 1 - y_pred_pos\n", 123 | "\n", 124 | " y_pos = tf.keras.backend.round(tf.keras.backend.clip(y_true, 0, 1))\n", 125 | " y_neg = 1 - y_pos\n", 126 | "\n", 127 | " \n", 128 | " fp = tf.keras.backend.sum(y_neg * y_pred_pos)\n", 129 | " \n", 130 | "\n", 131 | " return fp * (0.005**2)" 132 | ] 133 | }, 134 | { 135 | "cell_type": "code", 136 | "execution_count": null, 137 | "metadata": {}, 138 | "outputs": [], 139 | "source": [ 140 | "# Define FN metrics\n", 141 | "def false_negative(y_true, y_pred):\n", 142 | " y_pred_pos = tf.keras.backend.round(tf.keras.backend.clip(y_pred, 0, 1))\n", 143 | " y_pred_neg = 1 - y_pred_pos\n", 144 | "\n", 145 | " y_pos = tf.keras.backend.round(tf.keras.backend.clip(y_true, 0, 1))\n", 146 | " y_neg = 1 - y_pos\n", 147 | "\n", 148 | " fn = tf.keras.backend.sum(y_pos * y_pred_neg)\n", 149 | "\n", 150 | "\n", 151 | "\n", 152 | " return fn * (0.005**2)" 153 | ] 154 | }, 155 | { 156 | "cell_type": "code", 157 | "execution_count": null, 158 | "metadata": {}, 159 | "outputs": [], 160 | "source": [ 161 | "# Network Metrics\n", 162 | "metrics = [sm.metrics.Precision(threshold=0.5),sm.metrics.Recall(threshold=0.5),sm.metrics.FScore(threshold=0.5,beta=1),sm.metrics.IOUScore(threshold=0.5),matthews_correlation,true_positive,true_negative,false_positve,false_negative]" 163 | ] 164 | }, 165 | { 166 | "cell_type": "code", 167 | "execution_count": null, 168 | "metadata": {}, 169 | "outputs": [], 170 | "source": [ 171 | "# Define model Architecture\n", 172 | "def Unet(lr,filtersFirstLayer, pretrained_weights = None,input_size = (32,32,6)):\n", 173 | " inputs = Input(input_size)\n", 174 | " \n", 175 | " conv1 = Conv2D(filtersFirstLayer, 3, activation = 'relu', padding = 'same')(inputs)\n", 176 | " conv1 = Conv2D(filtersFirstLayer, 3, activation = 'relu', padding = 'same')(conv1)\n", 177 | " pool1 = MaxPooling2D(pool_size=(2, 2))(conv1)\n", 178 | " \n", 179 | " conv2 = Conv2D(filtersFirstLayer*2, 3, activation = 'relu', padding = 'same')(pool1)\n", 180 | " conv2 = Conv2D(filtersFirstLayer*2, 3, activation = 'relu', padding = 'same')(conv2)\n", 181 | " pool2 = MaxPooling2D(pool_size=(2, 2))(conv2)\n", 182 | "\n", 183 | "\n", 184 | " conv3 = Conv2D(filtersFirstLayer*4, 3, activation = 'relu', padding = 'same')(pool2)\n", 185 | " conv3 = Conv2D(filtersFirstLayer*4, 3, activation = 'relu', padding = 'same')(conv3)\n", 186 | " pool3 = MaxPooling2D(pool_size=(2, 2))(conv3)\n", 187 | "\n", 188 | " \n", 189 | " conv4 = Conv2D(filtersFirstLayer*8, 3, activation = 'relu', padding = 'same')(pool3)\n", 190 | " conv4 = Conv2D(filtersFirstLayer*8, 3, activation = 'relu', padding = 'same')(conv4)\n", 191 | " pool4 = MaxPooling2D(pool_size=(2, 2))(conv4)\n", 192 | "\n", 193 | " \n", 194 | " conv5 = Conv2D(filtersFirstLayer*16, 3, activation = 'relu', padding = 'same')(pool4)\n", 195 | " conv5 = Conv2D(filtersFirstLayer*16, 3, activation = 'relu', padding = 'same')(conv5)\n", 196 | "\n", 197 | " # Up 1 \n", 198 | " up6 = Conv2D(filtersFirstLayer*8, 2, activation = 'relu', padding = 'same')(UpSampling2D(size = (2,2))(conv5))\n", 199 | " merge6 = concatenate([conv4,up6], axis = 3)\n", 200 | " conv6 = Conv2D(filtersFirstLayer*8, 3, activation = 'relu', padding = 'same')(merge6)\n", 201 | " conv6 = Conv2D(filtersFirstLayer*8, 3, activation = 'relu', padding = 'same')(conv6)\n", 202 | "\n", 203 | " # Up 2 \n", 204 | " up7 = Conv2D(filtersFirstLayer*4, 2, activation = 'relu', padding = 'same')(UpSampling2D(size = (2,2))(conv6))\n", 205 | " merge7 = concatenate([conv3,up7], axis = 3)\n", 206 | " conv7 = Conv2D(filtersFirstLayer*4, 3, activation = 'relu', padding = 'same')(merge7)\n", 207 | " conv7 = Conv2D(filtersFirstLayer*4, 3, activation = 'relu', padding = 'same')(conv7)\n", 208 | "\n", 209 | " # Up 3 \n", 210 | " up8 = Conv2D(filtersFirstLayer*2, 2, activation = 'relu', padding = 'same')(UpSampling2D(size = (2,2))(conv7))\n", 211 | " merge8 = concatenate([conv2,up8], axis = 3)\n", 212 | " conv8 = Conv2D(filtersFirstLayer*2, 3, activation = 'relu', padding = 'same')(merge8)\n", 213 | " conv8 = Conv2D(filtersFirstLayer*2, 3, activation = 'relu', padding = 'same')(conv8)\n", 214 | "\n", 215 | " # Up 4 \n", 216 | " up9 = Conv2D(filtersFirstLayer, 2, activation = 'relu', padding = 'same')(UpSampling2D(size = (2,2))(conv8))\n", 217 | " merge9 = concatenate([conv1,up9], axis = 3)\n", 218 | " conv9 = Conv2D(filtersFirstLayer, 3, activation = 'relu', padding = 'same')(merge9)\n", 219 | " conv9 = Conv2D(filtersFirstLayer, 3, activation = 'relu', padding = 'same')(conv9)\n", 220 | " conv9 = Conv2D(2, 3, activation = 'relu', padding = 'same')(conv9)\n", 221 | "\n", 222 | " # output\n", 223 | " conv10 = Conv2D(1, 1, activation = 'sigmoid')(conv9)\n", 224 | "\n", 225 | " model = Model(inputs, conv10)\n", 226 | "\n", 227 | " model.compile(optimizer = Adam(lr = lr), loss = 'binary_crossentropy', metrics = metrics)\n", 228 | " \n", 229 | " model.summary()\n", 230 | "\n", 231 | " if(pretrained_weights):\n", 232 | " \tmodel.load_weights(pretrained_weights)\n", 233 | "\n", 234 | " return model\n", 235 | "\n", 236 | "model = Unet(0.0001,32,input_size=(1024,1024,6))" 237 | ] 238 | }, 239 | { 240 | "cell_type": "code", 241 | "execution_count": null, 242 | "metadata": {}, 243 | "outputs": [], 244 | "source": [ 245 | "# Load model weights\n", 246 | "model.load_weights(\"/content/drive/My Drive/Mestrado/artigo/artigo_final/results/augmented_terrain/64_64/random/model/unet/unet_random_size_64_filters_32_batch_size_16_lr_0.001.hdf5\")" 247 | ] 248 | }, 249 | { 250 | "cell_type": "code", 251 | "execution_count": null, 252 | "metadata": {}, 253 | "outputs": [], 254 | "source": [ 255 | "# Evaluate the model \n", 256 | "model.evaluate(X_test,Y_test)" 257 | ] 258 | }, 259 | { 260 | "cell_type": "code", 261 | "execution_count": null, 262 | "metadata": {}, 263 | "outputs": [], 264 | "source": [ 265 | "# Make the prediction over the test areas and save as .tif\n", 266 | "\n", 267 | "# import rasterio\n", 268 | "import rasterio\n", 269 | "\n", 270 | "\n", 271 | "# Predict\n", 272 | "preds_train = model.predict(X_test, verbose=1)\n", 273 | "# Assign the value one for predictions with results > 0.5\n", 274 | "preds_train_t = (preds_train > 0.5).astype(np.uint8)\n", 275 | "# Open the original image\n", 276 | "dataset = rasterio.open(original_image_path)\n", 277 | "# Get the metadata from the image\n", 278 | "meta = dataset.meta\n", 279 | "# Change the metadata to 1 (Result image will have just one channel)\n", 280 | "meta[\"count\"] = 1\n", 281 | "# Nodata values = 0\n", 282 | "meta[\"nodata\"] = 0\n", 283 | "# data type = uint8 (8bits)\n", 284 | "meta[\"dtype\"] = \"uint8\"\n", 285 | "# Ajust array dimensions\n", 286 | "save = np.squeeze(preds_train_t, axis=(0,3))\n", 287 | "save = np.expand_dims(save,axis = 0)\n", 288 | "# Save .tif image\n", 289 | "with rasterio.open(\"area_2_32_predict.tif\", 'w', **meta) as dst:\n", 290 | " dst.write(save)" 291 | ] 292 | } 293 | ], 294 | "metadata": { 295 | "kernelspec": { 296 | "display_name": "Python 3", 297 | "language": "python", 298 | "name": "python3" 299 | }, 300 | "language_info": { 301 | "codemirror_mode": { 302 | "name": "ipython", 303 | "version": 3 304 | }, 305 | "file_extension": ".py", 306 | "mimetype": "text/x-python", 307 | "name": "python", 308 | "nbconvert_exporter": "python", 309 | "pygments_lexer": "ipython3", 310 | "version": "3.7.7" 311 | } 312 | }, 313 | "nbformat": 4, 314 | "nbformat_minor": 4 315 | } 316 | -------------------------------------------------------------------------------- /notebooks/Training_random_RapidEye+Augmentation.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Code used to train the RapidEye+Augmentation random models \n", 8 | "\n", 9 | "The models were trained in Google Colaboratory Virtual Environment, thus, to work properly, this notebook should be loaded in google drive.\n", 10 | "\n", 11 | "* [32x32 models](#32-x-32-models) \n", 12 | "\n", 13 | "* [64x64 models](#64-x-64-models) \n", 14 | "\n", 15 | "* [128x128 models](#128-x-128-models) " 16 | ] 17 | }, 18 | { 19 | "cell_type": "code", 20 | "execution_count": null, 21 | "metadata": {}, 22 | "outputs": [], 23 | "source": [ 24 | "# Import libraries\n", 25 | "\n", 26 | "import tensorflow as tf\n", 27 | "from __future__ import absolute_import\n", 28 | "from __future__ import division\n", 29 | "from __future__ import print_function\n", 30 | "\n", 31 | "from datetime import datetime\n", 32 | "from packaging import version\n", 33 | "\n", 34 | "%tensorflow_version 2.x\n", 35 | "from tensorflow import keras\n", 36 | "from tensorflow.keras.models import *\n", 37 | "from tensorflow.keras.layers import *\n", 38 | "from tensorflow.keras.optimizers import *\n", 39 | "\n", 40 | "import numpy as np\n", 41 | "import pandas as pd\n", 42 | "import matplotlib.pyplot as plt\n", 43 | "\n", 44 | "print(\"TensorFlow version: \", tf.__version__)\n", 45 | "assert version.parse(tf.__version__).release[0] >= 2, \\\n", 46 | " \"This notebook requires TensorFlow 2.0 or above.\"" 47 | ] 48 | }, 49 | { 50 | "cell_type": "code", 51 | "execution_count": null, 52 | "metadata": {}, 53 | "outputs": [], 54 | "source": [ 55 | "# Install segmetation_models library (https://github.com/qubvel/segmentation_models)\n", 56 | "pip install segmentation_models" 57 | ] 58 | }, 59 | { 60 | "cell_type": "code", 61 | "execution_count": null, 62 | "metadata": {}, 63 | "outputs": [], 64 | "source": [ 65 | "# Load segmentation)models library \n", 66 | "import segmentation_models as sm" 67 | ] 68 | }, 69 | { 70 | "cell_type": "markdown", 71 | "metadata": {}, 72 | "source": [ 73 | "#### 32 x 32 models" 74 | ] 75 | }, 76 | { 77 | "cell_type": "code", 78 | "execution_count": null, 79 | "metadata": {}, 80 | "outputs": [], 81 | "source": [ 82 | "# Load training data 32x32 - random - the Strings are the directions to the .npy files in google drive\n", 83 | "X_train = np.load(\"/content/drive/My Drive/Mestrado/artigo/artigo_final/data/augmented/32_32/random/arrays/X_train_32_random.npy\")\n", 84 | "Y_train = np.load(\"/content/drive/My Drive/Mestrado/artigo/artigo_final/data/augmented/32_32/random/arrays/Y_train_32_random.npy\")\n", 85 | "\n", 86 | "# Load test data - Area 1\n", 87 | "X_test_area_1 = np.load(\"/content/drive/My Drive/Mestrado/artigo/artigo_final/data/test/test_without_terrain/area_1/arrays/X_test_test_area_1.npy\")\n", 88 | "Y_test_area_1 = np.load(\"/content/drive/My Drive/Mestrado/artigo/artigo_final/data/test/test_without_terrain/area_1/arrays/Y_test_test_area_1.npy\")\n", 89 | "\n", 90 | "# Load test data - Area 2\n", 91 | "X_test_area_2 = np.load(\"/content/drive/My Drive/Mestrado/artigo/artigo_final/data/test/test_without_terrain/area_2/arrays/X_test_test_area_2.npy\")\n", 92 | "Y_test_area_2 = np.load(\"/content/drive/My Drive/Mestrado/artigo/artigo_final/data/test/test_without_terrain/area_2/arrays/Y_test_test_area_2.npy\")" 93 | ] 94 | }, 95 | { 96 | "cell_type": "code", 97 | "execution_count": null, 98 | "metadata": {}, 99 | "outputs": [], 100 | "source": [ 101 | "# Evaluate data dimensions\n", 102 | "print(f\"X_train shape: {X_train.shape}, Y_train shape: {Y_train.shape}\\nX_test_area_1 shape: {X_test_area_1.shape}, Y_test_area_1 shape: {Y_test_area_1.shape},\\nX_test_area_2 shape: {X_test_area_2.shape}, Y_test_area_2 shape: {Y_test_area_2.shape}\")" 103 | ] 104 | }, 105 | { 106 | "cell_type": "code", 107 | "execution_count": null, 108 | "metadata": {}, 109 | "outputs": [], 110 | "source": [ 111 | "# Evaluation Metrics - Precision, Recall, FScore, IoU\n", 112 | "metrics = [sm.metrics.Precision(threshold=0.5),sm.metrics.Recall(threshold=0.5),sm.metrics.FScore(threshold=0.5,beta=1),sm.metrics.IOUScore(threshold=0.5)]" 113 | ] 114 | }, 115 | { 116 | "cell_type": "code", 117 | "execution_count": null, 118 | "metadata": {}, 119 | "outputs": [], 120 | "source": [ 121 | "# Unet Architecture\n", 122 | "def Unet_Original(lr,filtersFirstLayer, pretrained_weights = None,input_size = (32,32,5)):\n", 123 | " inputs = Input(input_size)\n", 124 | " conv1 = Conv2D(filtersFirstLayer, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(inputs)\n", 125 | " conv1 = Conv2D(filtersFirstLayer, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(conv1)\n", 126 | " pool1 = MaxPooling2D(pool_size=(2, 2))(conv1)\n", 127 | " conv2 = Conv2D(filtersFirstLayer*2, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(pool1)\n", 128 | " conv2 = Conv2D(filtersFirstLayer*2, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(conv2)\n", 129 | " pool2 = MaxPooling2D(pool_size=(2, 2))(conv2)\n", 130 | " conv3 = Conv2D(filtersFirstLayer*4, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(pool2)\n", 131 | " conv3 = Conv2D(filtersFirstLayer*4, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(conv3)\n", 132 | " pool3 = MaxPooling2D(pool_size=(2, 2))(conv3)\n", 133 | " conv4 = Conv2D(filtersFirstLayer*8, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(pool3)\n", 134 | " conv4 = Conv2D(filtersFirstLayer*8, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(conv4)\n", 135 | " pool4 = MaxPooling2D(pool_size=(2, 2))(conv4)\n", 136 | "\n", 137 | " conv5 = Conv2D(filtersFirstLayer*16, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(pool4)\n", 138 | " conv5 = Conv2D(filtersFirstLayer*16, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(conv5)\n", 139 | "\n", 140 | " up6 = Conv2D(filtersFirstLayer*8, 2, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(UpSampling2D(size = (2,2))(conv5))\n", 141 | " merge6 = concatenate([conv4,up6], axis = 3)\n", 142 | " conv6 = Conv2D(filtersFirstLayer*8, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(merge6)\n", 143 | " conv6 = Conv2D(filtersFirstLayer*8, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(conv6)\n", 144 | "\n", 145 | " up7 = Conv2D(filtersFirstLayer*4, 2, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(UpSampling2D(size = (2,2))(conv6))\n", 146 | " merge7 = concatenate([conv3,up7], axis = 3)\n", 147 | " conv7 = Conv2D(filtersFirstLayer*4, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(merge7)\n", 148 | " conv7 = Conv2D(filtersFirstLayer*4, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(conv7)\n", 149 | "\n", 150 | " up8 = Conv2D(filtersFirstLayer*2, 2, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(UpSampling2D(size = (2,2))(conv7))\n", 151 | " merge8 = concatenate([conv2,up8], axis = 3)\n", 152 | " conv8 = Conv2D(filtersFirstLayer*2, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(merge8)\n", 153 | " conv8 = Conv2D(filtersFirstLayer*2, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(conv8)\n", 154 | "\n", 155 | " up9 = Conv2D(filtersFirstLayer, 2, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(UpSampling2D(size = (2,2))(conv8))\n", 156 | " merge9 = concatenate([conv1,up9], axis = 3)\n", 157 | " conv9 = Conv2D(filtersFirstLayer, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(merge9)\n", 158 | " conv9 = Conv2D(filtersFirstLayer, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(conv9)\n", 159 | " conv9 = Conv2D(2, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(conv9)\n", 160 | " conv10 = Conv2D(1, 1, activation = 'sigmoid')(conv9)\n", 161 | "\n", 162 | " model = Model(inputs, conv10)\n", 163 | "\n", 164 | " model.compile(optimizer = Adam(lr = lr), loss = 'binary_crossentropy', metrics = metrics)\n", 165 | " \n", 166 | " model.summary()\n", 167 | "\n", 168 | " if(pretrained_weights):\n", 169 | " \tmodel.load_weights(pretrained_weights)\n", 170 | "\n", 171 | " return model" 172 | ] 173 | }, 174 | { 175 | "cell_type": "code", 176 | "execution_count": null, 177 | "metadata": {}, 178 | "outputs": [], 179 | "source": [ 180 | "# Model training - Results are saved in a .csv file\n", 181 | "\n", 182 | "# size of the tiles\n", 183 | "size = 32\n", 184 | "# Sampling method\n", 185 | "sampling = \"random\"\n", 186 | "# number of filters \n", 187 | "filters = [16,32,64]\n", 188 | "# lr = 0.001\n", 189 | "lr = [10e-4]\n", 190 | "# batch sizes \n", 191 | "batch_size = [16,32,64,128]\n", 192 | "\n", 193 | "# dictionary that will save the results\n", 194 | "dic = {}\n", 195 | "\n", 196 | "# Hyperparameters\n", 197 | "dic[\"model\"] = []\n", 198 | "dic[\"batch_size\"] = []\n", 199 | "dic[\"learning_rate\"] = []\n", 200 | "dic[\"filters\"] = []\n", 201 | "\n", 202 | "# test area 1\n", 203 | "dic[\"precision_area_1\"] = []\n", 204 | "dic[\"recall_area_1\"] = []\n", 205 | "dic[\"f1_score_area_1\"] = []\n", 206 | "dic[\"iou_score_area_1\"] = []\n", 207 | "\n", 208 | "# test area 2\n", 209 | "dic[\"precision_area_2\"] = []\n", 210 | "dic[\"recall_area_2\"] = []\n", 211 | "dic[\"f1_score_area_2\"] = []\n", 212 | "dic[\"iou_score_area_2\"] = []\n", 213 | "\n", 214 | "\n", 215 | "\n", 216 | "\n", 217 | "# loop over all the filters in the filter list\n", 218 | "for fiilter in filters:\n", 219 | " # loop over the learning rates (used to evalute 0.01 and 0.0001 without good results)\n", 220 | " for learning_rate in lr:\n", 221 | " # loop over all batch sizes in batch_size list\n", 222 | " for batch in batch_size:\n", 223 | " # load the model\n", 224 | " model = Unet_Original(filtersFirstLayer= fiilter, lr = learning_rate)\n", 225 | " # Save the models only when validation loss decrease\n", 226 | " model_checkpoint = tf.keras.callbacks.ModelCheckpoint(f'/content/drive/My Drive/Mestrado/artigo/artigo_final/results/augmented/{size}_{size}/{sampling}/model/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}_lr_{learning_rate}.hdf5', monitor='val_loss', mode='min',verbose=1, save_best_only=True,save_weights_only = True)\n", 227 | " # Stop after 20 epochs without decreasing the validation loss\n", 228 | " early_stopping = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=20)\n", 229 | " print(fiilter, learning_rate,batch)\n", 230 | " # fit the model 30% of the dataset was used as validation\n", 231 | " history = model.fit(X_train,Y_train,batch_size = batch,epochs=200,validation_split=0.3,callbacks=[model_checkpoint, early_stopping])\n", 232 | "\n", 233 | " # summarize history for iou score\n", 234 | " plt.plot(history.history['iou_score'])\n", 235 | " plt.plot(history.history['val_iou_score'])\n", 236 | " plt.title('model accuracy')\n", 237 | " plt.ylabel('accuracy')\n", 238 | " plt.xlabel('epoch')\n", 239 | " plt.legend(['train', 'validation'], loc='upper left')\n", 240 | " # save plots \n", 241 | " plt.savefig(f\"/content/drive/My Drive/Mestrado/artigo/artigo_final/results/augmented/{size}_{size}/{sampling}/plots/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}_lr_{learning_rate}_iou_score.png\")\n", 242 | " plt.show()\n", 243 | " # summarize history for loss\n", 244 | " plt.plot(history.history['loss'])\n", 245 | " plt.plot(history.history['val_loss'])\n", 246 | " plt.title('model loss')\n", 247 | " plt.ylabel('loss')\n", 248 | " plt.xlabel('epoch')\n", 249 | " plt.legend(['train', 'validation'], loc='upper left')\n", 250 | " plt.savefig(f\"/content/drive/My Drive/Mestrado/artigo/artigo_final/results/augmented/{size}_{size}/{sampling}/plots/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}_lr_{learning_rate}_val_loss.png\")\n", 251 | " plt.show()\n", 252 | " \n", 253 | " # load unet to evaluate the test data\n", 254 | " unet_original = Unet_Original(filtersFirstLayer= fiilter, lr = learning_rate,input_size=(1024,1024,5))\n", 255 | " # load the last saved weight from the training\n", 256 | " unet_original.load_weights(f\"/content/drive/My Drive/Mestrado/artigo/artigo_final/results/augmented/{size}_{size}/{sampling}/model/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}_lr_{learning_rate}.hdf5\")\n", 257 | " \n", 258 | " # Evaluate test area 1\n", 259 | " res_1 = unet_original.evaluate(X_test_area_1,Y_test_area_1)\n", 260 | " \n", 261 | " # Evaluate test area 2\n", 262 | " res_2 = unet_original.evaluate(X_test_area_2,Y_test_area_2)\n", 263 | "\n", 264 | " # Data to plot the predicted output\n", 265 | " preds_train_1 = unet_original.predict(X_test_area_1, verbose=1)\n", 266 | " preds_train_t1 = (preds_train_1 > 0.5).astype(np.uint8)\n", 267 | " preds_train_2 = unet_original.predict(X_test_area_2, verbose=1)\n", 268 | " preds_train_t2 = (preds_train_2 > 0.5).astype(np.uint8)\n", 269 | "\n", 270 | "\n", 271 | " # save results on the dictionary\n", 272 | " dic[\"model\"].append(\"Unet\")\n", 273 | " dic[\"batch_size\"].append(batch)\n", 274 | " dic[\"learning_rate\"].append(learning_rate)\n", 275 | " dic[\"filters\"].append(fiilter)\n", 276 | " dic[\"precision_area_1\"].append(res_1[1])\n", 277 | " dic[\"recall_area_1\"].append(res_1[2])\n", 278 | " dic[\"f1_score_area_1\"].append(res_1[3])\n", 279 | " dic[\"iou_score_area_1\"].append(res_1[4])\n", 280 | " \n", 281 | " dic[\"precision_area_2\"].append(res_2[1])\n", 282 | " dic[\"recall_area_2\"].append(res_2[2])\n", 283 | " dic[\"f1_score_area_2\"].append(res_2[3])\n", 284 | " dic[\"iou_score_area_2\"].append(res_2[4])\n", 285 | " \n", 286 | " \n", 287 | " # Plot the results and save the plots\n", 288 | " f, axarr = plt.subplots(2,3,figsize=(10,10))\n", 289 | " axarr[0,0].imshow(X_test_area_1[0][:,:,:3])\n", 290 | " axarr[0,1].imshow(np.squeeze(preds_train_t1[0]))\n", 291 | " axarr[0,2].imshow(np.squeeze(Y_test_area_1[0]))\n", 292 | " axarr[1,0].imshow(X_test_area_2[0][:,:,:3])\n", 293 | " axarr[1,1].imshow(np.squeeze(preds_train_t2[0]))\n", 294 | " axarr[1,2].imshow(np.squeeze(Y_test_area_2[0]))\n", 295 | " f.savefig(f\"/content/drive/My Drive/Mestrado/artigo/artigo_final/results/augmented/{size}_{size}/{sampling}/images/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}_lr_{learning_rate}_result.png\")\n", 296 | " \n", 297 | " # Convert results to a dataframe\n", 298 | " results = pd.DataFrame(dic)\n", 299 | " # Export as csv\n", 300 | " results.to_csv(f'/content/drive/My Drive/Mestrado/artigo/artigo_final/results/augmented/{size}_{size}/{sampling}/result_table/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}.csv', index = False)" 301 | ] 302 | }, 303 | { 304 | "cell_type": "markdown", 305 | "metadata": {}, 306 | "source": [ 307 | "#### 64 x 64 models" 308 | ] 309 | }, 310 | { 311 | "cell_type": "code", 312 | "execution_count": null, 313 | "metadata": {}, 314 | "outputs": [], 315 | "source": [ 316 | "# Load training data 64x64 - random \n", 317 | "X_train = np.load(\"/content/drive/My Drive/Mestrado/artigo/artigo_final/data/augmented/64_64/random/arrays/X_train_64_random.npy\")\n", 318 | "Y_train = np.load(\"/content/drive/My Drive/Mestrado/artigo/artigo_final/data/augmented/64_64/random/arrays/Y_train_64_random.npy\")" 319 | ] 320 | }, 321 | { 322 | "cell_type": "code", 323 | "execution_count": null, 324 | "metadata": {}, 325 | "outputs": [], 326 | "source": [ 327 | "# Evaluate data dimensions\n", 328 | "print(f\"X_train shape: {X_train.shape}, Y_train shape: {Y_train.shape}\\nX_test_area_1 shape: {X_test_area_1.shape}, Y_test_area_1 shape: {Y_test_area_1.shape},\\nX_test_area_2 shape: {X_test_area_2.shape}, Y_test_area_2 shape: {Y_test_area_2.shape}\")" 329 | ] 330 | }, 331 | { 332 | "cell_type": "code", 333 | "execution_count": null, 334 | "metadata": {}, 335 | "outputs": [], 336 | "source": [ 337 | "# Model training - Results are saved in a .csv file\n", 338 | "\n", 339 | "# size of the tiles\n", 340 | "size = 64\n", 341 | "# Sampling method\n", 342 | "sampling = \"random\"\n", 343 | "# number of filters \n", 344 | "filters = [16,32,64]\n", 345 | "# lr = 0.001\n", 346 | "lr = [10e-4]\n", 347 | "# batch sizes \n", 348 | "batch_size = [16,32,64,128]\n", 349 | "\n", 350 | "# dictionary that will save the results\n", 351 | "dic = {}\n", 352 | "\n", 353 | "# Hyperparameters\n", 354 | "dic[\"model\"] = []\n", 355 | "dic[\"batch_size\"] = []\n", 356 | "dic[\"learning_rate\"] = []\n", 357 | "dic[\"filters\"] = []\n", 358 | "\n", 359 | "# test area 1\n", 360 | "dic[\"precision_area_1\"] = []\n", 361 | "dic[\"recall_area_1\"] = []\n", 362 | "dic[\"f1_score_area_1\"] = []\n", 363 | "dic[\"iou_score_area_1\"] = []\n", 364 | "\n", 365 | "# test area 2\n", 366 | "dic[\"precision_area_2\"] = []\n", 367 | "dic[\"recall_area_2\"] = []\n", 368 | "dic[\"f1_score_area_2\"] = []\n", 369 | "dic[\"iou_score_area_2\"] = []\n", 370 | "\n", 371 | "\n", 372 | "\n", 373 | "\n", 374 | "# loop over all the filters in the filter list\n", 375 | "for fiilter in filters:\n", 376 | " # loop over the learning rates (used to evalute 0.01 and 0.0001 without good results)\n", 377 | " for learning_rate in lr:\n", 378 | " # loop over all batch sizes in batch_size list\n", 379 | " for batch in batch_size:\n", 380 | " # load the model\n", 381 | " model = Unet_Original(filtersFirstLayer= fiilter, lr = learning_rate, input_size = (64,64,5))\n", 382 | " # Save the models only when validation loss decrease\n", 383 | " model_checkpoint = tf.keras.callbacks.ModelCheckpoint(f'/content/drive/My Drive/Mestrado/artigo/artigo_final/results/augmented/{size}_{size}/{sampling}/model/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}_lr_{learning_rate}.hdf5', monitor='val_loss', mode='min',verbose=1, save_best_only=True,save_weights_only = True)\n", 384 | " # Stop after 20 epochs without decreasing the validation loss\n", 385 | " early_stopping = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=20)\n", 386 | " print(fiilter, learning_rate,batch)\n", 387 | " # fit the model 30% of the dataset was used as validation\n", 388 | " history = model.fit(X_train,Y_train,batch_size = batch,epochs=200,validation_split=0.3,callbacks=[model_checkpoint, early_stopping])\n", 389 | "\n", 390 | " # summarize history for iou score\n", 391 | " plt.plot(history.history['iou_score'])\n", 392 | " plt.plot(history.history['val_iou_score'])\n", 393 | " plt.title('model accuracy')\n", 394 | " plt.ylabel('accuracy')\n", 395 | " plt.xlabel('epoch')\n", 396 | " plt.legend(['train', 'validation'], loc='upper left')\n", 397 | " # save plots \n", 398 | " plt.savefig(f\"/content/drive/My Drive/Mestrado/artigo/artigo_final/results/augmented/{size}_{size}/{sampling}/plots/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}_lr_{learning_rate}_iou_score.png\")\n", 399 | " plt.show()\n", 400 | " # summarize history for loss\n", 401 | " plt.plot(history.history['loss'])\n", 402 | " plt.plot(history.history['val_loss'])\n", 403 | " plt.title('model loss')\n", 404 | " plt.ylabel('loss')\n", 405 | " plt.xlabel('epoch')\n", 406 | " plt.legend(['train', 'validation'], loc='upper left')\n", 407 | " plt.savefig(f\"/content/drive/My Drive/Mestrado/artigo/artigo_final/results/augmented/{size}_{size}/{sampling}/plots/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}_lr_{learning_rate}_val_loss.png\")\n", 408 | " plt.show()\n", 409 | " \n", 410 | " # load unet to evaluate the test data\n", 411 | " unet_original = Unet_Original(filtersFirstLayer= fiilter, lr = learning_rate,input_size=(1024,1024,5))\n", 412 | " # load the last saved weight from the training\n", 413 | " unet_original.load_weights(f\"/content/drive/My Drive/Mestrado/artigo/artigo_final/results/augmented/{size}_{size}/{sampling}/model/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}_lr_{learning_rate}.hdf5\")\n", 414 | " \n", 415 | " # Evaluate test area 1\n", 416 | " res_1 = unet_original.evaluate(X_test_area_1,Y_test_area_1)\n", 417 | " \n", 418 | " # Evaluate test area 2\n", 419 | " res_2 = unet_original.evaluate(X_test_area_2,Y_test_area_2)\n", 420 | "\n", 421 | " # Data to plot the predicted output\n", 422 | " preds_train_1 = unet_original.predict(X_test_area_1, verbose=1)\n", 423 | " preds_train_t1 = (preds_train_1 > 0.5).astype(np.uint8)\n", 424 | " preds_train_2 = unet_original.predict(X_test_area_2, verbose=1)\n", 425 | " preds_train_t2 = (preds_train_2 > 0.5).astype(np.uint8)\n", 426 | "\n", 427 | "\n", 428 | " # save results on the dictionary\n", 429 | " dic[\"model\"].append(\"Unet\")\n", 430 | " dic[\"batch_size\"].append(batch)\n", 431 | " dic[\"learning_rate\"].append(learning_rate)\n", 432 | " dic[\"filters\"].append(fiilter)\n", 433 | " dic[\"precision_area_1\"].append(res_1[1])\n", 434 | " dic[\"recall_area_1\"].append(res_1[2])\n", 435 | " dic[\"f1_score_area_1\"].append(res_1[3])\n", 436 | " dic[\"iou_score_area_1\"].append(res_1[4])\n", 437 | " \n", 438 | " dic[\"precision_area_2\"].append(res_2[1])\n", 439 | " dic[\"recall_area_2\"].append(res_2[2])\n", 440 | " dic[\"f1_score_area_2\"].append(res_2[3])\n", 441 | " dic[\"iou_score_area_2\"].append(res_2[4])\n", 442 | " \n", 443 | " \n", 444 | " # Plot the results and save the plots\n", 445 | " f, axarr = plt.subplots(2,3,figsize=(10,10))\n", 446 | " axarr[0,0].imshow(X_test_area_1[0][:,:,:3])\n", 447 | " axarr[0,1].imshow(np.squeeze(preds_train_t1[0]))\n", 448 | " axarr[0,2].imshow(np.squeeze(Y_test_area_1[0]))\n", 449 | " axarr[1,0].imshow(X_test_area_2[0][:,:,:3])\n", 450 | " axarr[1,1].imshow(np.squeeze(preds_train_t2[0]))\n", 451 | " axarr[1,2].imshow(np.squeeze(Y_test_area_2[0]))\n", 452 | " f.savefig(f\"/content/drive/My Drive/Mestrado/artigo/artigo_final/results/augmented/{size}_{size}/{sampling}/images/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}_lr_{learning_rate}_result.png\")\n", 453 | " \n", 454 | " # Convert results to a dataframe\n", 455 | " results = pd.DataFrame(dic)\n", 456 | " # Export as csv\n", 457 | " results.to_csv(f'/content/drive/My Drive/Mestrado/artigo/artigo_final/results/augmented/{size}_{size}/{sampling}/result_table/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}.csv', index = False)" 458 | ] 459 | }, 460 | { 461 | "cell_type": "markdown", 462 | "metadata": {}, 463 | "source": [ 464 | "#### 128 x 128 models" 465 | ] 466 | }, 467 | { 468 | "cell_type": "code", 469 | "execution_count": null, 470 | "metadata": {}, 471 | "outputs": [], 472 | "source": [ 473 | "# Load training data 128x128 - random \n", 474 | "X_train = np.load(\"/content/drive/My Drive/Mestrado/artigo/artigo_final/data/augmented/128_128/random/arrays/X_train_128_random.npy\")\n", 475 | "Y_train = np.load(\"/content/drive/My Drive/Mestrado/artigo/artigo_final/data/augmented/128_128/random/arrays/Y_train_128_random.npy\")" 476 | ] 477 | }, 478 | { 479 | "cell_type": "code", 480 | "execution_count": null, 481 | "metadata": {}, 482 | "outputs": [], 483 | "source": [ 484 | "# Evaluate data dimensions\n", 485 | "print(f\"X_train shape: {X_train.shape}, Y_train shape: {Y_train.shape}\\nX_test_area_1 shape: {X_test_area_1.shape}, Y_test_area_1 shape: {Y_test_area_1.shape},\\nX_test_area_2 shape: {X_test_area_2.shape}, Y_test_area_2 shape: {Y_test_area_2.shape}\")" 486 | ] 487 | }, 488 | { 489 | "cell_type": "code", 490 | "execution_count": null, 491 | "metadata": {}, 492 | "outputs": [], 493 | "source": [ 494 | "# Model training - Results are saved in a .csv file\n", 495 | "\n", 496 | "# size of the tiles\n", 497 | "size = 128\n", 498 | "# Sampling method\n", 499 | "sampling = \"random\"\n", 500 | "# number of filters \n", 501 | "filters = [16,32,64]\n", 502 | "# lr = 0.001\n", 503 | "lr = [10e-4]\n", 504 | "# batch sizes \n", 505 | "batch_size = [16,32,64,128]\n", 506 | "\n", 507 | "# dictionary that will save the results\n", 508 | "dic = {}\n", 509 | "\n", 510 | "# Hyperparameters\n", 511 | "dic[\"model\"] = []\n", 512 | "dic[\"batch_size\"] = []\n", 513 | "dic[\"learning_rate\"] = []\n", 514 | "dic[\"filters\"] = []\n", 515 | "\n", 516 | "# test area 1\n", 517 | "dic[\"precision_area_1\"] = []\n", 518 | "dic[\"recall_area_1\"] = []\n", 519 | "dic[\"f1_score_area_1\"] = []\n", 520 | "dic[\"iou_score_area_1\"] = []\n", 521 | "\n", 522 | "# test area 2\n", 523 | "dic[\"precision_area_2\"] = []\n", 524 | "dic[\"recall_area_2\"] = []\n", 525 | "dic[\"f1_score_area_2\"] = []\n", 526 | "dic[\"iou_score_area_2\"] = []\n", 527 | "\n", 528 | "\n", 529 | "\n", 530 | "\n", 531 | "# loop over all the filters in the filter list\n", 532 | "for fiilter in filters:\n", 533 | " # loop over the learning rates (used to evalute 0.01 and 0.0001 without good results)\n", 534 | " for learning_rate in lr:\n", 535 | " # loop over all batch sizes in batch_size list\n", 536 | " for batch in batch_size:\n", 537 | " # load the model\n", 538 | " model = Unet_Original(filtersFirstLayer= fiilter, lr = learning_rate, input_size = (128,128,5))\n", 539 | " # Save the models only when validation loss decrease\n", 540 | " model_checkpoint = tf.keras.callbacks.ModelCheckpoint(f'/content/drive/My Drive/Mestrado/artigo/artigo_final/results/augmented/{size}_{size}/{sampling}/model/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}_lr_{learning_rate}.hdf5', monitor='val_loss', mode='min',verbose=1, save_best_only=True,save_weights_only = True)\n", 541 | " # Stop after 20 epochs without decreasing the validation loss\n", 542 | " early_stopping = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=20)\n", 543 | " print(fiilter, learning_rate,batch)\n", 544 | " # fit the model 30% of the dataset was used as validation\n", 545 | " history = model.fit(X_train,Y_train,batch_size = batch,epochs=200,validation_split=0.3,callbacks=[model_checkpoint, early_stopping])\n", 546 | "\n", 547 | " # summarize history for iou score\n", 548 | " plt.plot(history.history['iou_score'])\n", 549 | " plt.plot(history.history['val_iou_score'])\n", 550 | " plt.title('model accuracy')\n", 551 | " plt.ylabel('accuracy')\n", 552 | " plt.xlabel('epoch')\n", 553 | " plt.legend(['train', 'validation'], loc='upper left')\n", 554 | " # save plots \n", 555 | " plt.savefig(f\"/content/drive/My Drive/Mestrado/artigo/artigo_final/results/augmented/{size}_{size}/{sampling}/plots/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}_lr_{learning_rate}_iou_score.png\")\n", 556 | " plt.show()\n", 557 | " # summarize history for loss\n", 558 | " plt.plot(history.history['loss'])\n", 559 | " plt.plot(history.history['val_loss'])\n", 560 | " plt.title('model loss')\n", 561 | " plt.ylabel('loss')\n", 562 | " plt.xlabel('epoch')\n", 563 | " plt.legend(['train', 'validation'], loc='upper left')\n", 564 | " plt.savefig(f\"/content/drive/My Drive/Mestrado/artigo/artigo_final/results/augmented/{size}_{size}/{sampling}/plots/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}_lr_{learning_rate}_val_loss.png\")\n", 565 | " plt.show()\n", 566 | " \n", 567 | " # load unet to evaluate the test data\n", 568 | " unet_original = Unet_Original(filtersFirstLayer= fiilter, lr = learning_rate,input_size=(1024,1024,5))\n", 569 | " # load the last saved weight from the training\n", 570 | " unet_original.load_weights(f\"/content/drive/My Drive/Mestrado/artigo/artigo_final/results/augmented/{size}_{size}/{sampling}/model/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}_lr_{learning_rate}.hdf5\")\n", 571 | " \n", 572 | " # Evaluate test area 1\n", 573 | " res_1 = unet_original.evaluate(X_test_area_1,Y_test_area_1)\n", 574 | " \n", 575 | " # Evaluate test area 2\n", 576 | " res_2 = unet_original.evaluate(X_test_area_2,Y_test_area_2)\n", 577 | "\n", 578 | " # Data to plot the predicted output\n", 579 | " preds_train_1 = unet_original.predict(X_test_area_1, verbose=1)\n", 580 | " preds_train_t1 = (preds_train_1 > 0.5).astype(np.uint8)\n", 581 | " preds_train_2 = unet_original.predict(X_test_area_2, verbose=1)\n", 582 | " preds_train_t2 = (preds_train_2 > 0.5).astype(np.uint8)\n", 583 | "\n", 584 | "\n", 585 | " # save results on the dictionary\n", 586 | " dic[\"model\"].append(\"Unet\")\n", 587 | " dic[\"batch_size\"].append(batch)\n", 588 | " dic[\"learning_rate\"].append(learning_rate)\n", 589 | " dic[\"filters\"].append(fiilter)\n", 590 | " dic[\"precision_area_1\"].append(res_1[1])\n", 591 | " dic[\"recall_area_1\"].append(res_1[2])\n", 592 | " dic[\"f1_score_area_1\"].append(res_1[3])\n", 593 | " dic[\"iou_score_area_1\"].append(res_1[4])\n", 594 | " \n", 595 | " dic[\"precision_area_2\"].append(res_2[1])\n", 596 | " dic[\"recall_area_2\"].append(res_2[2])\n", 597 | " dic[\"f1_score_area_2\"].append(res_2[3])\n", 598 | " dic[\"iou_score_area_2\"].append(res_2[4])\n", 599 | " \n", 600 | " \n", 601 | " # Plot the results and save the plots\n", 602 | " f, axarr = plt.subplots(2,3,figsize=(10,10))\n", 603 | " axarr[0,0].imshow(X_test_area_1[0][:,:,:3])\n", 604 | " axarr[0,1].imshow(np.squeeze(preds_train_t1[0]))\n", 605 | " axarr[0,2].imshow(np.squeeze(Y_test_area_1[0]))\n", 606 | " axarr[1,0].imshow(X_test_area_2[0][:,:,:3])\n", 607 | " axarr[1,1].imshow(np.squeeze(preds_train_t2[0]))\n", 608 | " axarr[1,2].imshow(np.squeeze(Y_test_area_2[0]))\n", 609 | " f.savefig(f\"/content/drive/My Drive/Mestrado/artigo/artigo_final/results/augmented/{size}_{size}/{sampling}/images/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}_lr_{learning_rate}_result.png\")\n", 610 | " \n", 611 | " # Convert results to a dataframe\n", 612 | " results = pd.DataFrame(dic)\n", 613 | " # Export as csv\n", 614 | " results.to_csv(f'/content/drive/My Drive/Mestrado/artigo/artigo_final/results/augmented/{size}_{size}/{sampling}/result_table/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}.csv', index = False)" 615 | ] 616 | } 617 | ], 618 | "metadata": { 619 | "kernelspec": { 620 | "display_name": "Python 3", 621 | "language": "python", 622 | "name": "python3" 623 | }, 624 | "language_info": { 625 | "codemirror_mode": { 626 | "name": "ipython", 627 | "version": 3 628 | }, 629 | "file_extension": ".py", 630 | "mimetype": "text/x-python", 631 | "name": "python", 632 | "nbconvert_exporter": "python", 633 | "pygments_lexer": "ipython3", 634 | "version": "3.7.0" 635 | } 636 | }, 637 | "nbformat": 4, 638 | "nbformat_minor": 2 639 | } 640 | -------------------------------------------------------------------------------- /notebooks/Training_random_RapidEye.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Code used to train the RapidEye random models \n", 8 | "\n", 9 | "The models were trained in Google Colaboratory Virtual Environment, thus, to work properly, this notebook should be loaded in google drive.\n", 10 | "\n", 11 | "* [32x32 models](#32-x-32-models) \n", 12 | "\n", 13 | "* [64x64 models](#64-x-64-models) \n", 14 | "\n", 15 | "* [128x128 models](#128-x-128-models) " 16 | ] 17 | }, 18 | { 19 | "cell_type": "code", 20 | "execution_count": null, 21 | "metadata": {}, 22 | "outputs": [], 23 | "source": [ 24 | "# Import libraries\n", 25 | "\n", 26 | "import tensorflow as tf\n", 27 | "from __future__ import absolute_import\n", 28 | "from __future__ import division\n", 29 | "from __future__ import print_function\n", 30 | "\n", 31 | "from datetime import datetime\n", 32 | "from packaging import version\n", 33 | "\n", 34 | "%tensorflow_version 2.x\n", 35 | "from tensorflow import keras\n", 36 | "from tensorflow.keras.models import *\n", 37 | "from tensorflow.keras.layers import *\n", 38 | "from tensorflow.keras.optimizers import *\n", 39 | "\n", 40 | "import numpy as np\n", 41 | "import pandas as pd\n", 42 | "import matplotlib.pyplot as plt\n", 43 | "\n", 44 | "print(\"TensorFlow version: \", tf.__version__)\n", 45 | "assert version.parse(tf.__version__).release[0] >= 2, \\\n", 46 | " \"This notebook requires TensorFlow 2.0 or above.\"" 47 | ] 48 | }, 49 | { 50 | "cell_type": "code", 51 | "execution_count": null, 52 | "metadata": {}, 53 | "outputs": [], 54 | "source": [ 55 | "# Install segmetation_models library (https://github.com/qubvel/segmentation_models)\n", 56 | "pip install segmentation_models" 57 | ] 58 | }, 59 | { 60 | "cell_type": "code", 61 | "execution_count": null, 62 | "metadata": {}, 63 | "outputs": [], 64 | "source": [ 65 | "# Load segmentation)models library \n", 66 | "import segmentation_models as sm" 67 | ] 68 | }, 69 | { 70 | "cell_type": "markdown", 71 | "metadata": {}, 72 | "source": [ 73 | "#### 32 x 32 models" 74 | ] 75 | }, 76 | { 77 | "cell_type": "code", 78 | "execution_count": null, 79 | "metadata": {}, 80 | "outputs": [], 81 | "source": [ 82 | "# Load training data 32x32 - random - the Strings are the directions to the .npy files in google drive\n", 83 | "X_train = np.load(\"/content/drive/My Drive/Mestrado/artigo/artigo_final/data/non_augmented/32_32/random/arrays/X_train_32_random.npy\")\n", 84 | "Y_train = np.load(\"/content/drive/My Drive/Mestrado/artigo/artigo_final/data/non_augmented/32_32/random/arrays/Y_train_32_random.npy\")\n", 85 | "\n", 86 | "# Load test data - Area 1\n", 87 | "X_test_area_1 = np.load(\"/content/drive/My Drive/Mestrado/artigo/artigo_final/data/test/test_without_terrain/area_1/arrays/X_test_test_area_1.npy\")\n", 88 | "Y_test_area_1 = np.load(\"/content/drive/My Drive/Mestrado/artigo/artigo_final/data/test/test_without_terrain/area_1/arrays/Y_test_test_area_1.npy\")\n", 89 | "\n", 90 | "# Load test data - Area 2\n", 91 | "X_test_area_2 = np.load(\"/content/drive/My Drive/Mestrado/artigo/artigo_final/data/test/test_without_terrain/area_2/arrays/X_test_test_area_2.npy\")\n", 92 | "Y_test_area_2 = np.load(\"/content/drive/My Drive/Mestrado/artigo/artigo_final/data/test/test_without_terrain/area_2/arrays/Y_test_test_area_2.npy\")" 93 | ] 94 | }, 95 | { 96 | "cell_type": "code", 97 | "execution_count": null, 98 | "metadata": {}, 99 | "outputs": [], 100 | "source": [ 101 | "# Evaluate data dimensions\n", 102 | "print(f\"X_train shape: {X_train.shape}, Y_train shape: {Y_train.shape}\\nX_test_area_1 shape: {X_test_area_1.shape}, Y_test_area_1 shape: {Y_test_area_1.shape},\\nX_test_area_2 shape: {X_test_area_2.shape}, Y_test_area_2 shape: {Y_test_area_2.shape}\")" 103 | ] 104 | }, 105 | { 106 | "cell_type": "code", 107 | "execution_count": null, 108 | "metadata": {}, 109 | "outputs": [], 110 | "source": [ 111 | "# Evaluation Metrics - Precision, Recall, FScore, IoU\n", 112 | "metrics = [sm.metrics.Precision(threshold=0.5),sm.metrics.Recall(threshold=0.5),sm.metrics.FScore(threshold=0.5,beta=1),sm.metrics.IOUScore(threshold=0.5)]" 113 | ] 114 | }, 115 | { 116 | "cell_type": "code", 117 | "execution_count": null, 118 | "metadata": {}, 119 | "outputs": [], 120 | "source": [ 121 | "# Unet Architecture\n", 122 | "def Unet_Original(lr,filtersFirstLayer, pretrained_weights = None,input_size = (32,32,5)):\n", 123 | " inputs = Input(input_size)\n", 124 | " conv1 = Conv2D(filtersFirstLayer, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(inputs)\n", 125 | " conv1 = Conv2D(filtersFirstLayer, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(conv1)\n", 126 | " pool1 = MaxPooling2D(pool_size=(2, 2))(conv1)\n", 127 | " conv2 = Conv2D(filtersFirstLayer*2, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(pool1)\n", 128 | " conv2 = Conv2D(filtersFirstLayer*2, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(conv2)\n", 129 | " pool2 = MaxPooling2D(pool_size=(2, 2))(conv2)\n", 130 | " conv3 = Conv2D(filtersFirstLayer*4, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(pool2)\n", 131 | " conv3 = Conv2D(filtersFirstLayer*4, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(conv3)\n", 132 | " pool3 = MaxPooling2D(pool_size=(2, 2))(conv3)\n", 133 | " conv4 = Conv2D(filtersFirstLayer*8, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(pool3)\n", 134 | " conv4 = Conv2D(filtersFirstLayer*8, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(conv4)\n", 135 | " pool4 = MaxPooling2D(pool_size=(2, 2))(conv4)\n", 136 | "\n", 137 | " conv5 = Conv2D(filtersFirstLayer*16, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(pool4)\n", 138 | " conv5 = Conv2D(filtersFirstLayer*16, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(conv5)\n", 139 | "\n", 140 | " up6 = Conv2D(filtersFirstLayer*8, 2, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(UpSampling2D(size = (2,2))(conv5))\n", 141 | " merge6 = concatenate([conv4,up6], axis = 3)\n", 142 | " conv6 = Conv2D(filtersFirstLayer*8, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(merge6)\n", 143 | " conv6 = Conv2D(filtersFirstLayer*8, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(conv6)\n", 144 | "\n", 145 | " up7 = Conv2D(filtersFirstLayer*4, 2, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(UpSampling2D(size = (2,2))(conv6))\n", 146 | " merge7 = concatenate([conv3,up7], axis = 3)\n", 147 | " conv7 = Conv2D(filtersFirstLayer*4, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(merge7)\n", 148 | " conv7 = Conv2D(filtersFirstLayer*4, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(conv7)\n", 149 | "\n", 150 | " up8 = Conv2D(filtersFirstLayer*2, 2, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(UpSampling2D(size = (2,2))(conv7))\n", 151 | " merge8 = concatenate([conv2,up8], axis = 3)\n", 152 | " conv8 = Conv2D(filtersFirstLayer*2, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(merge8)\n", 153 | " conv8 = Conv2D(filtersFirstLayer*2, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(conv8)\n", 154 | "\n", 155 | " up9 = Conv2D(filtersFirstLayer, 2, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(UpSampling2D(size = (2,2))(conv8))\n", 156 | " merge9 = concatenate([conv1,up9], axis = 3)\n", 157 | " conv9 = Conv2D(filtersFirstLayer, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(merge9)\n", 158 | " conv9 = Conv2D(filtersFirstLayer, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(conv9)\n", 159 | " conv9 = Conv2D(2, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(conv9)\n", 160 | " conv10 = Conv2D(1, 1, activation = 'sigmoid')(conv9)\n", 161 | "\n", 162 | " model = Model(inputs, conv10)\n", 163 | "\n", 164 | " model.compile(optimizer = Adam(lr = lr), loss = 'binary_crossentropy', metrics = metrics)\n", 165 | " \n", 166 | " model.summary()\n", 167 | "\n", 168 | " if(pretrained_weights):\n", 169 | " \tmodel.load_weights(pretrained_weights)\n", 170 | "\n", 171 | " return model" 172 | ] 173 | }, 174 | { 175 | "cell_type": "code", 176 | "execution_count": null, 177 | "metadata": {}, 178 | "outputs": [], 179 | "source": [ 180 | "# Model training - Results are saved in a .csv file\n", 181 | "\n", 182 | "# size of the tiles\n", 183 | "size = 32\n", 184 | "# Sampling method\n", 185 | "sampling = \"random\"\n", 186 | "# number of filters \n", 187 | "filters = [16,32,64]\n", 188 | "# lr = 0.001\n", 189 | "lr = [10e-4]\n", 190 | "# batch sizes \n", 191 | "batch_size = [16,32,64,128]\n", 192 | "\n", 193 | "# dictionary that will save the results\n", 194 | "dic = {}\n", 195 | "\n", 196 | "# Hyperparameters\n", 197 | "dic[\"model\"] = []\n", 198 | "dic[\"batch_size\"] = []\n", 199 | "dic[\"learning_rate\"] = []\n", 200 | "dic[\"filters\"] = []\n", 201 | "\n", 202 | "# test area 1\n", 203 | "dic[\"precision_area_1\"] = []\n", 204 | "dic[\"recall_area_1\"] = []\n", 205 | "dic[\"f1_score_area_1\"] = []\n", 206 | "dic[\"iou_score_area_1\"] = []\n", 207 | "\n", 208 | "# test area 2\n", 209 | "dic[\"precision_area_2\"] = []\n", 210 | "dic[\"recall_area_2\"] = []\n", 211 | "dic[\"f1_score_area_2\"] = []\n", 212 | "dic[\"iou_score_area_2\"] = []\n", 213 | "\n", 214 | "\n", 215 | "\n", 216 | "\n", 217 | "# loop over all the filters in the filter list\n", 218 | "for fiilter in filters:\n", 219 | " # loop over the learning rates (used to evalute 0.01 and 0.0001 without good results)\n", 220 | " for learning_rate in lr:\n", 221 | " # loop over all batch sizes in batch_size list\n", 222 | " for batch in batch_size:\n", 223 | " # load the model\n", 224 | " model = Unet_Original(filtersFirstLayer= fiilter, lr = learning_rate)\n", 225 | " # Save the models only when validation loss decrease\n", 226 | " model_checkpoint = tf.keras.callbacks.ModelCheckpoint(f'/content/drive/My Drive/Mestrado/artigo/artigo_final/results/non_augmented/{size}_{size}/{sampling}/model/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}_lr_{learning_rate}.hdf5', monitor='val_loss', mode='min',verbose=1, save_best_only=True,save_weights_only = True)\n", 227 | " # Stop after 20 epochs without decreasing the validation loss\n", 228 | " early_stopping = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=20)\n", 229 | " print(fiilter, learning_rate,batch)\n", 230 | " # fit the model 30% of the dataset was used as validation\n", 231 | " history = model.fit(X_train,Y_train,batch_size = batch,epochs=200,validation_split=0.3,callbacks=[model_checkpoint, early_stopping])\n", 232 | "\n", 233 | " # summarize history for iou score\n", 234 | " plt.plot(history.history['iou_score'])\n", 235 | " plt.plot(history.history['val_iou_score'])\n", 236 | " plt.title('model accuracy')\n", 237 | " plt.ylabel('accuracy')\n", 238 | " plt.xlabel('epoch')\n", 239 | " plt.legend(['train', 'validation'], loc='upper left')\n", 240 | " # save plots \n", 241 | " plt.savefig(f\"/content/drive/My Drive/Mestrado/artigo/artigo_final/results/non_augmented/{size}_{size}/{sampling}/plots/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}_lr_{learning_rate}_iou_score.png\")\n", 242 | " plt.show()\n", 243 | " # summarize history for loss\n", 244 | " plt.plot(history.history['loss'])\n", 245 | " plt.plot(history.history['val_loss'])\n", 246 | " plt.title('model loss')\n", 247 | " plt.ylabel('loss')\n", 248 | " plt.xlabel('epoch')\n", 249 | " plt.legend(['train', 'validation'], loc='upper left')\n", 250 | " plt.savefig(f\"/content/drive/My Drive/Mestrado/artigo/artigo_final/results/non_augmented/{size}_{size}/{sampling}/plots/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}_lr_{learning_rate}_val_loss.png\")\n", 251 | " plt.show()\n", 252 | " \n", 253 | " # load unet to evaluate the test data\n", 254 | " unet_original = Unet_Original(filtersFirstLayer= fiilter, lr = learning_rate,input_size=(1024,1024,5))\n", 255 | " # load the last saved weight from the training\n", 256 | " unet_original.load_weights(f\"/content/drive/My Drive/Mestrado/artigo/artigo_final/results/non_augmented/{size}_{size}/{sampling}/model/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}_lr_{learning_rate}.hdf5\")\n", 257 | " \n", 258 | " # Evaluate test area 1\n", 259 | " res_1 = unet_original.evaluate(X_test_area_1,Y_test_area_1)\n", 260 | " \n", 261 | " # Evaluate test area 2\n", 262 | " res_2 = unet_original.evaluate(X_test_area_2,Y_test_area_2)\n", 263 | "\n", 264 | " # Data to plot the predicted output\n", 265 | " preds_train_1 = unet_original.predict(X_test_area_1, verbose=1)\n", 266 | " preds_train_t1 = (preds_train_1 > 0.5).astype(np.uint8)\n", 267 | " preds_train_2 = unet_original.predict(X_test_area_2, verbose=1)\n", 268 | " preds_train_t2 = (preds_train_2 > 0.5).astype(np.uint8)\n", 269 | "\n", 270 | "\n", 271 | " # save results on the dictionary\n", 272 | " dic[\"model\"].append(\"Unet\")\n", 273 | " dic[\"batch_size\"].append(batch)\n", 274 | " dic[\"learning_rate\"].append(learning_rate)\n", 275 | " dic[\"filters\"].append(fiilter)\n", 276 | " dic[\"precision_area_1\"].append(res_1[1])\n", 277 | " dic[\"recall_area_1\"].append(res_1[2])\n", 278 | " dic[\"f1_score_area_1\"].append(res_1[3])\n", 279 | " dic[\"iou_score_area_1\"].append(res_1[4])\n", 280 | " \n", 281 | " dic[\"precision_area_2\"].append(res_2[1])\n", 282 | " dic[\"recall_area_2\"].append(res_2[2])\n", 283 | " dic[\"f1_score_area_2\"].append(res_2[3])\n", 284 | " dic[\"iou_score_area_2\"].append(res_2[4])\n", 285 | " \n", 286 | " \n", 287 | " # Plot the results and save the plots\n", 288 | " f, axarr = plt.subplots(2,3,figsize=(10,10))\n", 289 | " axarr[0,0].imshow(X_test_area_1[0][:,:,:3])\n", 290 | " axarr[0,1].imshow(np.squeeze(preds_train_t1[0]))\n", 291 | " axarr[0,2].imshow(np.squeeze(Y_test_area_1[0]))\n", 292 | " axarr[1,0].imshow(X_test_area_2[0][:,:,:3])\n", 293 | " axarr[1,1].imshow(np.squeeze(preds_train_t2[0]))\n", 294 | " axarr[1,2].imshow(np.squeeze(Y_test_area_2[0]))\n", 295 | " f.savefig(f\"/content/drive/My Drive/Mestrado/artigo/artigo_final/results/non_augmented/{size}_{size}/{sampling}/images/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}_lr_{learning_rate}_result.png\")\n", 296 | " \n", 297 | " # Convert results to a dataframe\n", 298 | " results = pd.DataFrame(dic)\n", 299 | " # Export as csv\n", 300 | " results.to_csv(f'/content/drive/My Drive/Mestrado/artigo/artigo_final/results/non_augmented/{size}_{size}/{sampling}/result_table/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}.csv', index = False)" 301 | ] 302 | }, 303 | { 304 | "cell_type": "markdown", 305 | "metadata": {}, 306 | "source": [ 307 | "#### 64 x 64 models" 308 | ] 309 | }, 310 | { 311 | "cell_type": "code", 312 | "execution_count": null, 313 | "metadata": {}, 314 | "outputs": [], 315 | "source": [ 316 | "# Load training data 64x64 - random \n", 317 | "X_train = np.load(\"/content/drive/My Drive/Mestrado/artigo/artigo_final/data/non_augmented/64_64/random/arrays/X_train_64_random.npy\")\n", 318 | "Y_train = np.load(\"/content/drive/My Drive/Mestrado/artigo/artigo_final/data/non_augmented/64_64/random/arrays/Y_train_64_random.npy\")" 319 | ] 320 | }, 321 | { 322 | "cell_type": "code", 323 | "execution_count": null, 324 | "metadata": {}, 325 | "outputs": [], 326 | "source": [ 327 | "# Evaluate data dimensions\n", 328 | "print(f\"X_train shape: {X_train.shape}, Y_train shape: {Y_train.shape}\\nX_test_area_1 shape: {X_test_area_1.shape}, Y_test_area_1 shape: {Y_test_area_1.shape},\\nX_test_area_2 shape: {X_test_area_2.shape}, Y_test_area_2 shape: {Y_test_area_2.shape}\")" 329 | ] 330 | }, 331 | { 332 | "cell_type": "code", 333 | "execution_count": null, 334 | "metadata": {}, 335 | "outputs": [], 336 | "source": [ 337 | "# Model training - Results are saved in a .csv file\n", 338 | "\n", 339 | "# size of the tiles\n", 340 | "size = 64\n", 341 | "# Sampling method\n", 342 | "sampling = \"random\"\n", 343 | "# number of filters \n", 344 | "filters = [16,32,64]\n", 345 | "# lr = 0.001\n", 346 | "lr = [10e-4]\n", 347 | "# batch sizes \n", 348 | "batch_size = [16,32,64,128]\n", 349 | "\n", 350 | "# dictionary that will save the results\n", 351 | "dic = {}\n", 352 | "\n", 353 | "# Hyperparameters\n", 354 | "dic[\"model\"] = []\n", 355 | "dic[\"batch_size\"] = []\n", 356 | "dic[\"learning_rate\"] = []\n", 357 | "dic[\"filters\"] = []\n", 358 | "\n", 359 | "# test area 1\n", 360 | "dic[\"precision_area_1\"] = []\n", 361 | "dic[\"recall_area_1\"] = []\n", 362 | "dic[\"f1_score_area_1\"] = []\n", 363 | "dic[\"iou_score_area_1\"] = []\n", 364 | "\n", 365 | "# test area 2\n", 366 | "dic[\"precision_area_2\"] = []\n", 367 | "dic[\"recall_area_2\"] = []\n", 368 | "dic[\"f1_score_area_2\"] = []\n", 369 | "dic[\"iou_score_area_2\"] = []\n", 370 | "\n", 371 | "\n", 372 | "\n", 373 | "\n", 374 | "# loop over all the filters in the filter list\n", 375 | "for fiilter in filters:\n", 376 | " # loop over the learning rates (used to evalute 0.01 and 0.0001 without good results)\n", 377 | " for learning_rate in lr:\n", 378 | " # loop over all batch sizes in batch_size list\n", 379 | " for batch in batch_size:\n", 380 | " # load the model\n", 381 | " model = Unet_Original(filtersFirstLayer= fiilter, lr = learning_rate, input_size = (64,64,5))\n", 382 | " # Save the models only when validation loss decrease\n", 383 | " model_checkpoint = tf.keras.callbacks.ModelCheckpoint(f'/content/drive/My Drive/Mestrado/artigo/artigo_final/results/non_augmented/{size}_{size}/{sampling}/model/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}_lr_{learning_rate}.hdf5', monitor='val_loss', mode='min',verbose=1, save_best_only=True,save_weights_only = True)\n", 384 | " # Stop after 20 epochs without decreasing the validation loss\n", 385 | " early_stopping = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=20)\n", 386 | " print(fiilter, learning_rate,batch)\n", 387 | " # fit the model 30% of the dataset was used as validation\n", 388 | " history = model.fit(X_train,Y_train,batch_size = batch,epochs=200,validation_split=0.3,callbacks=[model_checkpoint, early_stopping])\n", 389 | "\n", 390 | " # summarize history for iou score\n", 391 | " plt.plot(history.history['iou_score'])\n", 392 | " plt.plot(history.history['val_iou_score'])\n", 393 | " plt.title('model accuracy')\n", 394 | " plt.ylabel('accuracy')\n", 395 | " plt.xlabel('epoch')\n", 396 | " plt.legend(['train', 'validation'], loc='upper left')\n", 397 | " # save plots \n", 398 | " plt.savefig(f\"/content/drive/My Drive/Mestrado/artigo/artigo_final/results/non_augmented/{size}_{size}/{sampling}/plots/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}_lr_{learning_rate}_iou_score.png\")\n", 399 | " plt.show()\n", 400 | " # summarize history for loss\n", 401 | " plt.plot(history.history['loss'])\n", 402 | " plt.plot(history.history['val_loss'])\n", 403 | " plt.title('model loss')\n", 404 | " plt.ylabel('loss')\n", 405 | " plt.xlabel('epoch')\n", 406 | " plt.legend(['train', 'validation'], loc='upper left')\n", 407 | " plt.savefig(f\"/content/drive/My Drive/Mestrado/artigo/artigo_final/results/non_augmented/{size}_{size}/{sampling}/plots/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}_lr_{learning_rate}_val_loss.png\")\n", 408 | " plt.show()\n", 409 | " \n", 410 | " # load unet to evaluate the test data\n", 411 | " unet_original = Unet_Original(filtersFirstLayer= fiilter, lr = learning_rate,input_size=(1024,1024,5))\n", 412 | " # load the last saved weight from the training\n", 413 | " unet_original.load_weights(f\"/content/drive/My Drive/Mestrado/artigo/artigo_final/results/non_augmented/{size}_{size}/{sampling}/model/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}_lr_{learning_rate}.hdf5\")\n", 414 | " \n", 415 | " # Evaluate test area 1\n", 416 | " res_1 = unet_original.evaluate(X_test_area_1,Y_test_area_1)\n", 417 | " \n", 418 | " # Evaluate test area 2\n", 419 | " res_2 = unet_original.evaluate(X_test_area_2,Y_test_area_2)\n", 420 | "\n", 421 | " # Data to plot the predicted output\n", 422 | " preds_train_1 = unet_original.predict(X_test_area_1, verbose=1)\n", 423 | " preds_train_t1 = (preds_train_1 > 0.5).astype(np.uint8)\n", 424 | " preds_train_2 = unet_original.predict(X_test_area_2, verbose=1)\n", 425 | " preds_train_t2 = (preds_train_2 > 0.5).astype(np.uint8)\n", 426 | "\n", 427 | "\n", 428 | " # save results on the dictionary\n", 429 | " dic[\"model\"].append(\"Unet\")\n", 430 | " dic[\"batch_size\"].append(batch)\n", 431 | " dic[\"learning_rate\"].append(learning_rate)\n", 432 | " dic[\"filters\"].append(fiilter)\n", 433 | " dic[\"precision_area_1\"].append(res_1[1])\n", 434 | " dic[\"recall_area_1\"].append(res_1[2])\n", 435 | " dic[\"f1_score_area_1\"].append(res_1[3])\n", 436 | " dic[\"iou_score_area_1\"].append(res_1[4])\n", 437 | " \n", 438 | " dic[\"precision_area_2\"].append(res_2[1])\n", 439 | " dic[\"recall_area_2\"].append(res_2[2])\n", 440 | " dic[\"f1_score_area_2\"].append(res_2[3])\n", 441 | " dic[\"iou_score_area_2\"].append(res_2[4])\n", 442 | " \n", 443 | " \n", 444 | " # Plot the results and save the plots\n", 445 | " f, axarr = plt.subplots(2,3,figsize=(10,10))\n", 446 | " axarr[0,0].imshow(X_test_area_1[0][:,:,:3])\n", 447 | " axarr[0,1].imshow(np.squeeze(preds_train_t1[0]))\n", 448 | " axarr[0,2].imshow(np.squeeze(Y_test_area_1[0]))\n", 449 | " axarr[1,0].imshow(X_test_area_2[0][:,:,:3])\n", 450 | " axarr[1,1].imshow(np.squeeze(preds_train_t2[0]))\n", 451 | " axarr[1,2].imshow(np.squeeze(Y_test_area_2[0]))\n", 452 | " f.savefig(f\"/content/drive/My Drive/Mestrado/artigo/artigo_final/results/non_augmented/{size}_{size}/{sampling}/images/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}_lr_{learning_rate}_result.png\")\n", 453 | " \n", 454 | " # Convert results to a dataframe\n", 455 | " results = pd.DataFrame(dic)\n", 456 | " # Export as csv\n", 457 | " results.to_csv(f'/content/drive/My Drive/Mestrado/artigo/artigo_final/results/non_augmented/{size}_{size}/{sampling}/result_table/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}.csv', index = False)" 458 | ] 459 | }, 460 | { 461 | "cell_type": "markdown", 462 | "metadata": {}, 463 | "source": [ 464 | "#### 128 x 128 models" 465 | ] 466 | }, 467 | { 468 | "cell_type": "code", 469 | "execution_count": null, 470 | "metadata": {}, 471 | "outputs": [], 472 | "source": [ 473 | "# Load training data 128x128 - random \n", 474 | "X_train = np.load(\"/content/drive/My Drive/Mestrado/artigo/artigo_final/data/non_augmented/128_128/random/arrays/X_train_128_random.npy\")\n", 475 | "Y_train = np.load(\"/content/drive/My Drive/Mestrado/artigo/artigo_final/data/non_augmented/128_128/random/arrays/Y_train_128_random.npy\")" 476 | ] 477 | }, 478 | { 479 | "cell_type": "code", 480 | "execution_count": null, 481 | "metadata": {}, 482 | "outputs": [], 483 | "source": [ 484 | "# Evaluate data dimensions\n", 485 | "print(f\"X_train shape: {X_train.shape}, Y_train shape: {Y_train.shape}\\nX_test_area_1 shape: {X_test_area_1.shape}, Y_test_area_1 shape: {Y_test_area_1.shape},\\nX_test_area_2 shape: {X_test_area_2.shape}, Y_test_area_2 shape: {Y_test_area_2.shape}\")" 486 | ] 487 | }, 488 | { 489 | "cell_type": "code", 490 | "execution_count": null, 491 | "metadata": {}, 492 | "outputs": [], 493 | "source": [ 494 | "# Model training - Results are saved in a .csv file\n", 495 | "\n", 496 | "# size of the tiles\n", 497 | "size = 128\n", 498 | "# Sampling method\n", 499 | "sampling = \"random\"\n", 500 | "# number of filters \n", 501 | "filters = [16,32,64]\n", 502 | "# lr = 0.001\n", 503 | "lr = [10e-4]\n", 504 | "# batch sizes \n", 505 | "batch_size = [16,32,64,128]\n", 506 | "\n", 507 | "# dictionary that will save the results\n", 508 | "dic = {}\n", 509 | "\n", 510 | "# Hyperparameters\n", 511 | "dic[\"model\"] = []\n", 512 | "dic[\"batch_size\"] = []\n", 513 | "dic[\"learning_rate\"] = []\n", 514 | "dic[\"filters\"] = []\n", 515 | "\n", 516 | "# test area 1\n", 517 | "dic[\"precision_area_1\"] = []\n", 518 | "dic[\"recall_area_1\"] = []\n", 519 | "dic[\"f1_score_area_1\"] = []\n", 520 | "dic[\"iou_score_area_1\"] = []\n", 521 | "\n", 522 | "# test area 2\n", 523 | "dic[\"precision_area_2\"] = []\n", 524 | "dic[\"recall_area_2\"] = []\n", 525 | "dic[\"f1_score_area_2\"] = []\n", 526 | "dic[\"iou_score_area_2\"] = []\n", 527 | "\n", 528 | "\n", 529 | "\n", 530 | "\n", 531 | "# loop over all the filters in the filter list\n", 532 | "for fiilter in filters:\n", 533 | " # loop over the learning rates (used to evalute 0.01 and 0.0001 without good results)\n", 534 | " for learning_rate in lr:\n", 535 | " # loop over all batch sizes in batch_size list\n", 536 | " for batch in batch_size:\n", 537 | " # load the model\n", 538 | " model = Unet_Original(filtersFirstLayer= fiilter, lr = learning_rate, input_size = (128,128,5))\n", 539 | " # Save the models only when validation loss decrease\n", 540 | " model_checkpoint = tf.keras.callbacks.ModelCheckpoint(f'/content/drive/My Drive/Mestrado/artigo/artigo_final/results/non_augmented/{size}_{size}/{sampling}/model/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}_lr_{learning_rate}.hdf5', monitor='val_loss', mode='min',verbose=1, save_best_only=True,save_weights_only = True)\n", 541 | " # Stop after 20 epochs without decreasing the validation loss\n", 542 | " early_stopping = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=20)\n", 543 | " print(fiilter, learning_rate,batch)\n", 544 | " # fit the model 30% of the dataset was used as validation\n", 545 | " history = model.fit(X_train,Y_train,batch_size = batch,epochs=200,validation_split=0.3,callbacks=[model_checkpoint, early_stopping])\n", 546 | "\n", 547 | " # summarize history for iou score\n", 548 | " plt.plot(history.history['iou_score'])\n", 549 | " plt.plot(history.history['val_iou_score'])\n", 550 | " plt.title('model accuracy')\n", 551 | " plt.ylabel('accuracy')\n", 552 | " plt.xlabel('epoch')\n", 553 | " plt.legend(['train', 'validation'], loc='upper left')\n", 554 | " # save plots \n", 555 | " plt.savefig(f\"/content/drive/My Drive/Mestrado/artigo/artigo_final/results/non_augmented/{size}_{size}/{sampling}/plots/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}_lr_{learning_rate}_iou_score.png\")\n", 556 | " plt.show()\n", 557 | " # summarize history for loss\n", 558 | " plt.plot(history.history['loss'])\n", 559 | " plt.plot(history.history['val_loss'])\n", 560 | " plt.title('model loss')\n", 561 | " plt.ylabel('loss')\n", 562 | " plt.xlabel('epoch')\n", 563 | " plt.legend(['train', 'validation'], loc='upper left')\n", 564 | " plt.savefig(f\"/content/drive/My Drive/Mestrado/artigo/artigo_final/results/non_augmented/{size}_{size}/{sampling}/plots/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}_lr_{learning_rate}_val_loss.png\")\n", 565 | " plt.show()\n", 566 | " \n", 567 | " # load unet to evaluate the test data\n", 568 | " unet_original = Unet_Original(filtersFirstLayer= fiilter, lr = learning_rate,input_size=(1024,1024,5))\n", 569 | " # load the last saved weight from the training\n", 570 | " unet_original.load_weights(f\"/content/drive/My Drive/Mestrado/artigo/artigo_final/results/non_augmented/{size}_{size}/{sampling}/model/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}_lr_{learning_rate}.hdf5\")\n", 571 | " \n", 572 | " # Evaluate test area 1\n", 573 | " res_1 = unet_original.evaluate(X_test_area_1,Y_test_area_1)\n", 574 | " \n", 575 | " # Evaluate test area 2\n", 576 | " res_2 = unet_original.evaluate(X_test_area_2,Y_test_area_2)\n", 577 | "\n", 578 | " # Data to plot the predicted output\n", 579 | " preds_train_1 = unet_original.predict(X_test_area_1, verbose=1)\n", 580 | " preds_train_t1 = (preds_train_1 > 0.5).astype(np.uint8)\n", 581 | " preds_train_2 = unet_original.predict(X_test_area_2, verbose=1)\n", 582 | " preds_train_t2 = (preds_train_2 > 0.5).astype(np.uint8)\n", 583 | "\n", 584 | "\n", 585 | " # save results on the dictionary\n", 586 | " dic[\"model\"].append(\"Unet\")\n", 587 | " dic[\"batch_size\"].append(batch)\n", 588 | " dic[\"learning_rate\"].append(learning_rate)\n", 589 | " dic[\"filters\"].append(fiilter)\n", 590 | " dic[\"precision_area_1\"].append(res_1[1])\n", 591 | " dic[\"recall_area_1\"].append(res_1[2])\n", 592 | " dic[\"f1_score_area_1\"].append(res_1[3])\n", 593 | " dic[\"iou_score_area_1\"].append(res_1[4])\n", 594 | " \n", 595 | " dic[\"precision_area_2\"].append(res_2[1])\n", 596 | " dic[\"recall_area_2\"].append(res_2[2])\n", 597 | " dic[\"f1_score_area_2\"].append(res_2[3])\n", 598 | " dic[\"iou_score_area_2\"].append(res_2[4])\n", 599 | " \n", 600 | " \n", 601 | " # Plot the results and save the plots\n", 602 | " f, axarr = plt.subplots(2,3,figsize=(10,10))\n", 603 | " axarr[0,0].imshow(X_test_area_1[0][:,:,:3])\n", 604 | " axarr[0,1].imshow(np.squeeze(preds_train_t1[0]))\n", 605 | " axarr[0,2].imshow(np.squeeze(Y_test_area_1[0]))\n", 606 | " axarr[1,0].imshow(X_test_area_2[0][:,:,:3])\n", 607 | " axarr[1,1].imshow(np.squeeze(preds_train_t2[0]))\n", 608 | " axarr[1,2].imshow(np.squeeze(Y_test_area_2[0]))\n", 609 | " f.savefig(f\"/content/drive/My Drive/Mestrado/artigo/artigo_final/results/non_augmented/{size}_{size}/{sampling}/images/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}_lr_{learning_rate}_result.png\")\n", 610 | " \n", 611 | " # Convert results to a dataframe\n", 612 | " results = pd.DataFrame(dic)\n", 613 | " # Export as csv\n", 614 | " results.to_csv(f'/content/drive/My Drive/Mestrado/artigo/artigo_final/results/non_augmented/{size}_{size}/{sampling}/result_table/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}.csv', index = False)" 615 | ] 616 | } 617 | ], 618 | "metadata": { 619 | "kernelspec": { 620 | "display_name": "Python 3", 621 | "language": "python", 622 | "name": "python3" 623 | }, 624 | "language_info": { 625 | "codemirror_mode": { 626 | "name": "ipython", 627 | "version": 3 628 | }, 629 | "file_extension": ".py", 630 | "mimetype": "text/x-python", 631 | "name": "python", 632 | "nbconvert_exporter": "python", 633 | "pygments_lexer": "ipython3", 634 | "version": "3.7.0" 635 | } 636 | }, 637 | "nbformat": 4, 638 | "nbformat_minor": 2 639 | } 640 | -------------------------------------------------------------------------------- /notebooks/Training_regular_RapidEye+Augmentation.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Code used to train the RapidEye+Augmentation regular models \n", 8 | "\n", 9 | "The models were trained in Google Colaboratory Virtual Environment, thus, to work properly, this notebook should be loaded in google drive.\n", 10 | "\n", 11 | "* [32x32 models](#32-x-32-models) \n", 12 | "\n", 13 | "* [64x64 models](#64-x-64-models) \n", 14 | "\n", 15 | "* [128x128 models](#128-x-128-models) " 16 | ] 17 | }, 18 | { 19 | "cell_type": "code", 20 | "execution_count": null, 21 | "metadata": {}, 22 | "outputs": [], 23 | "source": [ 24 | "# Import libraries\n", 25 | "\n", 26 | "import tensorflow as tf\n", 27 | "from __future__ import absolute_import\n", 28 | "from __future__ import division\n", 29 | "from __future__ import print_function\n", 30 | "\n", 31 | "from datetime import datetime\n", 32 | "from packaging import version\n", 33 | "\n", 34 | "%tensorflow_version 2.x\n", 35 | "from tensorflow import keras\n", 36 | "from tensorflow.keras.models import *\n", 37 | "from tensorflow.keras.layers import *\n", 38 | "from tensorflow.keras.optimizers import *\n", 39 | "\n", 40 | "import numpy as np\n", 41 | "import pandas as pd\n", 42 | "import matplotlib.pyplot as plt\n", 43 | "\n", 44 | "print(\"TensorFlow version: \", tf.__version__)\n", 45 | "assert version.parse(tf.__version__).release[0] >= 2, \\\n", 46 | " \"This notebook requires TensorFlow 2.0 or above.\"" 47 | ] 48 | }, 49 | { 50 | "cell_type": "code", 51 | "execution_count": null, 52 | "metadata": {}, 53 | "outputs": [], 54 | "source": [ 55 | "# Install segmetation_models library (https://github.com/qubvel/segmentation_models)\n", 56 | "pip install segmentation_models" 57 | ] 58 | }, 59 | { 60 | "cell_type": "code", 61 | "execution_count": null, 62 | "metadata": {}, 63 | "outputs": [], 64 | "source": [ 65 | "# Load segmentation)models library \n", 66 | "import segmentation_models as sm" 67 | ] 68 | }, 69 | { 70 | "cell_type": "markdown", 71 | "metadata": {}, 72 | "source": [ 73 | "#### 32 x 32 models" 74 | ] 75 | }, 76 | { 77 | "cell_type": "code", 78 | "execution_count": null, 79 | "metadata": {}, 80 | "outputs": [], 81 | "source": [ 82 | "# Load training data 32x32 - regular - the Strings are the directions to the .npy files in google drive\n", 83 | "X_train = np.load(\"/content/drive/My Drive/Mestrado/artigo/artigo_final/data/augmented/32_32/regular/arrays/X_train_32_regular.npy\")\n", 84 | "Y_train = np.load(\"/content/drive/My Drive/Mestrado/artigo/artigo_final/data/augmented/32_32/regular/arrays/Y_train_32_regular.npy\")\n", 85 | "\n", 86 | "# Load test data - Area 1\n", 87 | "X_test_area_1 = np.load(\"/content/drive/My Drive/Mestrado/artigo/artigo_final/data/test/test_without_terrain/area_1/arrays/X_test_test_area_1.npy\")\n", 88 | "Y_test_area_1 = np.load(\"/content/drive/My Drive/Mestrado/artigo/artigo_final/data/test/test_without_terrain/area_1/arrays/Y_test_test_area_1.npy\")\n", 89 | "\n", 90 | "# Load test data - Area 2\n", 91 | "X_test_area_2 = np.load(\"/content/drive/My Drive/Mestrado/artigo/artigo_final/data/test/test_without_terrain/area_2/arrays/X_test_test_area_2.npy\")\n", 92 | "Y_test_area_2 = np.load(\"/content/drive/My Drive/Mestrado/artigo/artigo_final/data/test/test_without_terrain/area_2/arrays/Y_test_test_area_2.npy\")" 93 | ] 94 | }, 95 | { 96 | "cell_type": "code", 97 | "execution_count": null, 98 | "metadata": {}, 99 | "outputs": [], 100 | "source": [ 101 | "# Evaluate data dimensions\n", 102 | "print(f\"X_train shape: {X_train.shape}, Y_train shape: {Y_train.shape}\\nX_test_area_1 shape: {X_test_area_1.shape}, Y_test_area_1 shape: {Y_test_area_1.shape},\\nX_test_area_2 shape: {X_test_area_2.shape}, Y_test_area_2 shape: {Y_test_area_2.shape}\")" 103 | ] 104 | }, 105 | { 106 | "cell_type": "code", 107 | "execution_count": null, 108 | "metadata": {}, 109 | "outputs": [], 110 | "source": [ 111 | "# Evaluation Metrics - Precision, Recall, FScore, IoU\n", 112 | "metrics = [sm.metrics.Precision(threshold=0.5),sm.metrics.Recall(threshold=0.5),sm.metrics.FScore(threshold=0.5,beta=1),sm.metrics.IOUScore(threshold=0.5)]" 113 | ] 114 | }, 115 | { 116 | "cell_type": "code", 117 | "execution_count": null, 118 | "metadata": {}, 119 | "outputs": [], 120 | "source": [ 121 | "# Unet Architecture\n", 122 | "def Unet_Original(lr,filtersFirstLayer, pretrained_weights = None,input_size = (32,32,5)):\n", 123 | " inputs = Input(input_size)\n", 124 | " conv1 = Conv2D(filtersFirstLayer, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(inputs)\n", 125 | " conv1 = Conv2D(filtersFirstLayer, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(conv1)\n", 126 | " pool1 = MaxPooling2D(pool_size=(2, 2))(conv1)\n", 127 | " conv2 = Conv2D(filtersFirstLayer*2, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(pool1)\n", 128 | " conv2 = Conv2D(filtersFirstLayer*2, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(conv2)\n", 129 | " pool2 = MaxPooling2D(pool_size=(2, 2))(conv2)\n", 130 | " conv3 = Conv2D(filtersFirstLayer*4, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(pool2)\n", 131 | " conv3 = Conv2D(filtersFirstLayer*4, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(conv3)\n", 132 | " pool3 = MaxPooling2D(pool_size=(2, 2))(conv3)\n", 133 | " conv4 = Conv2D(filtersFirstLayer*8, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(pool3)\n", 134 | " conv4 = Conv2D(filtersFirstLayer*8, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(conv4)\n", 135 | " pool4 = MaxPooling2D(pool_size=(2, 2))(conv4)\n", 136 | "\n", 137 | " conv5 = Conv2D(filtersFirstLayer*16, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(pool4)\n", 138 | " conv5 = Conv2D(filtersFirstLayer*16, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(conv5)\n", 139 | "\n", 140 | " up6 = Conv2D(filtersFirstLayer*8, 2, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(UpSampling2D(size = (2,2))(conv5))\n", 141 | " merge6 = concatenate([conv4,up6], axis = 3)\n", 142 | " conv6 = Conv2D(filtersFirstLayer*8, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(merge6)\n", 143 | " conv6 = Conv2D(filtersFirstLayer*8, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(conv6)\n", 144 | "\n", 145 | " up7 = Conv2D(filtersFirstLayer*4, 2, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(UpSampling2D(size = (2,2))(conv6))\n", 146 | " merge7 = concatenate([conv3,up7], axis = 3)\n", 147 | " conv7 = Conv2D(filtersFirstLayer*4, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(merge7)\n", 148 | " conv7 = Conv2D(filtersFirstLayer*4, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(conv7)\n", 149 | "\n", 150 | " up8 = Conv2D(filtersFirstLayer*2, 2, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(UpSampling2D(size = (2,2))(conv7))\n", 151 | " merge8 = concatenate([conv2,up8], axis = 3)\n", 152 | " conv8 = Conv2D(filtersFirstLayer*2, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(merge8)\n", 153 | " conv8 = Conv2D(filtersFirstLayer*2, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(conv8)\n", 154 | "\n", 155 | " up9 = Conv2D(filtersFirstLayer, 2, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(UpSampling2D(size = (2,2))(conv8))\n", 156 | " merge9 = concatenate([conv1,up9], axis = 3)\n", 157 | " conv9 = Conv2D(filtersFirstLayer, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(merge9)\n", 158 | " conv9 = Conv2D(filtersFirstLayer, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(conv9)\n", 159 | " conv9 = Conv2D(2, 3, activation = 'relu', padding = 'same', kernel_initializer = 'glorot_normal')(conv9)\n", 160 | " conv10 = Conv2D(1, 1, activation = 'sigmoid')(conv9)\n", 161 | "\n", 162 | " model = Model(inputs, conv10)\n", 163 | "\n", 164 | " model.compile(optimizer = Adam(lr = lr), loss = 'binary_crossentropy', metrics = metrics)\n", 165 | " \n", 166 | " model.summary()\n", 167 | "\n", 168 | " if(pretrained_weights):\n", 169 | " \tmodel.load_weights(pretrained_weights)\n", 170 | "\n", 171 | " return model" 172 | ] 173 | }, 174 | { 175 | "cell_type": "code", 176 | "execution_count": null, 177 | "metadata": {}, 178 | "outputs": [], 179 | "source": [ 180 | "# Model training - Results are saved in a .csv file\n", 181 | "\n", 182 | "# size of the tiles\n", 183 | "size = 32\n", 184 | "# Sampling method\n", 185 | "sampling = \"regular\"\n", 186 | "# number of filters \n", 187 | "filters = [16,32,64]\n", 188 | "# lr = 0.001\n", 189 | "lr = [10e-4]\n", 190 | "# batch sizes \n", 191 | "batch_size = [16,32,64,128]\n", 192 | "\n", 193 | "# dictionary that will save the results\n", 194 | "dic = {}\n", 195 | "\n", 196 | "# Hyperparameters\n", 197 | "dic[\"model\"] = []\n", 198 | "dic[\"batch_size\"] = []\n", 199 | "dic[\"learning_rate\"] = []\n", 200 | "dic[\"filters\"] = []\n", 201 | "\n", 202 | "# test area 1\n", 203 | "dic[\"precision_area_1\"] = []\n", 204 | "dic[\"recall_area_1\"] = []\n", 205 | "dic[\"f1_score_area_1\"] = []\n", 206 | "dic[\"iou_score_area_1\"] = []\n", 207 | "\n", 208 | "# test area 2\n", 209 | "dic[\"precision_area_2\"] = []\n", 210 | "dic[\"recall_area_2\"] = []\n", 211 | "dic[\"f1_score_area_2\"] = []\n", 212 | "dic[\"iou_score_area_2\"] = []\n", 213 | "\n", 214 | "\n", 215 | "\n", 216 | "\n", 217 | "# loop over all the filters in the filter list\n", 218 | "for fiilter in filters:\n", 219 | " # loop over the learning rates (used to evalute 0.01 and 0.0001 without good results)\n", 220 | " for learning_rate in lr:\n", 221 | " # loop over all batch sizes in batch_size list\n", 222 | " for batch in batch_size:\n", 223 | " # load the model\n", 224 | " model = Unet_Original(filtersFirstLayer= fiilter, lr = learning_rate)\n", 225 | " # Save the models only when validation loss decrease\n", 226 | " model_checkpoint = tf.keras.callbacks.ModelCheckpoint(f'/content/drive/My Drive/Mestrado/artigo/artigo_final/results/augmented/{size}_{size}/{sampling}/model/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}_lr_{learning_rate}.hdf5', monitor='val_loss', mode='min',verbose=1, save_best_only=True,save_weights_only = True)\n", 227 | " # Stop after 20 epochs without decreasing the validation loss\n", 228 | " early_stopping = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=20)\n", 229 | " print(fiilter, learning_rate,batch)\n", 230 | " # fit the model 30% of the dataset was used as validation\n", 231 | " history = model.fit(X_train,Y_train,batch_size = batch,epochs=200,validation_split=0.3,callbacks=[model_checkpoint, early_stopping])\n", 232 | "\n", 233 | " # summarize history for iou score\n", 234 | " plt.plot(history.history['iou_score'])\n", 235 | " plt.plot(history.history['val_iou_score'])\n", 236 | " plt.title('model accuracy')\n", 237 | " plt.ylabel('accuracy')\n", 238 | " plt.xlabel('epoch')\n", 239 | " plt.legend(['train', 'validation'], loc='upper left')\n", 240 | " # save plots \n", 241 | " plt.savefig(f\"/content/drive/My Drive/Mestrado/artigo/artigo_final/results/augmented/{size}_{size}/{sampling}/plots/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}_lr_{learning_rate}_iou_score.png\")\n", 242 | " plt.show()\n", 243 | " # summarize history for loss\n", 244 | " plt.plot(history.history['loss'])\n", 245 | " plt.plot(history.history['val_loss'])\n", 246 | " plt.title('model loss')\n", 247 | " plt.ylabel('loss')\n", 248 | " plt.xlabel('epoch')\n", 249 | " plt.legend(['train', 'validation'], loc='upper left')\n", 250 | " plt.savefig(f\"/content/drive/My Drive/Mestrado/artigo/artigo_final/results/augmented/{size}_{size}/{sampling}/plots/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}_lr_{learning_rate}_val_loss.png\")\n", 251 | " plt.show()\n", 252 | " \n", 253 | " # load unet to evaluate the test data\n", 254 | " unet_original = Unet_Original(filtersFirstLayer= fiilter, lr = learning_rate,input_size=(1024,1024,5))\n", 255 | " # load the last saved weight from the training\n", 256 | " unet_original.load_weights(f\"/content/drive/My Drive/Mestrado/artigo/artigo_final/results/augmented/{size}_{size}/{sampling}/model/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}_lr_{learning_rate}.hdf5\")\n", 257 | " \n", 258 | " # Evaluate test area 1\n", 259 | " res_1 = unet_original.evaluate(X_test_area_1,Y_test_area_1)\n", 260 | " \n", 261 | " # Evaluate test area 2\n", 262 | " res_2 = unet_original.evaluate(X_test_area_2,Y_test_area_2)\n", 263 | "\n", 264 | " # Data to plot the predicted output\n", 265 | " preds_train_1 = unet_original.predict(X_test_area_1, verbose=1)\n", 266 | " preds_train_t1 = (preds_train_1 > 0.5).astype(np.uint8)\n", 267 | " preds_train_2 = unet_original.predict(X_test_area_2, verbose=1)\n", 268 | " preds_train_t2 = (preds_train_2 > 0.5).astype(np.uint8)\n", 269 | "\n", 270 | "\n", 271 | " # save results on the dictionary\n", 272 | " dic[\"model\"].append(\"Unet\")\n", 273 | " dic[\"batch_size\"].append(batch)\n", 274 | " dic[\"learning_rate\"].append(learning_rate)\n", 275 | " dic[\"filters\"].append(fiilter)\n", 276 | " dic[\"precision_area_1\"].append(res_1[1])\n", 277 | " dic[\"recall_area_1\"].append(res_1[2])\n", 278 | " dic[\"f1_score_area_1\"].append(res_1[3])\n", 279 | " dic[\"iou_score_area_1\"].append(res_1[4])\n", 280 | " \n", 281 | " dic[\"precision_area_2\"].append(res_2[1])\n", 282 | " dic[\"recall_area_2\"].append(res_2[2])\n", 283 | " dic[\"f1_score_area_2\"].append(res_2[3])\n", 284 | " dic[\"iou_score_area_2\"].append(res_2[4])\n", 285 | " \n", 286 | " \n", 287 | " # Plot the results and save the plots\n", 288 | " f, axarr = plt.subplots(2,3,figsize=(10,10))\n", 289 | " axarr[0,0].imshow(X_test_area_1[0][:,:,:3])\n", 290 | " axarr[0,1].imshow(np.squeeze(preds_train_t1[0]))\n", 291 | " axarr[0,2].imshow(np.squeeze(Y_test_area_1[0]))\n", 292 | " axarr[1,0].imshow(X_test_area_2[0][:,:,:3])\n", 293 | " axarr[1,1].imshow(np.squeeze(preds_train_t2[0]))\n", 294 | " axarr[1,2].imshow(np.squeeze(Y_test_area_2[0]))\n", 295 | " f.savefig(f\"/content/drive/My Drive/Mestrado/artigo/artigo_final/results/augmented/{size}_{size}/{sampling}/images/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}_lr_{learning_rate}_result.png\")\n", 296 | " \n", 297 | " # Convert results to a dataframe\n", 298 | " results = pd.DataFrame(dic)\n", 299 | " # Export as csv\n", 300 | " results.to_csv(f'/content/drive/My Drive/Mestrado/artigo/artigo_final/results/augmented/{size}_{size}/{sampling}/result_table/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}.csv', index = False)" 301 | ] 302 | }, 303 | { 304 | "cell_type": "markdown", 305 | "metadata": {}, 306 | "source": [ 307 | "#### 64 x 64 models" 308 | ] 309 | }, 310 | { 311 | "cell_type": "code", 312 | "execution_count": null, 313 | "metadata": {}, 314 | "outputs": [], 315 | "source": [ 316 | "# Load training data 64x64 - regular \n", 317 | "X_train = np.load(\"/content/drive/My Drive/Mestrado/artigo/artigo_final/data/augmented/64_64/regular/arrays/X_train_64_regular.npy\")\n", 318 | "Y_train = np.load(\"/content/drive/My Drive/Mestrado/artigo/artigo_final/data/augmented/64_64/regular/arrays/Y_train_64_regular.npy\")" 319 | ] 320 | }, 321 | { 322 | "cell_type": "code", 323 | "execution_count": null, 324 | "metadata": {}, 325 | "outputs": [], 326 | "source": [ 327 | "# Evaluate data dimensions\n", 328 | "print(f\"X_train shape: {X_train.shape}, Y_train shape: {Y_train.shape}\\nX_test_area_1 shape: {X_test_area_1.shape}, Y_test_area_1 shape: {Y_test_area_1.shape},\\nX_test_area_2 shape: {X_test_area_2.shape}, Y_test_area_2 shape: {Y_test_area_2.shape}\")" 329 | ] 330 | }, 331 | { 332 | "cell_type": "code", 333 | "execution_count": null, 334 | "metadata": {}, 335 | "outputs": [], 336 | "source": [ 337 | "# Model training - Results are saved in a .csv file\n", 338 | "\n", 339 | "# size of the tiles\n", 340 | "size = 64\n", 341 | "# Sampling method\n", 342 | "sampling = \"regular\"\n", 343 | "# number of filters \n", 344 | "filters = [16,32,64]\n", 345 | "# lr = 0.001\n", 346 | "lr = [10e-4]\n", 347 | "# batch sizes \n", 348 | "batch_size = [16,32,64,128]\n", 349 | "\n", 350 | "# dictionary that will save the results\n", 351 | "dic = {}\n", 352 | "\n", 353 | "# Hyperparameters\n", 354 | "dic[\"model\"] = []\n", 355 | "dic[\"batch_size\"] = []\n", 356 | "dic[\"learning_rate\"] = []\n", 357 | "dic[\"filters\"] = []\n", 358 | "\n", 359 | "# test area 1\n", 360 | "dic[\"precision_area_1\"] = []\n", 361 | "dic[\"recall_area_1\"] = []\n", 362 | "dic[\"f1_score_area_1\"] = []\n", 363 | "dic[\"iou_score_area_1\"] = []\n", 364 | "\n", 365 | "# test area 2\n", 366 | "dic[\"precision_area_2\"] = []\n", 367 | "dic[\"recall_area_2\"] = []\n", 368 | "dic[\"f1_score_area_2\"] = []\n", 369 | "dic[\"iou_score_area_2\"] = []\n", 370 | "\n", 371 | "\n", 372 | "\n", 373 | "\n", 374 | "# loop over all the filters in the filter list\n", 375 | "for fiilter in filters:\n", 376 | " # loop over the learning rates (used to evalute 0.01 and 0.0001 without good results)\n", 377 | " for learning_rate in lr:\n", 378 | " # loop over all batch sizes in batch_size list\n", 379 | " for batch in batch_size:\n", 380 | " # load the model\n", 381 | " model = Unet_Original(filtersFirstLayer= fiilter, lr = learning_rate, input_size = (64,64,5))\n", 382 | " # Save the models only when validation loss decrease\n", 383 | " model_checkpoint = tf.keras.callbacks.ModelCheckpoint(f'/content/drive/My Drive/Mestrado/artigo/artigo_final/results/augmented/{size}_{size}/{sampling}/model/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}_lr_{learning_rate}.hdf5', monitor='val_loss', mode='min',verbose=1, save_best_only=True,save_weights_only = True)\n", 384 | " # Stop after 20 epochs without decreasing the validation loss\n", 385 | " early_stopping = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=20)\n", 386 | " print(fiilter, learning_rate,batch)\n", 387 | " # fit the model 30% of the dataset was used as validation\n", 388 | " history = model.fit(X_train,Y_train,batch_size = batch,epochs=200,validation_split=0.3,callbacks=[model_checkpoint, early_stopping])\n", 389 | "\n", 390 | " # summarize history for iou score\n", 391 | " plt.plot(history.history['iou_score'])\n", 392 | " plt.plot(history.history['val_iou_score'])\n", 393 | " plt.title('model accuracy')\n", 394 | " plt.ylabel('accuracy')\n", 395 | " plt.xlabel('epoch')\n", 396 | " plt.legend(['train', 'validation'], loc='upper left')\n", 397 | " # save plots \n", 398 | " plt.savefig(f\"/content/drive/My Drive/Mestrado/artigo/artigo_final/results/augmented/{size}_{size}/{sampling}/plots/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}_lr_{learning_rate}_iou_score.png\")\n", 399 | " plt.show()\n", 400 | " # summarize history for loss\n", 401 | " plt.plot(history.history['loss'])\n", 402 | " plt.plot(history.history['val_loss'])\n", 403 | " plt.title('model loss')\n", 404 | " plt.ylabel('loss')\n", 405 | " plt.xlabel('epoch')\n", 406 | " plt.legend(['train', 'validation'], loc='upper left')\n", 407 | " plt.savefig(f\"/content/drive/My Drive/Mestrado/artigo/artigo_final/results/augmented/{size}_{size}/{sampling}/plots/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}_lr_{learning_rate}_val_loss.png\")\n", 408 | " plt.show()\n", 409 | " \n", 410 | " # load unet to evaluate the test data\n", 411 | " unet_original = Unet_Original(filtersFirstLayer= fiilter, lr = learning_rate,input_size=(1024,1024,5))\n", 412 | " # load the last saved weight from the training\n", 413 | " unet_original.load_weights(f\"/content/drive/My Drive/Mestrado/artigo/artigo_final/results/augmented/{size}_{size}/{sampling}/model/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}_lr_{learning_rate}.hdf5\")\n", 414 | " \n", 415 | " # Evaluate test area 1\n", 416 | " res_1 = unet_original.evaluate(X_test_area_1,Y_test_area_1)\n", 417 | " \n", 418 | " # Evaluate test area 2\n", 419 | " res_2 = unet_original.evaluate(X_test_area_2,Y_test_area_2)\n", 420 | "\n", 421 | " # Data to plot the predicted output\n", 422 | " preds_train_1 = unet_original.predict(X_test_area_1, verbose=1)\n", 423 | " preds_train_t1 = (preds_train_1 > 0.5).astype(np.uint8)\n", 424 | " preds_train_2 = unet_original.predict(X_test_area_2, verbose=1)\n", 425 | " preds_train_t2 = (preds_train_2 > 0.5).astype(np.uint8)\n", 426 | "\n", 427 | "\n", 428 | " # save results on the dictionary\n", 429 | " dic[\"model\"].append(\"Unet\")\n", 430 | " dic[\"batch_size\"].append(batch)\n", 431 | " dic[\"learning_rate\"].append(learning_rate)\n", 432 | " dic[\"filters\"].append(fiilter)\n", 433 | " dic[\"precision_area_1\"].append(res_1[1])\n", 434 | " dic[\"recall_area_1\"].append(res_1[2])\n", 435 | " dic[\"f1_score_area_1\"].append(res_1[3])\n", 436 | " dic[\"iou_score_area_1\"].append(res_1[4])\n", 437 | " \n", 438 | " dic[\"precision_area_2\"].append(res_2[1])\n", 439 | " dic[\"recall_area_2\"].append(res_2[2])\n", 440 | " dic[\"f1_score_area_2\"].append(res_2[3])\n", 441 | " dic[\"iou_score_area_2\"].append(res_2[4])\n", 442 | " \n", 443 | " \n", 444 | " # Plot the results and save the plots\n", 445 | " f, axarr = plt.subplots(2,3,figsize=(10,10))\n", 446 | " axarr[0,0].imshow(X_test_area_1[0][:,:,:3])\n", 447 | " axarr[0,1].imshow(np.squeeze(preds_train_t1[0]))\n", 448 | " axarr[0,2].imshow(np.squeeze(Y_test_area_1[0]))\n", 449 | " axarr[1,0].imshow(X_test_area_2[0][:,:,:3])\n", 450 | " axarr[1,1].imshow(np.squeeze(preds_train_t2[0]))\n", 451 | " axarr[1,2].imshow(np.squeeze(Y_test_area_2[0]))\n", 452 | " f.savefig(f\"/content/drive/My Drive/Mestrado/artigo/artigo_final/results/augmented/{size}_{size}/{sampling}/images/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}_lr_{learning_rate}_result.png\")\n", 453 | " \n", 454 | " # Convert results to a dataframe\n", 455 | " results = pd.DataFrame(dic)\n", 456 | " # Export as csv\n", 457 | " results.to_csv(f'/content/drive/My Drive/Mestrado/artigo/artigo_final/results/augmented/{size}_{size}/{sampling}/result_table/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}.csv', index = False)" 458 | ] 459 | }, 460 | { 461 | "cell_type": "markdown", 462 | "metadata": {}, 463 | "source": [ 464 | "#### 128 x 128 models" 465 | ] 466 | }, 467 | { 468 | "cell_type": "code", 469 | "execution_count": null, 470 | "metadata": {}, 471 | "outputs": [], 472 | "source": [ 473 | "# Load training data 128x128 - regular \n", 474 | "X_train = np.load(\"/content/drive/My Drive/Mestrado/artigo/artigo_final/data/augmented/128_128/regular/arrays/X_train_128_regular.npy\")\n", 475 | "Y_train = np.load(\"/content/drive/My Drive/Mestrado/artigo/artigo_final/data/augmented/128_128/regular/arrays/Y_train_128_regular.npy\")" 476 | ] 477 | }, 478 | { 479 | "cell_type": "code", 480 | "execution_count": null, 481 | "metadata": {}, 482 | "outputs": [], 483 | "source": [ 484 | "# Evaluate data dimensions\n", 485 | "print(f\"X_train shape: {X_train.shape}, Y_train shape: {Y_train.shape}\\nX_test_area_1 shape: {X_test_area_1.shape}, Y_test_area_1 shape: {Y_test_area_1.shape},\\nX_test_area_2 shape: {X_test_area_2.shape}, Y_test_area_2 shape: {Y_test_area_2.shape}\")" 486 | ] 487 | }, 488 | { 489 | "cell_type": "code", 490 | "execution_count": null, 491 | "metadata": {}, 492 | "outputs": [], 493 | "source": [ 494 | "# Model training - Results are saved in a .csv file\n", 495 | "\n", 496 | "# size of the tiles\n", 497 | "size = 128\n", 498 | "# Sampling method\n", 499 | "sampling = \"regular\"\n", 500 | "# number of filters \n", 501 | "filters = [16,32,64]\n", 502 | "# lr = 0.001\n", 503 | "lr = [10e-4]\n", 504 | "# batch sizes \n", 505 | "batch_size = [16,32,64,128]\n", 506 | "\n", 507 | "# dictionary that will save the results\n", 508 | "dic = {}\n", 509 | "\n", 510 | "# Hyperparameters\n", 511 | "dic[\"model\"] = []\n", 512 | "dic[\"batch_size\"] = []\n", 513 | "dic[\"learning_rate\"] = []\n", 514 | "dic[\"filters\"] = []\n", 515 | "\n", 516 | "# test area 1\n", 517 | "dic[\"precision_area_1\"] = []\n", 518 | "dic[\"recall_area_1\"] = []\n", 519 | "dic[\"f1_score_area_1\"] = []\n", 520 | "dic[\"iou_score_area_1\"] = []\n", 521 | "\n", 522 | "# test area 2\n", 523 | "dic[\"precision_area_2\"] = []\n", 524 | "dic[\"recall_area_2\"] = []\n", 525 | "dic[\"f1_score_area_2\"] = []\n", 526 | "dic[\"iou_score_area_2\"] = []\n", 527 | "\n", 528 | "\n", 529 | "\n", 530 | "\n", 531 | "# loop over all the filters in the filter list\n", 532 | "for fiilter in filters:\n", 533 | " # loop over the learning rates (used to evalute 0.01 and 0.0001 without good results)\n", 534 | " for learning_rate in lr:\n", 535 | " # loop over all batch sizes in batch_size list\n", 536 | " for batch in batch_size:\n", 537 | " # load the model\n", 538 | " model = Unet_Original(filtersFirstLayer= fiilter, lr = learning_rate, input_size = (128,128,5))\n", 539 | " # Save the models only when validation loss decrease\n", 540 | " model_checkpoint = tf.keras.callbacks.ModelCheckpoint(f'/content/drive/My Drive/Mestrado/artigo/artigo_final/results/augmented/{size}_{size}/{sampling}/model/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}_lr_{learning_rate}.hdf5', monitor='val_loss', mode='min',verbose=1, save_best_only=True,save_weights_only = True)\n", 541 | " # Stop after 20 epochs without decreasing the validation loss\n", 542 | " early_stopping = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=20)\n", 543 | " print(fiilter, learning_rate,batch)\n", 544 | " # fit the model 30% of the dataset was used as validation\n", 545 | " history = model.fit(X_train,Y_train,batch_size = batch,epochs=200,validation_split=0.3,callbacks=[model_checkpoint, early_stopping])\n", 546 | "\n", 547 | " # summarize history for iou score\n", 548 | " plt.plot(history.history['iou_score'])\n", 549 | " plt.plot(history.history['val_iou_score'])\n", 550 | " plt.title('model accuracy')\n", 551 | " plt.ylabel('accuracy')\n", 552 | " plt.xlabel('epoch')\n", 553 | " plt.legend(['train', 'validation'], loc='upper left')\n", 554 | " # save plots \n", 555 | " plt.savefig(f\"/content/drive/My Drive/Mestrado/artigo/artigo_final/results/augmented/{size}_{size}/{sampling}/plots/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}_lr_{learning_rate}_iou_score.png\")\n", 556 | " plt.show()\n", 557 | " # summarize history for loss\n", 558 | " plt.plot(history.history['loss'])\n", 559 | " plt.plot(history.history['val_loss'])\n", 560 | " plt.title('model loss')\n", 561 | " plt.ylabel('loss')\n", 562 | " plt.xlabel('epoch')\n", 563 | " plt.legend(['train', 'validation'], loc='upper left')\n", 564 | " plt.savefig(f\"/content/drive/My Drive/Mestrado/artigo/artigo_final/results/augmented/{size}_{size}/{sampling}/plots/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}_lr_{learning_rate}_val_loss.png\")\n", 565 | " plt.show()\n", 566 | " \n", 567 | " # load unet to evaluate the test data\n", 568 | " unet_original = Unet_Original(filtersFirstLayer= fiilter, lr = learning_rate,input_size=(1024,1024,5))\n", 569 | " # load the last saved weight from the training\n", 570 | " unet_original.load_weights(f\"/content/drive/My Drive/Mestrado/artigo/artigo_final/results/augmented/{size}_{size}/{sampling}/model/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}_lr_{learning_rate}.hdf5\")\n", 571 | " \n", 572 | " # Evaluate test area 1\n", 573 | " res_1 = unet_original.evaluate(X_test_area_1,Y_test_area_1)\n", 574 | " \n", 575 | " # Evaluate test area 2\n", 576 | " res_2 = unet_original.evaluate(X_test_area_2,Y_test_area_2)\n", 577 | "\n", 578 | " # Data to plot the predicted output\n", 579 | " preds_train_1 = unet_original.predict(X_test_area_1, verbose=1)\n", 580 | " preds_train_t1 = (preds_train_1 > 0.5).astype(np.uint8)\n", 581 | " preds_train_2 = unet_original.predict(X_test_area_2, verbose=1)\n", 582 | " preds_train_t2 = (preds_train_2 > 0.5).astype(np.uint8)\n", 583 | "\n", 584 | "\n", 585 | " # save results on the dictionary\n", 586 | " dic[\"model\"].append(\"Unet\")\n", 587 | " dic[\"batch_size\"].append(batch)\n", 588 | " dic[\"learning_rate\"].append(learning_rate)\n", 589 | " dic[\"filters\"].append(fiilter)\n", 590 | " dic[\"precision_area_1\"].append(res_1[1])\n", 591 | " dic[\"recall_area_1\"].append(res_1[2])\n", 592 | " dic[\"f1_score_area_1\"].append(res_1[3])\n", 593 | " dic[\"iou_score_area_1\"].append(res_1[4])\n", 594 | " \n", 595 | " dic[\"precision_area_2\"].append(res_2[1])\n", 596 | " dic[\"recall_area_2\"].append(res_2[2])\n", 597 | " dic[\"f1_score_area_2\"].append(res_2[3])\n", 598 | " dic[\"iou_score_area_2\"].append(res_2[4])\n", 599 | " \n", 600 | " \n", 601 | " # Plot the results and save the plots\n", 602 | " f, axarr = plt.subplots(2,3,figsize=(10,10))\n", 603 | " axarr[0,0].imshow(X_test_area_1[0][:,:,:3])\n", 604 | " axarr[0,1].imshow(np.squeeze(preds_train_t1[0]))\n", 605 | " axarr[0,2].imshow(np.squeeze(Y_test_area_1[0]))\n", 606 | " axarr[1,0].imshow(X_test_area_2[0][:,:,:3])\n", 607 | " axarr[1,1].imshow(np.squeeze(preds_train_t2[0]))\n", 608 | " axarr[1,2].imshow(np.squeeze(Y_test_area_2[0]))\n", 609 | " f.savefig(f\"/content/drive/My Drive/Mestrado/artigo/artigo_final/results/augmented/{size}_{size}/{sampling}/images/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}_lr_{learning_rate}_result.png\")\n", 610 | " \n", 611 | " # Convert results to a dataframe\n", 612 | " results = pd.DataFrame(dic)\n", 613 | " # Export as csv\n", 614 | " results.to_csv(f'/content/drive/My Drive/Mestrado/artigo/artigo_final/results/augmented/{size}_{size}/{sampling}/result_table/unet/unet_{sampling}_size_{size}_filters_{fiilter}_batch_size_{batch}.csv', index = False)" 615 | ] 616 | } 617 | ], 618 | "metadata": { 619 | "kernelspec": { 620 | "display_name": "Python 3", 621 | "language": "python", 622 | "name": "python3" 623 | }, 624 | "language_info": { 625 | "codemirror_mode": { 626 | "name": "ipython", 627 | "version": 3 628 | }, 629 | "file_extension": ".py", 630 | "mimetype": "text/x-python", 631 | "name": "python", 632 | "nbconvert_exporter": "python", 633 | "pygments_lexer": "ipython3", 634 | "version": "3.7.0" 635 | } 636 | }, 637 | "nbformat": 4, 638 | "nbformat_minor": 2 639 | } 640 | -------------------------------------------------------------------------------- /notebooks/utils.py: -------------------------------------------------------------------------------- 1 | 2 | import os 3 | from itertools import product 4 | import rasterio as rio 5 | from rasterio import windows 6 | import skimage 7 | import skimage.io 8 | import numpy as np 9 | 10 | from rasterio.plot import reshape_as_image 11 | import rasterio.mask 12 | from rasterio.features import rasterize 13 | 14 | import pandas as pd 15 | import geopandas as gpd 16 | from shapely.geometry import mapping, Point, Polygon 17 | from shapely.ops import cascaded_union 18 | 19 | ######################## load image tif ############################### 20 | from typing import Any 21 | 22 | 23 | def open_tif_image(input_path): 24 | # type: (function) -> np.array 25 | """Function to open tif images. 26 | 27 | Parameters: 28 | 29 | input_path (string) = path where the image file is located; 30 | 31 | return 32 | 33 | np.array of the tif image""" 34 | 35 | # get the image_path. 36 | image_path = input_path 37 | # read image 38 | im = skimage.io.imread(image_path, plugin="tifffile") 39 | return im 40 | 41 | 42 | def get_list_file_names(folder_path): 43 | 44 | """ Function to get the name of all files in folder. 45 | 46 | Parameters: 47 | 48 | folder_path (string) = path to the folder where all the .tif image files are located 49 | 50 | return 51 | 52 | (list) with all the files within the folder_path """ 53 | 54 | image_names = next(os.walk(folder_path))[2] 55 | if ".DS_Store" in image_names: 56 | image_names.remove(".DS_Store") 57 | print("Number of images: {}".format(len(image_names))) 58 | return image_names 59 | 60 | 61 | def get_list_of_images_and_masks_with_same_dimension(image_names, images_path, masks_path, size): 62 | 63 | """Function to get the arrays of the .tif images and masks from a folder 64 | 65 | Parameters: 66 | 67 | image_names(list) = list of file names. 68 | 69 | images_path(string) = path to the folder where .tif image files are located. 70 | 71 | masks_path(string) = path to the folder where all the .tif mask files are located. 72 | 73 | size (int) = size of the height and width of the dimensions of the image. 74 | 75 | return 76 | (array) of images, masks 77 | 78 | """ 79 | images = [] 80 | masks = [] 81 | i = 0 82 | for image in sorted(image_names): 83 | current_image = open_tif_image(images_path + image) # type: np.array 84 | current_mask = open_tif_image(masks_path + image) # type: np.array 85 | i+= 1 86 | if current_image.shape[0] == size and current_image.shape[1] == size and current_mask.shape[0] == size and current_mask.shape[1] == size: 87 | images.append(current_image) 88 | masks.append(current_mask) 89 | print("Images shape: {}, Mask shape: {}".format(len(images), len(masks))) 90 | image = np.array(images, dtype="uint32") 91 | mask = np.expand_dims(np.array(masks, dtype="uint32"), axis=3) 92 | print("Images shape: {}, Mask shape: {}".format(image.shape, mask.shape)) 93 | return image, mask 94 | 95 | 96 | def save_array(image_array, output_file_name, outputfolder): 97 | """Function to save a numpy array to a specific folder and name. 98 | 99 | Parameters: 100 | 101 | image_array = np.array file. 102 | 103 | output_file_name = Name of the file that will be saved. 104 | 105 | outputfolder - path to the folder where the data will be saved. 106 | 107 | 108 | """ 109 | 110 | np.save(outputfolder + output_file_name , image_array) 111 | print("Image saved on {}".format(outputfolder)) 112 | 113 | 114 | 115 | ######################## Pre Processing ############################### 116 | def patch_images(input_path, output_path, size): 117 | 118 | """Function to patch the images in an specific size to a folder. 119 | 120 | Parameters: 121 | 122 | input_path(string) = path where the image file is located 123 | 124 | output_path(string) = path where the image tiles is located 125 | 126 | size (int) = crop size(width and height size will be the same during the crop) 127 | 128 | 129 | """ 130 | 131 | size = size 132 | i = 0 133 | in_path = input_path 134 | 135 | 136 | out_path = output_path 137 | output_filename = 'tile_{}.tif' 138 | 139 | def get_tiles(ds, width=size, height=size): 140 | nols, nrows = ds.meta['width'], ds.meta['height'] 141 | offsets = product(range(0, nols, width), range(0, nrows, height)) 142 | big_window = windows.Window(col_off=0, row_off=0, width=nols, height=nrows) 143 | for col_off, row_off in offsets: 144 | window =windows.Window(col_off=col_off, row_off=row_off, width=width, height=height).intersection(big_window) 145 | transform = windows.transform(window, ds.transform) 146 | yield window, transform 147 | 148 | 149 | with rio.open(input_path) as inds: 150 | tile_width, tile_height = size, size 151 | 152 | meta = inds.meta.copy() 153 | 154 | for window, transform in get_tiles(inds): 155 | print(window) 156 | meta['transform'] = transform 157 | meta['width'], meta['height'] = window.width, window.height 158 | i += 1 159 | outpath = os.path.join(out_path,output_filename.format(i)) 160 | with rio.open(outpath, 'w', **meta) as outds: 161 | outds.write(inds.read(window=window)) 162 | 163 | 164 | 165 | 166 | 167 | def get_nonzero_files(images_array,masks_array): 168 | 169 | """ 170 | Function to evaluate all mask arrays and return just the files that have non zero masks. 171 | 172 | Parameters: 173 | 174 | images_array = array of images. 175 | 176 | mask_array = array of masks. 177 | 178 | :return images, masks 179 | """ 180 | # 5. Delete all zeros 181 | 182 | # Delete files with just zeros in the mask 183 | all_zeros = [] 184 | for i in range(masks_array.shape[0]): 185 | if masks_array[i].max() == 0: 186 | all_zeros.append(i) 187 | print("There are: {} arrays with just 0 values, and {} arrays with non zero values ".format(len(all_zeros), ( 188 | images_array.shape[0] - len(all_zeros)))) 189 | images = [] 190 | masks = [] 191 | for i in range(images_array.shape[0]): 192 | if i not in all_zeros: 193 | images.append(images_array[i]) 194 | masks.append(masks_array[i]) 195 | 196 | # Convert to array 197 | images = np.array(images, dtype="float32") 198 | masks = np.array(masks, dtype="float32") 199 | print("Image shape: {}, Mask shape: {}".format(images.shape, masks.shape)) 200 | return images, masks 201 | 202 | 203 | def generate_mask(raster_path, shape_path, output_path, file_name): 204 | """ Function to generate a mask from polygons with the same dimensions of an image. 205 | 206 | raster_path = path to .tif image; 207 | 208 | shape_path = path to shapefile or geojson. 209 | 210 | output_path = path to save the binary mask. 211 | 212 | file_name = name of the saved file. 213 | 214 | """ 215 | 216 | # Carregar o Raster 217 | 218 | with rio.open(raster_path, "r") as src: 219 | raster_img = src.read() 220 | raster_meta = src.meta 221 | 222 | # Carregar o shapefile ou GeoJson 223 | train_df = gpd.read_file(shape_path) 224 | 225 | # Verificar se o CRS é o mesmo 226 | if train_df.crs != src.crs: 227 | print( 228 | " Raster CRS : {} Vetor CRS : {}.\n Convert to the same CRS!".format( 229 | src.crs, train_df.crs)) 230 | 231 | # Função para gerar a máscara 232 | def poly_from_utm(polygon, transform): 233 | poly_pts = [] 234 | 235 | poly = cascaded_union(polygon) 236 | for i in np.array(poly.exterior.coords): 237 | poly_pts.append(~transform * tuple(i)) 238 | 239 | new_poly = Polygon(poly_pts) 240 | return new_poly 241 | 242 | poly_shp = [] 243 | im_size = (src.meta['height'], src.meta['width']) 244 | for num, row in train_df.iterrows(): 245 | if row['geometry'].geom_type == 'Polygon': 246 | poly = poly_from_utm(row['geometry'], src.meta['transform']) 247 | poly_shp.append(poly) 248 | else: 249 | for p in row['geometry']: 250 | poly = poly_from_utm(p, src.meta['transform']) 251 | poly_shp.append(poly) 252 | 253 | mask = rasterize(shapes=poly_shp, 254 | out_shape=im_size) 255 | 256 | # Salvar 257 | mask = mask.astype("uint16") 258 | 259 | bin_mask_meta = src.meta.copy() 260 | bin_mask_meta.update({'count': 1}) 261 | os.chdir(output_path) 262 | with rio.open(file_name, 'w', **bin_mask_meta) as dst: 263 | dst.write(mask * 255, 1) 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | affine==2.3.0 2 | albumentations==0.4.5 3 | appnope==0.1.0 4 | attrs==19.3.0 5 | backcall==0.2.0 6 | bleach==3.1.5 7 | certifi==2020.4.5.2 8 | click==7.1.2 9 | click-plugins==1.1.1 10 | cligj==0.5.0 11 | cycler==0.10.0 12 | decorator==4.4.2 13 | defusedxml==0.6.0 14 | entrypoints==0.3 15 | Fiona==1.8.13.post1 16 | geopandas==0.7.0 17 | imageio==2.8.0 18 | imgaug==0.2.6 19 | importlib-metadata==1.6.1 20 | ipykernel==5.3.0 21 | ipython==7.15.0 22 | ipython-genutils==0.2.0 23 | ipywidgets==7.5.1 24 | jedi==0.17.0 25 | Jinja2==2.11.2 26 | joblib==0.15.1 27 | jsonschema==3.2.0 28 | jupyter==1.0.0 29 | jupyter-client==6.1.3 30 | jupyter-console==6.1.0 31 | jupyter-core==4.6.3 32 | kiwisolver==1.2.0 33 | MarkupSafe==1.1.1 34 | matplotlib==3.2.2 35 | mistune==0.8.4 36 | munch==2.5.0 37 | nbconvert==5.6.1 38 | nbformat==5.0.7 39 | networkx==2.4 40 | notebook==6.0.3 41 | numpy==1.16.5 42 | opencv-python-headless==4.2.0.34 43 | packaging==20.4 44 | pandas==1.0.5 45 | pandocfilters==1.4.2 46 | parso==0.7.0 47 | pexpect==4.8.0 48 | pickleshare==0.7.5 49 | Pillow==7.1.2 50 | prometheus-client==0.8.0 51 | prompt-toolkit==3.0.5 52 | ptyprocess==0.6.0 53 | Pygments==2.6.1 54 | pyparsing==2.4.7 55 | pyproj==2.6.1.post1 56 | pyrsistent==0.16.0 57 | python-dateutil==2.8.1 58 | pytz==2020.1 59 | PyWavelets==1.1.1 60 | PyYAML==5.3.1 61 | pyzmq==19.0.1 62 | qtconsole==4.7.4 63 | QtPy==1.9.0 64 | rasterio==1.1.5 65 | scikit-image==0.17.2 66 | scikit-learn==0.23.1 67 | scipy==1.4.1 68 | Send2Trash==1.5.0 69 | Shapely==1.7.0 70 | six==1.15.0 71 | sklearn==0.0 72 | snuggs==1.4.7 73 | terminado==0.8.3 74 | testpath==0.4.4 75 | threadpoolctl==2.1.0 76 | tifffile==2020.6.3 77 | tornado==6.0.4 78 | traitlets==4.3.3 79 | wcwidth==0.2.4 80 | webencodings==0.5.1 81 | widgetsnbextension==3.5.1 82 | zipp==3.1.0 83 | --------------------------------------------------------------------------------