Skip to content

Commit 1a164c7

Browse files
authored
Merge pull request #225 from siapy/fix
2 parents 86768c3 + ec2d469 commit 1a164c7

File tree

6 files changed

+105
-2
lines changed

6 files changed

+105
-2
lines changed

docs/concepts/datasets.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Datasets
2+
3+
??? note "API Documentation"
4+
`siapy.datasets`
5+
6+
The `datasets` module provides structured containers and utilities for transforming spectral image data into formats optimized for analysis and machine learning. It bridges the gap between raw spectral data and analytical workflows.
7+
8+
```python
9+
--8<-- "docs/concepts/src/datasets_01.py"
10+
```

docs/concepts/entities.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,21 @@ The example below demonstrates two key conversion methods of `SpectralImage` ins
159159
--8<-- "docs/concepts/src/spectral_image_05.py"
160160
```
161161

162-
<!-- ### Manipulation of shapes -->
162+
### Manipulation of Shapes
163+
164+
Each `SpectralImage` instance automatically initializes a `GeometricShapes` object as a property called `geometric_shapes`. This property provides a container for managing shape objects associated with the image. It lets you work with image regions while maintaining the connection between spatial geometries and their spectral data. This is particularly useful for region-based analysis, masking, and feature extraction from specific areas of interest.
165+
166+
The `GeometricShapes` class provides a list-like interface that wraps a standard Python list, enhancing it with specialized functionality for manipulating geometric shapes while preserving standard list behavior. The list of shapes can be accessed via the `image.geometric_shapes.shapes` property.
167+
168+
```python
169+
--8<-- "docs/concepts/src/spectral_image_shapes_01.py:init"
170+
```
171+
172+
As a result, shapes can be added to the spectral image using standard list operations. The example below demonstrates how this can be done:
173+
174+
```python
175+
--8<-- "docs/concepts/src/spectral_image_shapes_01.py:operations"
176+
```
163177

164178
## Spectral Image Set
165179

docs/concepts/src/datasets_01.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import numpy as np
2+
from rich import print
3+
4+
from siapy.datasets.tabular import TabularDataset
5+
from siapy.entities import Shape, SpectralImage, SpectralImageSet
6+
7+
# Create two mock spectral images with dimensions 100x100 pixels and 10 bands
8+
rng = np.random.default_rng(seed=42)
9+
image1 = SpectralImage.from_numpy(rng.random((100, 100, 10)))
10+
image2 = SpectralImage.from_numpy(rng.random((100, 100, 10)))
11+
12+
# Define a region of interest as a rectangular shape (coordinates in pixel space)
13+
# This will select pixels from position (50,50) to (80,80) in both images
14+
rectangle = Shape.from_rectangle(x_min=50, y_min=50, x_max=80, y_max=80)
15+
image1.geometric_shapes.append(rectangle)
16+
image2.geometric_shapes.append(rectangle)
17+
18+
# Combine the images into a SpectralImageSet for batch processing
19+
image_set = SpectralImageSet([image1, image2])
20+
21+
# Initialize the TabularDataset with our image set and process the data
22+
# This extracts pixel data from the regions defined by our shapes
23+
dataset = TabularDataset(image_set)
24+
dataset.process_image_data()
25+
26+
# The dataset is now iterable - we can access each entity (processed region)
27+
for entity in dataset:
28+
print(f"Processing entity: {entity}")
29+
30+
# Generate tabular data from our processed dataset
31+
# Setting mean_signatures=False preserves individual pixel values instead of averaging them
32+
dataset_data = dataset.generate_dataset_data(mean_signatures=False)
33+
34+
# Convert the tabular data to a pandas DataFrame with multi-level indexing
35+
# This makes it easy to analyze and manipulate the data
36+
df = dataset_data.to_dataframe_multiindex()
37+
38+
print(f"dataset_data: \n{dataset_data}")
39+
print(f"df: \n{df}")
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# --8<-- [start:init]
2+
import numpy as np
3+
from rich import print
4+
5+
from siapy.entities import Shape, SpectralImage
6+
from siapy.entities.shapes import GeometricShapes
7+
8+
# Create a mock spectral image
9+
rng = np.random.default_rng(seed=42)
10+
array = rng.random((100, 100, 10)) # height, width, bands
11+
image = SpectralImage.from_numpy(array)
12+
13+
# SpectralImage automatically initializes GeometricShapes
14+
assert isinstance(image.geometric_shapes, GeometricShapes)
15+
# You can access the underlying list via the shapes property
16+
assert isinstance(image.geometric_shapes.shapes, list)
17+
18+
# GeometricShapes implements common list operations directly, i.e. number of shapes:
19+
length_via_geometric_shapes = len(image.geometric_shapes)
20+
length_via_raw_list = len(image.geometric_shapes.shapes)
21+
# --8<-- [end:init]
22+
23+
# --8<-- [start:operations]
24+
# Create two Shape objects with distinct spatial coordinates and semantic labels
25+
coords1 = [(1, 2), (3, 4), (2, 4)]
26+
shape1 = Shape.from_multipoint(coords1, label="coords1")
27+
coords2 = [(19, 20), (21, 22), (20, 22)]
28+
shape2 = Shape.from_multipoint(coords2, label="coords2")
29+
30+
# Add multiple shapes to the SpectralImage's geometric_shapes container at once
31+
image.geometric_shapes.extend([shape1, shape2])
32+
33+
# Display the current collection of shapes stored in the image
34+
# Each shape will be shown with its type and label
35+
print(f"Shapes in GeometricShapes: {image.geometric_shapes}")
36+
37+
# --8<-- [end:operations]

mkdocs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ nav:
6767
- Concepts:
6868
- Overview: concepts/overview.md
6969
- Entities: concepts/entities.md
70-
# - Datasets: concepts/datasets.md
70+
- Datasets: concepts/datasets.md
7171
# - Features: concepts/features.md
7272
# - Optimizers: concepts/optimizers.md
7373
# - Transformations: concepts/transformations.md

siapy/entities/shapes/geometric_shapes.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ def __init__(
2626
self._geometric_shapes = geometric_shapes if geometric_shapes is not None else []
2727
_check_shape_type(self._geometric_shapes, is_list=True)
2828

29+
def __repr__(self) -> str:
30+
return f"GeometricShapes(\n{self._geometric_shapes}\n)"
31+
2932
def __iter__(self) -> Iterator["Shape"]:
3033
return iter(self.shapes)
3134

0 commit comments

Comments
 (0)