urban-imageable 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- urban_imageable-0.1.0/.gitignore +54 -0
- urban_imageable-0.1.0/LICENSE +24 -0
- urban_imageable-0.1.0/PKG-INFO +319 -0
- urban_imageable-0.1.0/README.md +275 -0
- urban_imageable-0.1.0/pyproject.toml +286 -0
- urban_imageable-0.1.0/src/imageable/__init__.py +70 -0
- urban_imageable-0.1.0/src/imageable/_correction_ensembles/__init__.py +0 -0
- urban_imageable-0.1.0/src/imageable/_correction_ensembles/cluster_weighted_ensemble.py +456 -0
- urban_imageable-0.1.0/src/imageable/_correction_ensembles/model_factories.py +15 -0
- urban_imageable-0.1.0/src/imageable/_dataset_builder/__init__.py +0 -0
- urban_imageable-0.1.0/src/imageable/_dataset_builder/dataset_from_gdf.py +164 -0
- urban_imageable-0.1.0/src/imageable/_extraction/__init__.py +0 -0
- urban_imageable-0.1.0/src/imageable/_extraction/building.py +445 -0
- urban_imageable-0.1.0/src/imageable/_extraction/extract.py +323 -0
- urban_imageable-0.1.0/src/imageable/_extraction/footprint.py +863 -0
- urban_imageable-0.1.0/src/imageable/_extraction/image.py +325 -0
- urban_imageable-0.1.0/src/imageable/_features/__init__.py +0 -0
- urban_imageable-0.1.0/src/imageable/_features/height/__init__.py +0 -0
- urban_imageable-0.1.0/src/imageable/_features/height/building_height.py +714 -0
- urban_imageable-0.1.0/src/imageable/_features/height/image.jpg +0 -0
- urban_imageable-0.1.0/src/imageable/_features/height/metadata.json +21 -0
- urban_imageable-0.1.0/src/imageable/_features/materials/__init__.py +0 -0
- urban_imageable-0.1.0/src/imageable/_features/materials/building_materials.py +399 -0
- urban_imageable-0.1.0/src/imageable/_images/__init__.py +0 -0
- urban_imageable-0.1.0/src/imageable/_images/acquisition.py +298 -0
- urban_imageable-0.1.0/src/imageable/_images/camera/__init__.py +0 -0
- urban_imageable-0.1.0/src/imageable/_images/camera/building_observation.py +191 -0
- urban_imageable-0.1.0/src/imageable/_images/camera/camera_adjustment.py +219 -0
- urban_imageable-0.1.0/src/imageable/_images/camera/camera_parameters.py +71 -0
- urban_imageable-0.1.0/src/imageable/_images/download.py +255 -0
- urban_imageable-0.1.0/src/imageable/_images/image.py +58 -0
- urban_imageable-0.1.0/src/imageable/_models/__init__.py +0 -0
- urban_imageable-0.1.0/src/imageable/_models/base.py +90 -0
- urban_imageable-0.1.0/src/imageable/_models/distance_to_streets_wrapper.py +272 -0
- urban_imageable-0.1.0/src/imageable/_models/height_correction_model.py +166 -0
- urban_imageable-0.1.0/src/imageable/_models/height_estimation/__init__.py +5 -0
- urban_imageable-0.1.0/src/imageable/_models/height_estimation/height_calculator.py +632 -0
- urban_imageable-0.1.0/src/imageable/_models/height_estimation/processors/__init__.py +0 -0
- urban_imageable-0.1.0/src/imageable/_models/height_estimation/processors/line_classifier.py +148 -0
- urban_imageable-0.1.0/src/imageable/_models/height_estimation/processors/line_refiner.py +129 -0
- urban_imageable-0.1.0/src/imageable/_models/height_estimation/single_view_metrology.py +92 -0
- urban_imageable-0.1.0/src/imageable/_models/height_estimation/vanishing_point.py +89 -0
- urban_imageable-0.1.0/src/imageable/_models/huggingface/__init__.py +0 -0
- urban_imageable-0.1.0/src/imageable/_models/huggingface/base.py +92 -0
- urban_imageable-0.1.0/src/imageable/_models/huggingface/floor_sky_ratio_calculator.py +189 -0
- urban_imageable-0.1.0/src/imageable/_models/huggingface/segformer_segmentation.py +282 -0
- urban_imageable-0.1.0/src/imageable/_models/lcnn/__init__.py +8 -0
- urban_imageable-0.1.0/src/imageable/_models/lcnn/core/__init__.py +9 -0
- urban_imageable-0.1.0/src/imageable/_models/lcnn/core/box.py +1092 -0
- urban_imageable-0.1.0/src/imageable/_models/lcnn/core/config.py +7 -0
- urban_imageable-0.1.0/src/imageable/_models/lcnn/core/datasets.py +89 -0
- urban_imageable-0.1.0/src/imageable/_models/lcnn/core/metric.py +190 -0
- urban_imageable-0.1.0/src/imageable/_models/lcnn/core/postprocess.py +77 -0
- urban_imageable-0.1.0/src/imageable/_models/lcnn/core/trainer.py +314 -0
- urban_imageable-0.1.0/src/imageable/_models/lcnn/core/utils.py +95 -0
- urban_imageable-0.1.0/src/imageable/_models/lcnn/lcnn_wrapper.py +401 -0
- urban_imageable-0.1.0/src/imageable/_models/lcnn/models/__init__.py +5 -0
- urban_imageable-0.1.0/src/imageable/_models/lcnn/models/hourglass_pose.py +201 -0
- urban_imageable-0.1.0/src/imageable/_models/lcnn/models/line_vectorizer.py +260 -0
- urban_imageable-0.1.0/src/imageable/_models/lcnn/models/multitask_learner.py +104 -0
- urban_imageable-0.1.0/src/imageable/_models/line_param_selection_model.py +80 -0
- urban_imageable-0.1.0/src/imageable/_models/materials/backbones/segformer_mit_encoder.py +583 -0
- urban_imageable-0.1.0/src/imageable/_models/materials/decoders/samixer_head.py +588 -0
- urban_imageable-0.1.0/src/imageable/_models/materials/dpt_gate.py +391 -0
- urban_imageable-0.1.0/src/imageable/_models/materials/label_palette.py +82 -0
- urban_imageable-0.1.0/src/imageable/_models/materials/material_seg_model.py +1609 -0
- urban_imageable-0.1.0/src/imageable/_models/materials/norms/sync_batchnorm.py +392 -0
- urban_imageable-0.1.0/src/imageable/_models/materials/postprocess.py +139 -0
- urban_imageable-0.1.0/src/imageable/_models/materials/preprocess.py +197 -0
- urban_imageable-0.1.0/src/imageable/_models/materials/result_types.py +58 -0
- urban_imageable-0.1.0/src/imageable/_models/materials/rmsnet.py +78 -0
- urban_imageable-0.1.0/src/imageable/_models/materials/rmsnet_wrapper.py +139 -0
- urban_imageable-0.1.0/src/imageable/_models/vpts/vpts_wrapper.py +112 -0
- urban_imageable-0.1.0/src/imageable/_utils/__init__.py +0 -0
- urban_imageable-0.1.0/src/imageable/_utils/geometry/__init__.py +0 -0
- urban_imageable-0.1.0/src/imageable/_utils/geometry/line_geometry.py +178 -0
- urban_imageable-0.1.0/src/imageable/_utils/geometry/point_geometry.py +63 -0
- urban_imageable-0.1.0/src/imageable/_utils/geometry/polygons.py +267 -0
- urban_imageable-0.1.0/src/imageable/_utils/geometry/ray_geometry.py +195 -0
- urban_imageable-0.1.0/src/imageable/_utils/geometry/surface_geometry.py +10 -0
- urban_imageable-0.1.0/src/imageable/_utils/geometry/vector_geometry.py +1 -0
- urban_imageable-0.1.0/src/imageable/_utils/masks/__init__.py +0 -0
- urban_imageable-0.1.0/src/imageable/_utils/masks/mask_operations.py +121 -0
- urban_imageable-0.1.0/src/imageable/_utils/masks/mask_visualizer.py +104 -0
- urban_imageable-0.1.0/src/imageable/_version.py +3 -0
- urban_imageable-0.1.0/src/imageable/assets/ade20k_palette.json +455 -0
- urban_imageable-0.1.0/src/imageable/assets/wireframe.yaml +71 -0
- urban_imageable-0.1.0/src/imageable/core/__init__.py +36 -0
- urban_imageable-0.1.0/src/imageable/core/building_data.py +625 -0
- urban_imageable-0.1.0/src/imageable/core/dataset.py +59 -0
- urban_imageable-0.1.0/src/imageable/core/image.py +213 -0
- urban_imageable-0.1.0/src/imageable/visualization/__init__.py +0 -0
- urban_imageable-0.1.0/src/imageable/visualization/footprints.py +322 -0
- urban_imageable-0.1.0/src/imageable/visualization/wheel_visualization.py +353 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
cache
|
|
3
|
+
__pycache__/
|
|
4
|
+
*.py[cod]
|
|
5
|
+
*$py.class
|
|
6
|
+
*.so
|
|
7
|
+
.Python
|
|
8
|
+
build/
|
|
9
|
+
develop-eggs/
|
|
10
|
+
dist/
|
|
11
|
+
downloads/
|
|
12
|
+
eggs/
|
|
13
|
+
.eggs/
|
|
14
|
+
lib/
|
|
15
|
+
lib64/
|
|
16
|
+
parts/
|
|
17
|
+
sdist/
|
|
18
|
+
var/
|
|
19
|
+
wheels/
|
|
20
|
+
*.egg-info/
|
|
21
|
+
.installed.cfg
|
|
22
|
+
*.egg
|
|
23
|
+
MANIFEST
|
|
24
|
+
|
|
25
|
+
# Testing
|
|
26
|
+
.pytest_cache/
|
|
27
|
+
.coverage
|
|
28
|
+
htmlcov/
|
|
29
|
+
.tox/
|
|
30
|
+
.nox/
|
|
31
|
+
coverage.xml
|
|
32
|
+
|
|
33
|
+
# Type checking
|
|
34
|
+
.mypy_cache/
|
|
35
|
+
.dmypy.json
|
|
36
|
+
dmypy.json
|
|
37
|
+
|
|
38
|
+
# Environments
|
|
39
|
+
.env
|
|
40
|
+
.venv
|
|
41
|
+
env/
|
|
42
|
+
venv/
|
|
43
|
+
ENV/
|
|
44
|
+
|
|
45
|
+
# IDEs
|
|
46
|
+
.vscode/
|
|
47
|
+
.idea/
|
|
48
|
+
*.swp
|
|
49
|
+
*.swo
|
|
50
|
+
|
|
51
|
+
# OS
|
|
52
|
+
.DS_Store
|
|
53
|
+
Thumbs.db
|
|
54
|
+
.coverage.*
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
BSD 2-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025, Scalable Design Participation Lab
|
|
4
|
+
|
|
5
|
+
Redistribution and use in source and binary forms, with or without
|
|
6
|
+
modification, are permitted provided that the following conditions are met:
|
|
7
|
+
|
|
8
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
9
|
+
list of conditions and the following disclaimer.
|
|
10
|
+
|
|
11
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
12
|
+
this list of conditions and the following disclaimer in the documentation
|
|
13
|
+
and/or other materials provided with the distribution.
|
|
14
|
+
|
|
15
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
16
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
17
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
18
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
19
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
20
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
21
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
22
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
23
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
24
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: urban-imageable
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Computer vision library for extracting 43+ building properties from street view images and footprints
|
|
5
|
+
Project-URL: Homepage, https://github.com/scalable-design-participation-lab/imageable
|
|
6
|
+
Project-URL: Bug Tracker, https://github.com/scalable-design-participation-lab/imageable/issues
|
|
7
|
+
Project-URL: Documentation, https://github.com/scalable-design-participation-lab/imageable#readme
|
|
8
|
+
Author-email: Khoi Ngo <ngo.kho@northeastern.edu>, Uriel Legaria <fill@gmail.com>
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: building-analysis,computer-vision,geospatial,gis,height-estimation,segmentation,street-view,urban-planning
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering :: GIS
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering :: Image Processing
|
|
22
|
+
Requires-Python: >=3.13
|
|
23
|
+
Requires-Dist: cmcrameri>=1.9
|
|
24
|
+
Requires-Dist: geopandas>=1.1.1
|
|
25
|
+
Requires-Dist: libpysal>=4.13.0
|
|
26
|
+
Requires-Dist: lu-vp-detect>=1.0.4
|
|
27
|
+
Requires-Dist: matplotlib>=3.5.0
|
|
28
|
+
Requires-Dist: numpy>=2.2.6
|
|
29
|
+
Requires-Dist: osmnx>=2.0.6
|
|
30
|
+
Requires-Dist: pandas>=2.2.3
|
|
31
|
+
Requires-Dist: pillow>=11.2.1
|
|
32
|
+
Requires-Dist: pydeck>=0.9.1
|
|
33
|
+
Requires-Dist: scikit-image>=0.19.0
|
|
34
|
+
Requires-Dist: scikit-learn>=1.7.2
|
|
35
|
+
Requires-Dist: seaborn>=0.13.2
|
|
36
|
+
Requires-Dist: shapely>=2.1.1
|
|
37
|
+
Requires-Dist: spopt>=0.7.0
|
|
38
|
+
Requires-Dist: tensorboardx>=2.6.4
|
|
39
|
+
Requires-Dist: timm>=1.0.21
|
|
40
|
+
Requires-Dist: torch>=2.7.1
|
|
41
|
+
Requires-Dist: transformers>=4.52.4
|
|
42
|
+
Requires-Dist: ultralytics>=8.4.0
|
|
43
|
+
Description-Content-Type: text/markdown
|
|
44
|
+
|
|
45
|
+
# imageable
|
|
46
|
+
|
|
47
|
+
[](https://github.com/scalable-design-participation-lab/imageable/actions/workflows/ci.yml)
|
|
48
|
+
[](https://badge.fury.io/py/imageable)
|
|
49
|
+
[](https://www.python.org/downloads/)
|
|
50
|
+
[](https://opensource.org/licenses/MIT)
|
|
51
|
+
|
|
52
|
+
An open-source Python library for extracting **43+ building properties** from street view images and building footprints. Designed for urban planners, architects, climate resilience researchers, and GIS professionals.
|
|
53
|
+
|
|
54
|
+

|
|
55
|
+
|
|
56
|
+
## Features
|
|
57
|
+
|
|
58
|
+
- **Height Estimation**: Estimate building heights from single street-level images using vanishing point detection and semantic segmentation
|
|
59
|
+
- **Material Analysis**: Segment and quantify façade materials (brick, glass, concrete, etc.)
|
|
60
|
+
- **Footprint Properties**: Extract 21 geometric, engineered, and contextual features from building polygons
|
|
61
|
+
- **Image Features**: Analyze color, shape, and façade characteristics from street view images
|
|
62
|
+
- **Batch Processing**: Process entire neighborhoods via GeoDataFrames or GeoJSON files
|
|
63
|
+
|
|
64
|
+
## Installation
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
pip install urban-imageable
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### For Development
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
# Clone the repository
|
|
74
|
+
git clone https://github.com/scalable-design-participation-lab/imageable.git
|
|
75
|
+
cd imageable
|
|
76
|
+
|
|
77
|
+
# Install with uv (recommended)
|
|
78
|
+
uv sync --group dev
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Quick Start
|
|
82
|
+
|
|
83
|
+
### Single Building Analysis
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
import imageable
|
|
87
|
+
from shapely.geometry import Polygon
|
|
88
|
+
|
|
89
|
+
# Define building footprint (WGS84 coordinates)
|
|
90
|
+
footprint = Polygon([
|
|
91
|
+
(-71.0589, 42.3601),
|
|
92
|
+
(-71.0585, 42.3601),
|
|
93
|
+
(-71.0585, 42.3605),
|
|
94
|
+
(-71.0589, 42.3605),
|
|
95
|
+
])
|
|
96
|
+
|
|
97
|
+
# Get street view image
|
|
98
|
+
image, metadata = imageable.get_image(api_key, footprint)
|
|
99
|
+
|
|
100
|
+
# Extract all 43+ properties
|
|
101
|
+
props = imageable.get_dataset(api_key, footprint)
|
|
102
|
+
print(f"Estimated height: {props.building_height}m")
|
|
103
|
+
print(f"Projected area: {props.projected_area}m²")
|
|
104
|
+
print(f"Shape complexity: {props.complexity}")
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Batch Processing from GeoDataFrame
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
import geopandas as gpd
|
|
111
|
+
import imageable
|
|
112
|
+
|
|
113
|
+
# Load building footprints
|
|
114
|
+
gdf = gpd.read_file("buildings.geojson")
|
|
115
|
+
|
|
116
|
+
# Extract properties for all buildings
|
|
117
|
+
result = imageable.get_building_data_from_gdf(
|
|
118
|
+
gdf,
|
|
119
|
+
api_key,
|
|
120
|
+
id_column="building_id",
|
|
121
|
+
neighbor_radius=100.0, # meters
|
|
122
|
+
verbose=True,
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
# Result is a GeoDataFrame with 43+ new columns
|
|
126
|
+
print(result.columns)
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### From GeoJSON File
|
|
130
|
+
|
|
131
|
+
```python
|
|
132
|
+
import imageable
|
|
133
|
+
|
|
134
|
+
# Process directly from GeoJSON
|
|
135
|
+
result = imageable.get_building_data_from_geojson(
|
|
136
|
+
"buildings.geojson",
|
|
137
|
+
api_key,
|
|
138
|
+
output_format="gdf", # or "geojson", "dict"
|
|
139
|
+
)
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### With Pre-downloaded Images
|
|
143
|
+
|
|
144
|
+
```python
|
|
145
|
+
import imageable
|
|
146
|
+
|
|
147
|
+
# Process from local footprints and images
|
|
148
|
+
result = imageable.get_building_data_from_file(
|
|
149
|
+
"footprints.geojson",
|
|
150
|
+
"images/", # Directory containing images named by building ID
|
|
151
|
+
id_column="building_id",
|
|
152
|
+
)
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Extracted Properties
|
|
156
|
+
|
|
157
|
+
### Footprint Properties (21 features)
|
|
158
|
+
|
|
159
|
+
**Geometric (6):**
|
|
160
|
+
- `unprojected_area`, `projected_area`: Area in original and projected CRS
|
|
161
|
+
- `longitude_difference`, `latitude_difference`: Bounding box dimensions
|
|
162
|
+
- `n_vertices`: Number of polygon vertices
|
|
163
|
+
- `shape_length`: Perimeter length
|
|
164
|
+
|
|
165
|
+
**Engineered (5):**
|
|
166
|
+
- `complexity`: Perimeter/area ratio
|
|
167
|
+
- `inverse_average_segment_length`: Edge length metric
|
|
168
|
+
- `vertices_per_area`: Vertex density
|
|
169
|
+
- `average_complexity_per_segment`: Segment-level complexity
|
|
170
|
+
- `isoperimetric_quotient`: Circularity measure (4πA/P²)
|
|
171
|
+
|
|
172
|
+
**Contextual (10):**
|
|
173
|
+
- `neighbor_count`: Number of buildings within radius
|
|
174
|
+
- `mean_distance_to_neighbors`: Average centroid distance
|
|
175
|
+
- `nearest_neighbor_distance`: Distance to closest building
|
|
176
|
+
- `n_size_mean/std/min/max/cv`: Neighbor area statistics
|
|
177
|
+
- `expected_nearest_neighbor_distance`: Random distribution expectation
|
|
178
|
+
- `nni`: Nearest neighbor index
|
|
179
|
+
|
|
180
|
+
### Height Estimation
|
|
181
|
+
|
|
182
|
+
- `building_height`: Estimated height in meters using CV pipeline (vanishing points + segmentation)
|
|
183
|
+
|
|
184
|
+
### Image Features (16 features)
|
|
185
|
+
|
|
186
|
+
**Color (5):**
|
|
187
|
+
- `average_red/green/blue_channel_value`: RGB means
|
|
188
|
+
- `average_brightness`: HSV brightness percentage
|
|
189
|
+
- `average_vividness`: HSV saturation percentage
|
|
190
|
+
|
|
191
|
+
**Shape (5):**
|
|
192
|
+
- `mask_area`: Segmented building pixels
|
|
193
|
+
- `mask_length`: Boundary perimeter
|
|
194
|
+
- `mask_complexity`: Length/area ratio
|
|
195
|
+
- `number_of_edges`, `number_of_vertices`: Polygon complexity
|
|
196
|
+
|
|
197
|
+
**Façade (6):**
|
|
198
|
+
- `average_window_x/y`: Window centroid location
|
|
199
|
+
- `average_door_x/y`: Door centroid location
|
|
200
|
+
- `number_of_windows`, `number_of_doors`: Element counts
|
|
201
|
+
|
|
202
|
+
### Material Percentages
|
|
203
|
+
|
|
204
|
+
- `material_percentages`: Dictionary of façade material coverage (brick, glass, concrete, metal, etc.)
|
|
205
|
+
|
|
206
|
+
## API Reference
|
|
207
|
+
|
|
208
|
+
### Main Functions
|
|
209
|
+
|
|
210
|
+
```python
|
|
211
|
+
# Batch processing
|
|
212
|
+
imageable.get_building_data_from_gdf(gdf, api_key, ...)
|
|
213
|
+
imageable.get_building_data_from_geojson(source, api_key, ...)
|
|
214
|
+
imageable.get_building_data_from_file(footprints, images_dir, ...)
|
|
215
|
+
|
|
216
|
+
# Single building
|
|
217
|
+
imageable.get_dataset(api_key, footprint, ...)
|
|
218
|
+
imageable.get_image(api_key, footprint, ...)
|
|
219
|
+
|
|
220
|
+
# Data class
|
|
221
|
+
imageable.BuildingProperties
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### BuildingProperties
|
|
225
|
+
|
|
226
|
+
```python
|
|
227
|
+
from imageable import BuildingProperties
|
|
228
|
+
|
|
229
|
+
# Create and populate
|
|
230
|
+
props = BuildingProperties(building_id="b001")
|
|
231
|
+
props.update_footprint_features(footprint_dict)
|
|
232
|
+
props.update_height(25.5)
|
|
233
|
+
props.update_material_percentages({"brick": 60.0, "glass": 40.0})
|
|
234
|
+
|
|
235
|
+
# Export
|
|
236
|
+
props.to_dict() # Dictionary
|
|
237
|
+
props.to_json("output.json") # JSON file
|
|
238
|
+
props.get_feature_vector() # NumPy array for ML
|
|
239
|
+
|
|
240
|
+
# Import
|
|
241
|
+
props = BuildingProperties.from_dict(data)
|
|
242
|
+
props = BuildingProperties.from_json("input.json")
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
## Requirements
|
|
246
|
+
|
|
247
|
+
- Python 3.13+
|
|
248
|
+
- Google Street View API key (for image acquisition and height estimation)
|
|
249
|
+
- See `pyproject.toml` for full dependency list
|
|
250
|
+
|
|
251
|
+
## Development
|
|
252
|
+
|
|
253
|
+
```bash
|
|
254
|
+
# Run tests
|
|
255
|
+
uv run pytest
|
|
256
|
+
|
|
257
|
+
# Run tests with coverage
|
|
258
|
+
uv run pytest --cov-report=html
|
|
259
|
+
open htmlcov/index.html
|
|
260
|
+
|
|
261
|
+
# Lint and format
|
|
262
|
+
uv run pre-commit run --all-files
|
|
263
|
+
|
|
264
|
+
# Build package
|
|
265
|
+
uv build
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
## Project Structure
|
|
269
|
+
|
|
270
|
+
```
|
|
271
|
+
imageable/
|
|
272
|
+
├── src/imageable/
|
|
273
|
+
│ ├── core/ # Public API
|
|
274
|
+
│ │ ├── building_data.py # Batch processing
|
|
275
|
+
│ │ ├── dataset.py # Single building extraction
|
|
276
|
+
│ │ └── image.py # Image acquisition
|
|
277
|
+
│ ├── _extraction/ # Property extraction
|
|
278
|
+
│ │ ├── building.py # BuildingProperties dataclass
|
|
279
|
+
│ │ ├── extract.py # Main orchestrator
|
|
280
|
+
│ │ ├── footprint.py # Footprint features
|
|
281
|
+
│ │ └── image.py # Image features
|
|
282
|
+
│ ├── _features/ # Feature pipelines
|
|
283
|
+
│ │ ├── height/ # Height estimation
|
|
284
|
+
│ │ └── materials/ # Material segmentation
|
|
285
|
+
│ ├── _images/ # Image acquisition
|
|
286
|
+
│ │ ├── camera/ # Camera parameters
|
|
287
|
+
│ │ └── download.py # Street View API
|
|
288
|
+
│ └── _models/ # ML models
|
|
289
|
+
│ ├── huggingface/ # SegFormer segmentation
|
|
290
|
+
│ ├── lcnn/ # Line detection
|
|
291
|
+
│ └── vpts/ # Vanishing points
|
|
292
|
+
└── tests/ # Test suite
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
## Citation
|
|
296
|
+
|
|
297
|
+
If you use imageable in your research, please cite:
|
|
298
|
+
|
|
299
|
+
```bibtex
|
|
300
|
+
@software{imageable2025,
|
|
301
|
+
author = {Ngo, Khoi and Legaria, Uriel and Sandoval Olascoaga, Carlos},
|
|
302
|
+
title = {imageable: Computer Vision Library for Urban Building Analysis},
|
|
303
|
+
year = {2025},
|
|
304
|
+
url = {https://github.com/scalable-design-participation-lab/imageable}
|
|
305
|
+
}
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
## License
|
|
309
|
+
|
|
310
|
+
MIT License - see [LICENSE](LICENSE) for details.
|
|
311
|
+
|
|
312
|
+
## Authors
|
|
313
|
+
|
|
314
|
+
- Khoi Ngo ([Khoi Ngo](https://github.com/billnqk)) - ngo.kho@northeastern.edu
|
|
315
|
+
- Uriel Legaria
|
|
316
|
+
- Carlos Sandoval Olascoaga
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
Developed at the [Scalable Design Participation Lab](https://github.com/scalable-design-participation-lab), Northeastern University.
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
# imageable
|
|
2
|
+
|
|
3
|
+
[](https://github.com/scalable-design-participation-lab/imageable/actions/workflows/ci.yml)
|
|
4
|
+
[](https://badge.fury.io/py/imageable)
|
|
5
|
+
[](https://www.python.org/downloads/)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
An open-source Python library for extracting **43+ building properties** from street view images and building footprints. Designed for urban planners, architects, climate resilience researchers, and GIS professionals.
|
|
9
|
+
|
|
10
|
+

|
|
11
|
+
|
|
12
|
+
## Features
|
|
13
|
+
|
|
14
|
+
- **Height Estimation**: Estimate building heights from single street-level images using vanishing point detection and semantic segmentation
|
|
15
|
+
- **Material Analysis**: Segment and quantify façade materials (brick, glass, concrete, etc.)
|
|
16
|
+
- **Footprint Properties**: Extract 21 geometric, engineered, and contextual features from building polygons
|
|
17
|
+
- **Image Features**: Analyze color, shape, and façade characteristics from street view images
|
|
18
|
+
- **Batch Processing**: Process entire neighborhoods via GeoDataFrames or GeoJSON files
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pip install urban-imageable
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### For Development
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
# Clone the repository
|
|
30
|
+
git clone https://github.com/scalable-design-participation-lab/imageable.git
|
|
31
|
+
cd imageable
|
|
32
|
+
|
|
33
|
+
# Install with uv (recommended)
|
|
34
|
+
uv sync --group dev
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Quick Start
|
|
38
|
+
|
|
39
|
+
### Single Building Analysis
|
|
40
|
+
|
|
41
|
+
```python
|
|
42
|
+
import imageable
|
|
43
|
+
from shapely.geometry import Polygon
|
|
44
|
+
|
|
45
|
+
# Define building footprint (WGS84 coordinates)
|
|
46
|
+
footprint = Polygon([
|
|
47
|
+
(-71.0589, 42.3601),
|
|
48
|
+
(-71.0585, 42.3601),
|
|
49
|
+
(-71.0585, 42.3605),
|
|
50
|
+
(-71.0589, 42.3605),
|
|
51
|
+
])
|
|
52
|
+
|
|
53
|
+
# Get street view image
|
|
54
|
+
image, metadata = imageable.get_image(api_key, footprint)
|
|
55
|
+
|
|
56
|
+
# Extract all 43+ properties
|
|
57
|
+
props = imageable.get_dataset(api_key, footprint)
|
|
58
|
+
print(f"Estimated height: {props.building_height}m")
|
|
59
|
+
print(f"Projected area: {props.projected_area}m²")
|
|
60
|
+
print(f"Shape complexity: {props.complexity}")
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Batch Processing from GeoDataFrame
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
import geopandas as gpd
|
|
67
|
+
import imageable
|
|
68
|
+
|
|
69
|
+
# Load building footprints
|
|
70
|
+
gdf = gpd.read_file("buildings.geojson")
|
|
71
|
+
|
|
72
|
+
# Extract properties for all buildings
|
|
73
|
+
result = imageable.get_building_data_from_gdf(
|
|
74
|
+
gdf,
|
|
75
|
+
api_key,
|
|
76
|
+
id_column="building_id",
|
|
77
|
+
neighbor_radius=100.0, # meters
|
|
78
|
+
verbose=True,
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
# Result is a GeoDataFrame with 43+ new columns
|
|
82
|
+
print(result.columns)
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### From GeoJSON File
|
|
86
|
+
|
|
87
|
+
```python
|
|
88
|
+
import imageable
|
|
89
|
+
|
|
90
|
+
# Process directly from GeoJSON
|
|
91
|
+
result = imageable.get_building_data_from_geojson(
|
|
92
|
+
"buildings.geojson",
|
|
93
|
+
api_key,
|
|
94
|
+
output_format="gdf", # or "geojson", "dict"
|
|
95
|
+
)
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### With Pre-downloaded Images
|
|
99
|
+
|
|
100
|
+
```python
|
|
101
|
+
import imageable
|
|
102
|
+
|
|
103
|
+
# Process from local footprints and images
|
|
104
|
+
result = imageable.get_building_data_from_file(
|
|
105
|
+
"footprints.geojson",
|
|
106
|
+
"images/", # Directory containing images named by building ID
|
|
107
|
+
id_column="building_id",
|
|
108
|
+
)
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Extracted Properties
|
|
112
|
+
|
|
113
|
+
### Footprint Properties (21 features)
|
|
114
|
+
|
|
115
|
+
**Geometric (6):**
|
|
116
|
+
- `unprojected_area`, `projected_area`: Area in original and projected CRS
|
|
117
|
+
- `longitude_difference`, `latitude_difference`: Bounding box dimensions
|
|
118
|
+
- `n_vertices`: Number of polygon vertices
|
|
119
|
+
- `shape_length`: Perimeter length
|
|
120
|
+
|
|
121
|
+
**Engineered (5):**
|
|
122
|
+
- `complexity`: Perimeter/area ratio
|
|
123
|
+
- `inverse_average_segment_length`: Edge length metric
|
|
124
|
+
- `vertices_per_area`: Vertex density
|
|
125
|
+
- `average_complexity_per_segment`: Segment-level complexity
|
|
126
|
+
- `isoperimetric_quotient`: Circularity measure (4πA/P²)
|
|
127
|
+
|
|
128
|
+
**Contextual (10):**
|
|
129
|
+
- `neighbor_count`: Number of buildings within radius
|
|
130
|
+
- `mean_distance_to_neighbors`: Average centroid distance
|
|
131
|
+
- `nearest_neighbor_distance`: Distance to closest building
|
|
132
|
+
- `n_size_mean/std/min/max/cv`: Neighbor area statistics
|
|
133
|
+
- `expected_nearest_neighbor_distance`: Random distribution expectation
|
|
134
|
+
- `nni`: Nearest neighbor index
|
|
135
|
+
|
|
136
|
+
### Height Estimation
|
|
137
|
+
|
|
138
|
+
- `building_height`: Estimated height in meters using CV pipeline (vanishing points + segmentation)
|
|
139
|
+
|
|
140
|
+
### Image Features (16 features)
|
|
141
|
+
|
|
142
|
+
**Color (5):**
|
|
143
|
+
- `average_red/green/blue_channel_value`: RGB means
|
|
144
|
+
- `average_brightness`: HSV brightness percentage
|
|
145
|
+
- `average_vividness`: HSV saturation percentage
|
|
146
|
+
|
|
147
|
+
**Shape (5):**
|
|
148
|
+
- `mask_area`: Segmented building pixels
|
|
149
|
+
- `mask_length`: Boundary perimeter
|
|
150
|
+
- `mask_complexity`: Length/area ratio
|
|
151
|
+
- `number_of_edges`, `number_of_vertices`: Polygon complexity
|
|
152
|
+
|
|
153
|
+
**Façade (6):**
|
|
154
|
+
- `average_window_x/y`: Window centroid location
|
|
155
|
+
- `average_door_x/y`: Door centroid location
|
|
156
|
+
- `number_of_windows`, `number_of_doors`: Element counts
|
|
157
|
+
|
|
158
|
+
### Material Percentages
|
|
159
|
+
|
|
160
|
+
- `material_percentages`: Dictionary of façade material coverage (brick, glass, concrete, metal, etc.)
|
|
161
|
+
|
|
162
|
+
## API Reference
|
|
163
|
+
|
|
164
|
+
### Main Functions
|
|
165
|
+
|
|
166
|
+
```python
|
|
167
|
+
# Batch processing
|
|
168
|
+
imageable.get_building_data_from_gdf(gdf, api_key, ...)
|
|
169
|
+
imageable.get_building_data_from_geojson(source, api_key, ...)
|
|
170
|
+
imageable.get_building_data_from_file(footprints, images_dir, ...)
|
|
171
|
+
|
|
172
|
+
# Single building
|
|
173
|
+
imageable.get_dataset(api_key, footprint, ...)
|
|
174
|
+
imageable.get_image(api_key, footprint, ...)
|
|
175
|
+
|
|
176
|
+
# Data class
|
|
177
|
+
imageable.BuildingProperties
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### BuildingProperties
|
|
181
|
+
|
|
182
|
+
```python
|
|
183
|
+
from imageable import BuildingProperties
|
|
184
|
+
|
|
185
|
+
# Create and populate
|
|
186
|
+
props = BuildingProperties(building_id="b001")
|
|
187
|
+
props.update_footprint_features(footprint_dict)
|
|
188
|
+
props.update_height(25.5)
|
|
189
|
+
props.update_material_percentages({"brick": 60.0, "glass": 40.0})
|
|
190
|
+
|
|
191
|
+
# Export
|
|
192
|
+
props.to_dict() # Dictionary
|
|
193
|
+
props.to_json("output.json") # JSON file
|
|
194
|
+
props.get_feature_vector() # NumPy array for ML
|
|
195
|
+
|
|
196
|
+
# Import
|
|
197
|
+
props = BuildingProperties.from_dict(data)
|
|
198
|
+
props = BuildingProperties.from_json("input.json")
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Requirements
|
|
202
|
+
|
|
203
|
+
- Python 3.13+
|
|
204
|
+
- Google Street View API key (for image acquisition and height estimation)
|
|
205
|
+
- See `pyproject.toml` for full dependency list
|
|
206
|
+
|
|
207
|
+
## Development
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
# Run tests
|
|
211
|
+
uv run pytest
|
|
212
|
+
|
|
213
|
+
# Run tests with coverage
|
|
214
|
+
uv run pytest --cov-report=html
|
|
215
|
+
open htmlcov/index.html
|
|
216
|
+
|
|
217
|
+
# Lint and format
|
|
218
|
+
uv run pre-commit run --all-files
|
|
219
|
+
|
|
220
|
+
# Build package
|
|
221
|
+
uv build
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## Project Structure
|
|
225
|
+
|
|
226
|
+
```
|
|
227
|
+
imageable/
|
|
228
|
+
├── src/imageable/
|
|
229
|
+
│ ├── core/ # Public API
|
|
230
|
+
│ │ ├── building_data.py # Batch processing
|
|
231
|
+
│ │ ├── dataset.py # Single building extraction
|
|
232
|
+
│ │ └── image.py # Image acquisition
|
|
233
|
+
│ ├── _extraction/ # Property extraction
|
|
234
|
+
│ │ ├── building.py # BuildingProperties dataclass
|
|
235
|
+
│ │ ├── extract.py # Main orchestrator
|
|
236
|
+
│ │ ├── footprint.py # Footprint features
|
|
237
|
+
│ │ └── image.py # Image features
|
|
238
|
+
│ ├── _features/ # Feature pipelines
|
|
239
|
+
│ │ ├── height/ # Height estimation
|
|
240
|
+
│ │ └── materials/ # Material segmentation
|
|
241
|
+
│ ├── _images/ # Image acquisition
|
|
242
|
+
│ │ ├── camera/ # Camera parameters
|
|
243
|
+
│ │ └── download.py # Street View API
|
|
244
|
+
│ └── _models/ # ML models
|
|
245
|
+
│ ├── huggingface/ # SegFormer segmentation
|
|
246
|
+
│ ├── lcnn/ # Line detection
|
|
247
|
+
│ └── vpts/ # Vanishing points
|
|
248
|
+
└── tests/ # Test suite
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
## Citation
|
|
252
|
+
|
|
253
|
+
If you use imageable in your research, please cite:
|
|
254
|
+
|
|
255
|
+
```bibtex
|
|
256
|
+
@software{imageable2025,
|
|
257
|
+
author = {Ngo, Khoi and Legaria, Uriel and Sandoval Olascoaga, Carlos},
|
|
258
|
+
title = {imageable: Computer Vision Library for Urban Building Analysis},
|
|
259
|
+
year = {2025},
|
|
260
|
+
url = {https://github.com/scalable-design-participation-lab/imageable}
|
|
261
|
+
}
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
## License
|
|
265
|
+
|
|
266
|
+
MIT License - see [LICENSE](LICENSE) for details.
|
|
267
|
+
|
|
268
|
+
## Authors
|
|
269
|
+
|
|
270
|
+
- Khoi Ngo ([Khoi Ngo](https://github.com/billnqk)) - ngo.kho@northeastern.edu
|
|
271
|
+
- Uriel Legaria
|
|
272
|
+
- Carlos Sandoval Olascoaga
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
Developed at the [Scalable Design Participation Lab](https://github.com/scalable-design-participation-lab), Northeastern University.
|