|
1 | 1 | # Entities |
2 | 2 |
|
3 | | -Entities form the core data structures in SiaPy that represent fundamental elements of spectral image processing. They provide consistent interfaces for working with various kinds of spectral data and spatial information. |
| 3 | +Entities serve as the foundational data structures in SiaPy, representing key elements of spectral image analysis and processing workflows. They implement consistent, strongly-typed interfaces that allow seamless interaction between spectral data, spatial coordinates, and geometric information. |
4 | 4 |
|
5 | | -## Overview |
| 5 | +## Design principles |
6 | 6 |
|
7 | | -The SiaPy Entities module defines a set of interconnected classes that represent the foundational building blocks for spectral image analysis: |
| 7 | +SiaPy's architecture follows several key design principles: |
8 | 8 |
|
9 | | -- **SpectralImage**: A generic container for different types of hyperspectral/multispectral images |
10 | | -- **SpectralImageSet**: A collection of spectral images |
11 | | -- **Pixels**: Spatial coordinates within an image |
12 | | -- **Signatures**: Spectral signals associated with specific pixel locations |
13 | | -- **Shape**: Geometric shapes associated with image locations (points, lines, polygons) |
| 9 | +**Specialized yet compatible**: Each entity is optimized for its specific role while maintaining compatibility with the broader SiaPy ecosystem |
14 | 10 |
|
15 | | -These entity classes are designed to work together, forming a cohesive system for analyzing spectral imagery. |
| 11 | +**Independence**: Most entities can function independently (with the exception of abstract base classes) |
16 | 12 |
|
17 | | -## SpectralImage |
| 13 | +**Composition over inheritance**: |
18 | 14 |
|
19 | | -A `SpectralImage` is the primary container for spectral image data. It's a generic class that can wrap different image backends: |
| 15 | +- The composition is preferred, so that one class can leverage another by injecting it into its architecture |
| 16 | +- Inheritance is primarily used to implement common interfaces through base classes |
20 | 17 |
|
21 | | -```python |
22 | | -from siapy.entities import SpectralImage |
23 | | - |
24 | | -# Load from ENVI format |
25 | | -image = SpectralImage.spy_open( |
26 | | - header_path="path/to/header.hdr", |
27 | | - image_path="path/to/image.img" |
28 | | -) |
| 18 | +**Extensibility**: |
29 | 19 |
|
30 | | -# Load from GeoTIFF or other raster formats |
31 | | -image = SpectralImage.rasterio_open(filepath="path/to/image.tif") |
| 20 | +- The `SpectralImage` class supports multiple data sources through *spectral* or *rasterio* libraries, however, custom data loading can be implemented by creating your own driver |
| 21 | +- Basic geometric shapes (e.g. points, lines, polygons) are implemented using the *shapely* library, which could also be extended through base abstraction |
32 | 22 |
|
33 | | -# Create from NumPy array |
34 | | -import numpy as np |
35 | | -array = np.zeros((100, 100, 10)) # height, width, bands |
36 | | -image = SpectralImage.from_numpy(array) |
37 | | -``` |
| 23 | +The class structure is depicted in the following diagram: |
38 | 24 |
|
39 | | -### Key Properties |
| 25 | + |
40 | 26 |
|
41 | | -- **shape**: Dimensions as (height, width, bands) |
42 | | -- **width**, **height**: Image dimensions |
43 | | -- **bands**: Number of spectral bands |
44 | | -- **wavelengths**: List of wavelength values for each band |
45 | | -- **default_bands**: Default bands for RGB visualization |
46 | | -- **metadata**: Dictionary of metadata from the image file |
47 | | -- **filepath**: Path to the source file |
48 | | -- **camera_id**: Camera identifier (if available) |
49 | | -- **geometric_shapes**: Associated geometric shapes collection |
| 27 | +## Spectral Image |
50 | 28 |
|
51 | | -### Key Methods |
| 29 | +A `SpectralImage` is the primary container for spectral image data. It's a generic class that can wrap different image backends, allowing you to work with various file formats through a unified interface. |
52 | 30 |
|
53 | | -- **to_numpy()**: Convert to NumPy array |
54 | | -- **to_display()**: Convert to PIL Image for visualization |
55 | | -- **to_xarray()**: Convert to xarray.DataArray |
56 | | -- **to_signatures()**: Extract signatures at specified pixels |
57 | | -- **to_subarray()**: Extract a subarray for a region of interest |
58 | | -- **average_intensity()**: Calculate mean intensity across specified axes |
| 31 | +### Image Initialization Options |
59 | 32 |
|
60 | | -## Pixels |
| 33 | +#### 1. Load from ENVI format (using spectral python) |
61 | 34 |
|
62 | | -The `Pixels` class represents spatial coordinates within an image, typically stored as x,y pairs. |
| 35 | +This is commonly used for hyperspectral imagery from airborne or satellite sensors. |
63 | 36 |
|
64 | 37 | ```python |
65 | | -from siapy.entities import Pixels |
66 | | - |
67 | | -# Create from list of coordinates |
68 | | -pixels = Pixels.from_iterable([(10, 20), (30, 40), (50, 60)]) |
69 | | - |
70 | | -# Load from parquet file |
71 | | -pixels = Pixels.load_from_parquet("pixels.parquet") |
| 38 | +--8<-- "docs/concepts/src/spectral_image_01.py" |
72 | 39 | ``` |
73 | 40 |
|
74 | | -### Key Properties |
75 | | - |
76 | | -- **df**: Underlying pandas DataFrame with x,y coordinates |
77 | | -- **coords**: Coordinate system definition |
| 41 | +#### 2. Load from GeoTIFF or other geospatial formats (using rasterio) |
78 | 42 |
|
79 | | -### Key Methods |
80 | | - |
81 | | -- **x()**, **y()**: Access x and y coordinates as pandas Series |
82 | | -- **to_numpy()**: Convert to NumPy array |
83 | | -- **to_list()**: Convert to list of coordinates |
84 | | -- **as_type()**: Convert coordinates to a specific data type |
85 | | -- **get_coordinate()**: Get a specific coordinate pair |
86 | | -- **df_homogenious()**: Get homogeneous coordinates (x,y,1) |
87 | | - |
88 | | -## Signatures |
89 | | - |
90 | | -The `Signatures` class combines `Pixels` with their corresponding spectral signals. |
| 43 | +Perfect for georeferenced data with spatial information. |
91 | 44 |
|
92 | 45 | ```python |
93 | | -from siapy.entities import Signatures, Pixels, Signals |
94 | | - |
95 | | -# Create from pixels and signals |
96 | | -pixels = Pixels.from_iterable([(10, 20), (30, 40)]) |
97 | | -signals_df = pd.DataFrame([[0.1, 0.2, 0.3], [0.4, 0.5, 0.6]]) # 2 pixels, 3 bands |
98 | | -signals = Signals(signals_df) |
99 | | -signatures = Signatures(pixels, signals) |
100 | | - |
101 | | -# Extract signatures from an image at specific pixels |
102 | | -pixels = Pixels.from_iterable([(10, 20), (30, 40)]) |
103 | | -signatures = spectral_image.to_signatures(pixels) |
| 46 | +--8<-- "docs/concepts/src/spectral_image_02.py" |
104 | 47 | ``` |
105 | 48 |
|
106 | | -### Key Properties |
| 49 | +#### 3. Create from numpy array |
107 | 50 |
|
108 | | -- **pixels**: The `Pixels` object with coordinate information |
109 | | -- **signals**: The `Signals` object with spectral values |
110 | | - |
111 | | -### Key Methods |
112 | | - |
113 | | -- **to_dataframe()**: Convert to a pandas DataFrame |
114 | | -- **to_dataframe_multiindex()**: Convert to a DataFrame with MultiIndex columns |
115 | | -- **to_numpy()**: Convert to tuple of NumPy arrays (pixels, signals) |
116 | | -- **to_dict()**: Convert to dictionary representation |
117 | | -- **reset_index()**: Reset DataFrame indices |
118 | | -- **copy()**: Create a deep copy |
119 | | - |
120 | | -## Signals |
121 | | - |
122 | | -The `Signals` class represents spectral values associated with pixels. |
| 51 | +Useful for testing or when you already have image data in memory. |
123 | 52 |
|
124 | 53 | ```python |
125 | | -from siapy.entities.signatures import Signals |
126 | | - |
127 | | -# Create from DataFrame |
128 | | -signals_df = pd.DataFrame([[0.1, 0.2, 0.3], [0.4, 0.5, 0.6]]) # 2 pixels, 3 bands |
129 | | -signals = Signals(signals_df) |
130 | | - |
131 | | -# Create from iterable |
132 | | -signals = Signals.from_iterable([[0.1, 0.2, 0.3], [0.4, 0.5, 0.6]]) |
| 54 | +--8<-- "docs/concepts/src/spectral_image_03.py" |
133 | 55 | ``` |
134 | 56 |
|
135 | | -### Key Properties |
136 | | - |
137 | | -- **df**: Underlying pandas DataFrame with spectral values |
138 | | - |
139 | | -### Key Methods |
| 57 | +#### 4. Create your own custom image class |
140 | 58 |
|
141 | | -- **to_numpy()**: Convert to NumPy array |
142 | | -- **average_signal()**: Calculate mean signal across specified axis |
143 | | -- **save_to_parquet()**: Save to parquet file |
144 | | - |
145 | | -## Shape |
146 | | - |
147 | | -The `Shape` class represents geometric shapes that can be associated with images, such as points, lines, and polygons. |
| 59 | +For specialized file formats or custom processing needs, you can extend the ImageBase class. |
148 | 60 |
|
149 | 61 | ```python |
150 | | -from siapy.entities import Shape |
151 | | -from siapy.entities import Pixels |
| 62 | +--8<-- "docs/concepts/src/spectral_image_04.py" |
| 63 | +``` |
152 | 64 |
|
153 | | -# Create a point |
154 | | -point = Shape.from_point(10, 20) |
| 65 | +## Pixels |
155 | 66 |
|
156 | | -# Create a polygon from pixels |
157 | | -pixels = Pixels.from_iterable([(0, 0), (10, 0), (10, 10), (0, 10)]) |
158 | | -polygon = Shape.from_polygon(pixels) |
| 67 | +The `Pixels` class represents spatial coordinates within spectral image, providing a container for *(x, y)* coordinate pairs. It uses pandas DataFrame internally for storage, enabling high-performance operations. The class provides multiple initialization methods and conversion functions to work with different data representations (i.e. DataFrames, list, arrays) |
159 | 68 |
|
160 | | -# Load from shapefile |
161 | | -shape = Shape.open_shapefile("path/to/shapefile.shp") |
| 69 | +```python |
| 70 | +--8<-- "docs/concepts/src/pixels_01.py" |
162 | 71 | ``` |
163 | 72 |
|
164 | | -### Shape Types |
| 73 | +## Signals |
165 | 74 |
|
166 | | -- **Point**: Single coordinate point (x,y) |
167 | | -- **LineString**: Series of connected points forming a line |
168 | | -- **Polygon**: Closed shape with interior area |
169 | | -- **MultiPoint**: Collection of independent points |
170 | | -- **MultiLineString**: Collection of independent lines |
171 | | -- **MultiPolygon**: Collection of independent polygons |
| 75 | +The `Signals` class stores spectral data for each pixel in a pandas DataFrame, allowing you to use any column names you choose (e.g. "band_1", "nir", "red_edge"). You can initialize it from a DataFrame, lists, dicts or NumPy arrays. |
172 | 76 |
|
173 | | -### Key Properties |
| 77 | +```python |
| 78 | +--8<-- "docs/concepts/src/signals_01.py" |
| 79 | +``` |
174 | 80 |
|
175 | | -- **geometry**: The underlying shapely geometry |
176 | | -- **label**: Optional label for the shape |
177 | | -- **shape_type**: Type of geometry (point, line, polygon, etc.) |
178 | | -- **bounds**: Bounding box of the shape |
179 | | -- **centroid**: Centroid point of the shape |
| 81 | +## Signatures |
180 | 82 |
|
181 | | -### Key Methods |
| 83 | +The `Signatures` class represents spectral data collections by combining spatial coordinates (`Pixels`) with their corresponding spectral values (`Signals`). It provides a unified container that maintains the spatial-spectral relationship, allowing for analysis of spectral information at specific image locations. Internally, the data is stored as pandas DataFrames for efficient operations and indexing. |
182 | 84 |
|
183 | | -- **buffer()**: Create a buffered version of the shape |
184 | | -- **intersection()**: Find intersection with another shape |
185 | | -- **union()**: Combine with another shape |
186 | | -- **to_file()**: Save to a shapefile |
| 85 | +```python |
| 86 | +--8<-- "docs/concepts/src/signatures_01.py" |
| 87 | +``` |
187 | 88 |
|
188 | | -## GeometricShapes |
| 89 | +## Shape |
189 | 90 |
|
190 | | -The `GeometricShapes` class manages a collection of shapes associated with a spectral image. |
| 91 | +The `Shape` class represents geometric shapes that can be associated with images, such as points, lines, and polygons. |
191 | 92 |
|
192 | 93 | ```python |
193 | | -# Access shapes associated with an image |
194 | | -image = SpectralImage.spy_open(header_path="...", image_path="...") |
195 | | -shapes = image.geometric_shapes |
196 | | - |
197 | | -# Add a shape |
198 | | -polygon = Shape.from_rectangle(10, 20, 30, 40) |
199 | | -shapes.append(polygon) |
200 | | - |
201 | | -# Find a shape by name |
202 | | -shape = shapes.get_by_name("vegetation") |
| 94 | +--8<-- "docs/concepts/src/shapes_01.py" |
203 | 95 | ``` |
204 | 96 |
|
205 | | -### Key Methods |
206 | | - |
207 | | -- **append()**, **extend()**: Add shapes to the collection |
208 | | -- **remove()**, **pop()**, **clear()**: Remove shapes |
209 | | -- **index()**, **count()**: Find and count shapes |
210 | | -- **get_by_name()**: Find a shape by its label |
211 | | - |
212 | 97 | ## SpectralImageSet |
213 | 98 |
|
214 | 99 | The `SpectralImageSet` class manages a collection of spectral images. |
215 | 100 |
|
216 | 101 | ```python |
217 | | -from siapy.entities import SpectralImageSet |
218 | | -from pathlib import Path |
219 | | - |
220 | | -# Load multiple images |
221 | | -header_paths = list(Path("data_dir").glob("*.hdr")) |
222 | | -image_paths = list(Path("data_dir").glob("*.img")) |
223 | | -image_set = SpectralImageSet.spy_open( |
224 | | - header_paths=header_paths, |
225 | | - image_paths=image_paths |
226 | | -) |
227 | | - |
228 | | -# Access images |
229 | | -first_image = image_set[0] |
230 | | - |
231 | | -# Sort images |
232 | | -image_set.sort() |
| 102 | +--8<-- "docs/concepts/src/spectral_image_set_01.py" |
233 | 103 | ``` |
234 | | - |
235 | | -### Key Properties |
236 | | - |
237 | | -- **images**: List of SpectralImage objects |
238 | | -- **cameras_id**: List of unique camera IDs |
239 | | - |
240 | | -### Key Methods |
241 | | - |
242 | | -- **images_by_camera_id()**: Get images from a specific camera |
243 | | -- **sort()**: Sort the images |
244 | | - |
245 | | -## Relationship Between Entities |
246 | | - |
247 | | -The entities in SiaPy form a cohesive system: |
248 | | - |
249 | | -1. A `SpectralImage` contains pixel data across multiple spectral bands |
250 | | -2. `Pixels` represent spatial coordinates within that image |
251 | | -3. `Signals` contain spectral values at those coordinates |
252 | | -4. `Signatures` combine pixels and signals to represent spectral signatures at specific locations |
253 | | -5. `Shape` objects define geometric regions in the image |
254 | | -6. `GeometricShapes` organize multiple shapes associated with an image |
255 | | -7. `SpectralImageSet` manages multiple related spectral images |
256 | | - |
257 | | -This modular design allows for flexible workflows in spectral image analysis - from loading image data, to selecting regions of interest, to extracting and analyzing spectral signatures. |
0 commit comments