├── Data ├── DSM.tif ├── DSM_cliped.tif ├── qgis_stacked.tif ├── imagery_Subset.img └── imagery_subset_cliped.tif ├── images ├── image.png ├── image-1.png ├── image-2.png ├── image-3.png └── image-4.png ├── Outputs └── segments.tif ├── README.md └── spatialenv.yaml /Data/DSM.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/candepelliza/OBIA_Python/HEAD/Data/DSM.tif -------------------------------------------------------------------------------- /images/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/candepelliza/OBIA_Python/HEAD/images/image.png -------------------------------------------------------------------------------- /Data/DSM_cliped.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/candepelliza/OBIA_Python/HEAD/Data/DSM_cliped.tif -------------------------------------------------------------------------------- /images/image-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/candepelliza/OBIA_Python/HEAD/images/image-1.png -------------------------------------------------------------------------------- /images/image-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/candepelliza/OBIA_Python/HEAD/images/image-2.png -------------------------------------------------------------------------------- /images/image-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/candepelliza/OBIA_Python/HEAD/images/image-3.png -------------------------------------------------------------------------------- /images/image-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/candepelliza/OBIA_Python/HEAD/images/image-4.png -------------------------------------------------------------------------------- /Data/qgis_stacked.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/candepelliza/OBIA_Python/HEAD/Data/qgis_stacked.tif -------------------------------------------------------------------------------- /Outputs/segments.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/candepelliza/OBIA_Python/HEAD/Outputs/segments.tif -------------------------------------------------------------------------------- /Data/imagery_Subset.img: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/candepelliza/OBIA_Python/HEAD/Data/imagery_Subset.img -------------------------------------------------------------------------------- /Data/imagery_subset_cliped.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/candepelliza/OBIA_Python/HEAD/Data/imagery_subset_cliped.tif -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Object Based Image Analysis (OBIA) with Python 2 | 3 | _August, 2023_ 4 | 5 | Authors: [Candela Sol Pelliza](https://candelasolpelliza.com/) & [Rodrigo Brust Santos](rodrigobrust.com) 6 | 7 | Application Development (Object-Based Image Analysis) 8 | 9 | - Dr. Prof. Dirk Tiede & Dr. Prof Martin Sudmanns 10 | 11 | # Table of Contents 12 | 13 | 1. [Introduction](#introduction) 14 | 2. [Objectives](#objectives) 15 | 3. [Results](#results) 16 | 4. [References](#references) 17 | 18 | ___ 19 | 20 | ## Introduction 21 | 22 | This repository is the development of the final project for Application Development lecture. 23 | 24 | In the Remote Sensing industry, OBIA is a technique that aims to utilize objects instead of pixels when analyzing an image. 25 | 26 | From a satellite scene, one must segment pixel values in groups with similar values, following up for the classification. 27 | 28 | It is a powerful approach, since it is fiasible to utilize several bands and rasters, such as the regular RGB but also DEM and DSM, leading to more reliable classification - and avoiding salt-peper effect. 29 | 30 | ## Objectives 31 | 32 | In the EO*GI industry, there are a lot of softwares and resources that are very convinient, however an expensive subscription is necessary. Also, finding a good OBIA workflow is an exhausthing process. 33 | 34 | Having that in mind, this project has two main objectives: 35 | 36 | 1 - Apply the concepts of OBIA with Python on a 5-band-scene, using R, G, B, and NIR bands in addition to a DSM. 37 | 38 | 39 | 40 | - Classify high/low vegetation, road and houses based on NDVI and height. 41 | 42 | - Export classified segments to geojson. 43 | 44 | ![Alt text](images/image.png) 45 | 46 | 2 - Provide a resource for students and industry players from an open-source software. 47 | 48 | 49 | ## Results 50 | 51 | To achieve the result, there were a couple of steps: 52 | 53 | 1 - Segment the image with scikit-image quickshift algorithm. 54 | 55 | 2 - Create the mean of rgb for each object 56 | 57 | ![Alt text](images/image-3.png) 58 | 59 | 3 - Calculate the mean NDVI and Height for each object 60 | 61 | ![Alt text](images/image-2.png) 62 | 63 | 4 - Create rules and assign classes 64 | 65 | - In total, there were 5 classes: `unclassified`, `low vegetation`, `trees`, `roads` and `buildings`. 66 | 67 | 5 - Generate the classified image 68 | 69 | ![Alt text](images/image-4.png) 70 | 71 | 72 | ## References 73 | 74 | - [Tips for GIS - DEM Raster Analysis](https://github.com/TipsForGIS/dem-raster-analysis/blob/master/dem.ipynb) 75 | 76 | - [OBIA Tutorials by fkroeber](https://github.com/fkroeber/obia_tutorials) 77 | 78 | - [Open Source Options - OBIA](https://opensourceoptions.com/blog/python-geographic-object-based-image-analysis-geobia/) 79 | 80 | - [OBIA Land Cover Classification With Python](https://towardsdatascience.com/object-based-land-cover-classification-with-python-cbe54e9c9e24) 81 | 82 | - [Intro Raster: Fundamentals for Raster with Python](https://www.earthdatascience.org/courses/use-data-open-source-python/intro-raster-data-python/fundamentals-raster-data/open-lidar-raster-python/) 83 | -------------------------------------------------------------------------------- /spatialenv.yaml: -------------------------------------------------------------------------------- 1 | name: spatialenv 2 | channels: 3 | - conda-forge 4 | - defaults 5 | dependencies: 6 | - asttokens=2.2.1=pyhd8ed1ab_0 7 | - backcall=0.2.0=pyh9f0ad1d_0 8 | - backports=1.0=pyhd8ed1ab_3 9 | - backports.functools_lru_cache=1.6.4=pyhd8ed1ab_0 10 | - blosc=1.21.3=h6c2663c_0 11 | - boost-cpp=1.74.0=h5b4e17d_6 12 | - bzip2=1.0.8=h8ffe710_4 13 | - ca-certificates=2023.5.7=h56e8100_0 14 | - cairo=1.16.0=h63a05c6_1001 15 | - certifi=2023.5.7=pyhd8ed1ab_0 16 | - cfitsio=3.470=h2bbff1b_7 17 | - colorama=0.4.6=pyhd8ed1ab_0 18 | - curl=7.88.1=h2bbff1b_0 19 | - debugpy=1.5.1=py39hd77b12b_0 20 | - decorator=5.1.1=pyhd8ed1ab_0 21 | - executing=1.2.0=pyhd8ed1ab_0 22 | - expat=2.5.0=h63175ca_1 23 | - fontconfig=2.14.1=h9c4af85_2 24 | - freetype=2.10.4=h546665d_1 25 | - freexl=1.0.6=ha8e266a_0 26 | - gdal=3.6.2=py39h9eae49a_1 27 | - geos=3.8.0=h33f27b4_0 28 | - geotiff=1.7.0=h4545760_1 29 | - glib=2.69.1=h5dc1a3c_2 30 | - hdf4=4.2.13=h712560f_2 31 | - hdf5=1.10.6=nompi_h5268f04_1114 32 | - icu=58.2=ha925a31_3 33 | - importlib-metadata=6.1.0=pyha770c72_0 34 | - importlib_metadata=6.1.0=hd8ed1ab_0 35 | - intel-openmp=2023.1.0=h57928b3_46319 36 | - ipykernel=6.15.0=pyh025b116_0 37 | - ipython=8.12.0=pyh08f2357_0 38 | - jedi=0.18.2=pyhd8ed1ab_0 39 | - jpeg=9e=h8ffe710_2 40 | - jupyter_client=8.1.0=pyhd8ed1ab_0 41 | - jupyter_core=5.3.0=py39hcbf5309_0 42 | - kealib=1.5.0=hde4a422_0 43 | - krb5=1.19.3=h1176d77_0 44 | - lcms2=2.12=h83e58a3_0 45 | - lerc=3.0=hd77b12b_0 46 | - libblas=3.9.0=8_mkl 47 | - libcblas=3.9.0=8_mkl 48 | - libcurl=7.88.1=h86230a5_0 49 | - libdeflate=1.17=h2bbff1b_0 50 | - libexpat=2.5.0=h63175ca_1 51 | - libffi=3.4.2=h8ffe710_5 52 | - libgdal=3.6.2=h11d7215_1 53 | - libiconv=1.17=h8ffe710_0 54 | - libkml=1.3.0=h9859afa_1014 55 | - liblapack=3.9.0=8_mkl 56 | - libnetcdf=4.8.1=h6685c40_2 57 | - libpng=1.6.39=h8cc25b3_0 58 | - libpq=12.9=hb652d5d_3 59 | - libsodium=1.0.18=h8d14728_1 60 | - libspatialite=4.3.0a=h6ec8781_23 61 | - libssh2=1.10.0=h680486a_2 62 | - libtiff=4.5.0=h6c2663c_2 63 | - libwebp-base=1.2.4=h2bbff1b_1 64 | - libxml2=2.10.3=h0ad7f3c_0 65 | - libzip=1.8.0=h49b8836_0 66 | - lz4-c=1.9.4=h2bbff1b_0 67 | - matplotlib-inline=0.1.6=pyhd8ed1ab_0 68 | - mkl=2020.4=hb70f87d_311 69 | - nest-asyncio=1.5.6=pyhd8ed1ab_0 70 | - openjpeg=2.4.0=h4fc8c34_0 71 | - openssl=1.1.1t=h2bbff1b_0 72 | - packaging=23.0=pyhd8ed1ab_0 73 | - parso=0.8.3=pyhd8ed1ab_0 74 | - pcre=8.45=h0e60522_0 75 | - pcre2=10.37=h0ff8eda_1 76 | - pickleshare=0.7.5=py_1003 77 | - pip=23.0.1=py39haa95532_0 78 | - pixman=0.38.0=hfa6e2cd_1003 79 | - platformdirs=3.2.0=pyhd8ed1ab_0 80 | - poppler=22.12.0=h268424c_0 81 | - poppler-data=0.4.12=hd8ed1ab_0 82 | - postgresql=12.9=hb652d5d_3 83 | - proj=6.2.1=h3758d61_0 84 | - prompt-toolkit=3.0.38=pyha770c72_0 85 | - prompt_toolkit=3.0.38=hd8ed1ab_0 86 | - psutil=5.9.0=py39h2bbff1b_0 87 | - pure_eval=0.2.2=pyhd8ed1ab_0 88 | - pygments=2.14.0=pyhd8ed1ab_0 89 | - python=3.9.16=h6244533_2 90 | - python-dateutil=2.8.2=pyhd8ed1ab_0 91 | - python_abi=3.9=2_cp39 92 | - pywin32=305=py39h2bbff1b_0 93 | - pyzmq=23.2.0=py39hd77b12b_0 94 | - qhull=2020.2=h70d2c02_2 95 | - setuptools=65.6.3=py39haa95532_0 96 | - six=1.16.0=pyh6c4a22f_0 97 | - sqlite=3.41.1=h2bbff1b_0 98 | - stack_data=0.6.2=pyhd8ed1ab_0 99 | - tiledb=2.3.3=h3649cd2_2 100 | - tornado=6.2=py39hb82d6ee_0 101 | - traitlets=5.9.0=pyhd8ed1ab_0 102 | - typing-extensions=4.5.0=hd8ed1ab_0 103 | - typing_extensions=4.5.0=pyha770c72_0 104 | - tzdata=2022g=h04d1e81_0 105 | - vc=14.2=h21ff451_1 106 | - vs2015_runtime=14.27.29016=h5e58377_2 107 | - wcwidth=0.2.6=pyhd8ed1ab_0 108 | - wheel=0.38.4=py39haa95532_0 109 | - wincertstore=0.2=py39haa95532_2 110 | - xerces-c=3.2.4=hd77b12b_0 111 | - xz=5.4.2=h8cc25b3_0 112 | - zeromq=4.3.4=h0e60522_1 113 | - zipp=3.15.0=pyhd8ed1ab_0 114 | - zlib=1.2.13=h8cc25b3_0 115 | - zstd=1.5.5=hd43e919_0 116 | - pip: 117 | - affine==2.4.0 118 | - attrs==22.2.0 119 | - branca==0.6.0 120 | - cffi==1.15.1 121 | - charset-normalizer==3.1.0 122 | - click==7.1.2 123 | - click-plugins==1.1.1 124 | - cligj==0.7.2 125 | - contourpy==1.0.7 126 | - cryptography==41.0.1 127 | - cycler==0.11.0 128 | - deprecated==1.2.14 129 | - earthpy==0.9.4 130 | - et-xmlfile==1.1.0 131 | - fiona==1.9.2 132 | - folium==0.14.0 133 | - fonttools==4.39.3 134 | - geographiclib==2.0 135 | - geojson==3.0.1 136 | - geomet==1.0.0 137 | - geopandas==0.12.2 138 | - geopy==2.3.0 139 | - gitdb==4.0.10 140 | - gitpython==3.1.31 141 | - html2text==2020.1.16 142 | - idna==3.4 143 | - imageio==2.31.1 144 | - importlib-resources==5.12.0 145 | - jinja2==3.1.2 146 | - kiwisolver==1.4.4 147 | - landsatxplore==0.15.0 148 | - lazy-loader==0.3 149 | - mahotas==1.4.13 150 | - markupsafe==2.1.3 151 | - matplotlib==3.7.1 152 | - munch==2.5.0 153 | - networkx==3.1 154 | - numpy==1.25.1 155 | - ogr==0.45.0 156 | - opencv-python==4.8.0.74 157 | - openpyxl==3.1.2 158 | - osmnx==1.3.0 159 | - pandas==1.5.3 160 | - pillow==9.5.0 161 | - plotly==5.15.0 162 | - pychrone==0.0.3 163 | - pycparser==2.21 164 | - pygithub==1.59.0 165 | - pyjwt==2.7.0 166 | - pynacl==1.5.0 167 | - pyparsing==3.0.9 168 | - pyproj==3.4.1 169 | - python-gitlab==3.15.0 170 | - pytz==2022.7.1 171 | - pywavelets==1.4.1 172 | - pyyaml==6.0 173 | - rasterio==1.3.8 174 | - requests==2.28.2 175 | - requests-toolbelt==1.0.0 176 | - rioxarray==0.14.1 177 | - scikit-image==0.21.0 178 | - scipy==1.10.1 179 | - sentinelsat==1.2.1 180 | - shapely==1.8.5.post1 181 | - sklearn==0.0.post7 182 | - smmap==5.0.0 183 | - snuggs==1.4.7 184 | - tenacity==8.2.2 185 | - tifffile==2023.4.12 186 | - tqdm==4.65.0 187 | - urllib3==1.26.15 188 | - wrapt==1.15.0 189 | - xarray==2023.7.0 190 | --------------------------------------------------------------------------------