├── 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 | 
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 | 
58 |
59 | 3 - Calculate the mean NDVI and Height for each object
60 |
61 | 
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 | 
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 |
--------------------------------------------------------------------------------