geoahsi 1.2.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.
- geoahsi-1.2.0/LICENSE +21 -0
- geoahsi-1.2.0/MANIFEST.in +4 -0
- geoahsi-1.2.0/PKG-INFO +256 -0
- geoahsi-1.2.0/README.md +196 -0
- geoahsi-1.2.0/geoahsi/__init__.py +15 -0
- geoahsi-1.2.0/geoahsi/classifier.py +864 -0
- geoahsi-1.2.0/geoahsi/data/color_table.json +387 -0
- geoahsi-1.2.0/geoahsi/data/rf.json +5860 -0
- geoahsi-1.2.0/geoahsi/data/splib06b +0 -0
- geoahsi-1.2.0/geoahsi/emit_reader.py +65 -0
- geoahsi-1.2.0/geoahsi/mica_engine.py +358 -0
- geoahsi-1.2.0/geoahsi/renderer.py +799 -0
- geoahsi-1.2.0/geoahsi.egg-info/PKG-INFO +256 -0
- geoahsi-1.2.0/geoahsi.egg-info/SOURCES.txt +19 -0
- geoahsi-1.2.0/geoahsi.egg-info/dependency_links.txt +1 -0
- geoahsi-1.2.0/geoahsi.egg-info/entry_points.txt +2 -0
- geoahsi-1.2.0/geoahsi.egg-info/requires.txt +17 -0
- geoahsi-1.2.0/geoahsi.egg-info/top_level.txt +1 -0
- geoahsi-1.2.0/pyproject.toml +56 -0
- geoahsi-1.2.0/requirements.txt +10 -0
- geoahsi-1.2.0/setup.cfg +4 -0
geoahsi-1.2.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 GeoAHSI Team
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
geoahsi-1.2.0/PKG-INFO
ADDED
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: geoahsi
|
|
3
|
+
Version: 1.2.0
|
|
4
|
+
Summary: GeoAHSI — EMIT 高光谱矿物识别引擎(USGS MICA 算法)
|
|
5
|
+
Author: GeoAHSI Team
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2026 GeoAHSI Team
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
|
|
28
|
+
Keywords: GeoAHSI,MICA,EMIT,hyperspectral,mineral,USGS,remote sensing
|
|
29
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
30
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
31
|
+
Classifier: Intended Audience :: Science/Research
|
|
32
|
+
Classifier: Topic :: Scientific/Engineering :: GIS
|
|
33
|
+
Classifier: Programming Language :: Python :: 3
|
|
34
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
35
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
36
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
37
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
38
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
39
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
40
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
41
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
42
|
+
Requires-Python: >=3.8
|
|
43
|
+
Description-Content-Type: text/markdown
|
|
44
|
+
License-File: LICENSE
|
|
45
|
+
Requires-Dist: numpy>=1.20
|
|
46
|
+
Requires-Dist: pandas>=1.3
|
|
47
|
+
Requires-Dist: netCDF4>=1.6
|
|
48
|
+
Requires-Dist: pyproj>=3.0
|
|
49
|
+
Requires-Dist: pyresample>=1.25
|
|
50
|
+
Requires-Dist: threadpoolctl>=3.0
|
|
51
|
+
Provides-Extra: viz
|
|
52
|
+
Requires-Dist: matplotlib>=3.5; extra == "viz"
|
|
53
|
+
Provides-Extra: dev
|
|
54
|
+
Requires-Dist: pytest; extra == "dev"
|
|
55
|
+
Requires-Dist: matplotlib>=3.5; extra == "dev"
|
|
56
|
+
Requires-Dist: build; extra == "dev"
|
|
57
|
+
Requires-Dist: twine; extra == "dev"
|
|
58
|
+
Provides-Extra: gdal
|
|
59
|
+
Dynamic: license-file
|
|
60
|
+
|
|
61
|
+
# GeoAHSI 核心库
|
|
62
|
+
|
|
63
|
+
GeoAHSI — EMIT 高光谱矿物识别引擎(基于 USGS MICA 算法):EMIT 高光谱影像 → 逐像元矿物判别 → GeoTIFF 输出。
|
|
64
|
+
|
|
65
|
+
## 安装
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# 从 PyPI 安装(推荐)
|
|
69
|
+
pip install geoahsi # 基础:分类 + GeoTIFF 输出
|
|
70
|
+
pip install 'geoahsi[viz]' # + PDF 可视化(classify_spectrum / match_reference)
|
|
71
|
+
conda install -c conda-forge gdal # GDAL(write_tiff 需要,conda 安装)
|
|
72
|
+
|
|
73
|
+
# 从源码安装
|
|
74
|
+
cd D:/123
|
|
75
|
+
pip install . # 普通安装
|
|
76
|
+
pip install -e . # 开发模式(改代码即时生效)
|
|
77
|
+
pip install -e ".[dev]" # 含开发依赖(pytest/matplotlib/build/twine)
|
|
78
|
+
|
|
79
|
+
# 构建分发包
|
|
80
|
+
pip install build
|
|
81
|
+
python -m build
|
|
82
|
+
# → dist/geoahsi-1.2.0-py3-none-any.whl (可直接 pip install)
|
|
83
|
+
# → dist/geoahsi-1.2.0.tar.gz
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
安装后可直接用 `geoahsi` 命令行工具:
|
|
87
|
+
```bash
|
|
88
|
+
geoahsi -i D:/test/EMIT_xxx.nc -o D:/test/output
|
|
89
|
+
geoahsi -i D:/test/EMIT_xxx.nc -o D:/test/output --raw # 额外输出 mus_center + fd
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## 结构
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
123/
|
|
96
|
+
├── geoahsi/ # 核心库(零 GUI 依赖)
|
|
97
|
+
│ ├── emit_reader.py # 影像读取(EmitReader)
|
|
98
|
+
│ ├── classifier.py # 光谱分析核心(MicaClassifier + 全部算法 + 并行 worker)
|
|
99
|
+
│ ├── renderer.py # 结果封装(ResultRenderer + HSI + GeoTIFF + DEFAULT_MUS_TABLE)
|
|
100
|
+
│ ├── mica_engine.py # MicaEngine facade(组合三者,保留公共 API)
|
|
101
|
+
│ ├── __init__.py
|
|
102
|
+
│ └── data/ # 全部内置资源
|
|
103
|
+
│ ├── splib06b # USGS 光谱库(21MB)
|
|
104
|
+
│ ├── rf.json # 矿物规则库(77 矿物 + 混合配方 + 波长映射)
|
|
105
|
+
│ └── color_table.json # 矿物 RGB 颜色表(77 矿物)
|
|
106
|
+
├── requirements.txt
|
|
107
|
+
├── test_lib.py # 端到端自测
|
|
108
|
+
└── visualize_*.py # top-10 特征 PDF 生成
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**全部资源内置** `geoahsi/data/`:splib06b / rf.json / color_table.json / DEFAULT_MUS_TABLE 常量。
|
|
112
|
+
`MicaEngine()` 和 `MicaClassifier.from_paths()` / `ResultRenderer.from_paths()` **零参数**即可构造,库仅依赖输入 EMIT NetCDF 影像。
|
|
113
|
+
|
|
114
|
+
三组件通过 `ClassificationResult` 数据契约衔接:
|
|
115
|
+
```
|
|
116
|
+
EmitReader.load ─► (spectrum, lon, lat, w, bp) # 坏波段已剔除
|
|
117
|
+
│
|
|
118
|
+
▼
|
|
119
|
+
MicaClassifier.classify(spectrum, w, bp) ─► ClassificationResult(fit, depth, num, mus_center, ...)
|
|
120
|
+
│
|
|
121
|
+
▼
|
|
122
|
+
ResultRenderer.render ─► (orth_rgb, color_enhanced, mus_image)
|
|
123
|
+
│
|
|
124
|
+
▼
|
|
125
|
+
ResultRenderer.write_tiff ─► 3 × GeoTIFF
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## 外部资源
|
|
129
|
+
|
|
130
|
+
| 资源 | 用途 | 状态 |
|
|
131
|
+
|---|---|---|
|
|
132
|
+
| USGS splib06b | 光谱库 | **已内置** `geoahsi/data/splib06b` |
|
|
133
|
+
| rf.json | 矿物规则库 | **已内置** `geoahsi/data/rf.json` |
|
|
134
|
+
| 矿物颜色表 | 矿物→RGB | **已内置** `geoahsi/data/color_table.json` |
|
|
135
|
+
| 白云母色表 | mus_image 着色 | **已内置** `DEFAULT_MUS_TABLE` 常量 |
|
|
136
|
+
| EMIT L2A NetCDF | 输入影像 | 外部(必传) |
|
|
137
|
+
|
|
138
|
+
## 安装
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
pip install -r requirements.txt
|
|
142
|
+
# GDAL 通过 conda:
|
|
143
|
+
conda install -c conda-forge gdal
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## 用法
|
|
147
|
+
|
|
148
|
+
### 方式一:facade(最简,自动加载资源)
|
|
149
|
+
|
|
150
|
+
```python
|
|
151
|
+
from geoahsi import MicaEngine
|
|
152
|
+
|
|
153
|
+
engine = MicaEngine() # 零参数,全部资源内置
|
|
154
|
+
|
|
155
|
+
spectrum, lon, lat, w, bp = engine.load_emit("./EMIT_xxx.nc") # 坏波段已剔除
|
|
156
|
+
orth_rgb, color_enhanced, mus_image = engine.spectrum_analysis(
|
|
157
|
+
spectrum, w, bp, n_workers=8
|
|
158
|
+
)
|
|
159
|
+
engine.write_tiff("./EMIT_xxx", lon, lat, orth_rgb, color_enhanced, mus_image)
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### 方式二:直接用三组件(核心库,自包含 from_paths)
|
|
163
|
+
|
|
164
|
+
```python
|
|
165
|
+
from geoahsi.emit_reader import EmitReader
|
|
166
|
+
from geoahsi.classifier import MicaClassifier
|
|
167
|
+
from geoahsi.renderer import ResultRenderer
|
|
168
|
+
|
|
169
|
+
# 三组件各自零参数构造(全内置)
|
|
170
|
+
clf = MicaClassifier.from_paths()
|
|
171
|
+
rnd = ResultRenderer.from_paths()
|
|
172
|
+
|
|
173
|
+
# 读影像
|
|
174
|
+
spectrum, lon, lat, w, bp = EmitReader.load("./EMIT_xxx.nc")
|
|
175
|
+
|
|
176
|
+
# 分类 → ClassificationResult(无颜色/图像)
|
|
177
|
+
result = clf.classify(spectrum, w, bp, n_workers=8)
|
|
178
|
+
|
|
179
|
+
# 渲染 + 输出
|
|
180
|
+
orth, color, mus = rnd.render(result)
|
|
181
|
+
rnd.write_tiff("./EMIT_xxx", lon, lat, orth, color, mus)
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### 单像元 Top-N 识别
|
|
185
|
+
|
|
186
|
+
```python
|
|
187
|
+
engine = MicaEngine() # 零参数,全内置
|
|
188
|
+
spectrum, lon, lat, w, bp = engine.load_emit("./EMIT_xxx.nc")
|
|
189
|
+
pixel = spectrum[row, col, :] # 已是有效波段,无需再切片
|
|
190
|
+
top = engine.classify_spectrum(pixel, w, bp, top_n=10)
|
|
191
|
+
# [{"name": "muscovite_medAl", "fit": 0.98, "fd": 0.13}, ...]
|
|
192
|
+
# 传 pdf_path=... 可额外输出 Top-N 特征连续统去除多页 PDF
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### 单像元 vs 单条参考光谱匹配
|
|
196
|
+
|
|
197
|
+
按 rf.json 中指定矿物的专家规则匹配单条像元光谱,可选生成匹配过程可视化 PDF
|
|
198
|
+
(逐特征连续统去除 + 每道关卡 PASS/REJECT 判定,仿 pixel_features.pdf)。
|
|
199
|
+
|
|
200
|
+
```python
|
|
201
|
+
engine = MicaEngine()
|
|
202
|
+
spectrum, lon, lat, w, bp = engine.load_emit("./EMIT_xxx.nc")
|
|
203
|
+
pixel = spectrum[row, col, :]
|
|
204
|
+
|
|
205
|
+
r = engine.match_reference(
|
|
206
|
+
pixel, w, bp,
|
|
207
|
+
mineral_key="calcite.8+montmorilloniteNa.2_mix_intimate", # rf.json 中的 key
|
|
208
|
+
pdf_path="./match.pdf", # 可选;不传则只返回结果不出图
|
|
209
|
+
)
|
|
210
|
+
# {"name": "...", "fit": 0.9457, "fd": 0.0659, "accept": True}
|
|
211
|
+
# fit 为 NaN 表示被某道专家规则关卡否决(accept=False)
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
`mineral_key` 可用 `list(engine.rf.keys())` 查看全部 77 个候选(纯端元如 `calcite` /
|
|
215
|
+
`muscovite_medAl`,混合如 `calcite.8+montmorilloniteNa.2_mix_intimate`)。
|
|
216
|
+
|
|
217
|
+
## 主要 API
|
|
218
|
+
|
|
219
|
+
| 组件 | 方法 | 说明 |
|
|
220
|
+
|---|---|---|
|
|
221
|
+
| `EmitReader.load(path)` | 静态 | 读 EMIT NetCDF + 坏波段剔除 → `spectrum, lon, lat, w, bp` |
|
|
222
|
+
| `MicaClassifier.from_paths(rf, splib)` | 类方法 | 加载资源构造分类器 |
|
|
223
|
+
| `MicaClassifier.classify(spectrum, w, bp, ...)` | | 整景分类 → `ClassificationResult` |
|
|
224
|
+
| `MicaClassifier.classify_spectrum(spectrum, w, bp, top_n)` | | 单光谱 Top-N |
|
|
225
|
+
| `MicaClassifier.get_resample(w, bp)` | | 参考光谱重采样 |
|
|
226
|
+
| `ResultRenderer.from_paths(txt, tif)` | 类方法 | 加载颜色表构造渲染器 |
|
|
227
|
+
| `ResultRenderer.render(result)` | | `ClassificationResult` → 3 张 RGB 图 |
|
|
228
|
+
| `ResultRenderer.write_tiff(path, lon, lat, ...)` | 静态 | 写 3 张 GeoTIFF |
|
|
229
|
+
| `ResultRenderer.plot_features_pdf(...)` | 静态 | Top-N 特征连续统去除多页 PDF |
|
|
230
|
+
| `ResultRenderer.plot_rule_match_pdf(...)` | 静态 | 单矿物匹配过程可视化 PDF |
|
|
231
|
+
| `MicaEngine(...)` | facade | 组合三者的便捷入口 |
|
|
232
|
+
| `MicaEngine.load_emit(path)` | 静态 | 委托 `EmitReader.load` |
|
|
233
|
+
| `MicaEngine.spectrum_analysis(spectrum, w, bp, ...)` | | 整景分类 + 渲染 |
|
|
234
|
+
| `MicaEngine.classify_spectrum(spectrum, w, bp, top_n, pdf_path)` | | 单像元 Top-N(+可选 PDF) |
|
|
235
|
+
| `MicaEngine.match_reference(spectrum, w, bp, mineral_key, pdf_path)` | | 单像元 vs 单条参考光谱匹配(+可选过程 PDF) |
|
|
236
|
+
| `MicaEngine.write_tiff(path, lon, lat, ...)` | | 写 3 张 GeoTIFF |
|
|
237
|
+
|
|
238
|
+
## 参数
|
|
239
|
+
|
|
240
|
+
- `n_workers`:矿物级并行进程数。`<=1` 串行;`None` 默认 `min(cpu_count, 8)`。
|
|
241
|
+
- `spectrum_analysis` 支持 `progress_callback` / `log_callback` / `cancel_flag` 回调。
|
|
242
|
+
- `match_reference` 的 `mineral_key` 必须为 `rf.json` 中已有的 key,否则抛 `KeyError`(提示可用示例)。
|
|
243
|
+
- `classify_spectrum` / `match_reference` 的 `pdf_path` 需 `matplotlib`(`pip install 'geoahsi[viz]'`)。
|
|
244
|
+
|
|
245
|
+
## 性能
|
|
246
|
+
|
|
247
|
+
实测(1280×1242 EMIT 影像,24 核机器):
|
|
248
|
+
- 串行 ~175s,并行 nw=8 ~80s。
|
|
249
|
+
- 输出与 `mica_app.py` 原版逐比特一致(闭式 2×2 最小二乘 + det==0 奇异守卫)。
|
|
250
|
+
|
|
251
|
+
## 算法
|
|
252
|
+
|
|
253
|
+
- 连续统去除 + 闭式 2×2 最小二乘拟合(R² + 吸收深度)。
|
|
254
|
+
- 三层过滤:连续统约束 → 诊断特征 + 非特征排除 → 加权约束。
|
|
255
|
+
- 可选深度比值约束(`rf.json` 的 `max_depth_ratio_feat1_over_feat0`,6 个白云母纯端元)。
|
|
256
|
+
- 白云母 2.2μm 吸收中心抛物线拟合 → 10 档着色。
|
geoahsi-1.2.0/README.md
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
# GeoAHSI 核心库
|
|
2
|
+
|
|
3
|
+
GeoAHSI — EMIT 高光谱矿物识别引擎(基于 USGS MICA 算法):EMIT 高光谱影像 → 逐像元矿物判别 → GeoTIFF 输出。
|
|
4
|
+
|
|
5
|
+
## 安装
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# 从 PyPI 安装(推荐)
|
|
9
|
+
pip install geoahsi # 基础:分类 + GeoTIFF 输出
|
|
10
|
+
pip install 'geoahsi[viz]' # + PDF 可视化(classify_spectrum / match_reference)
|
|
11
|
+
conda install -c conda-forge gdal # GDAL(write_tiff 需要,conda 安装)
|
|
12
|
+
|
|
13
|
+
# 从源码安装
|
|
14
|
+
cd D:/123
|
|
15
|
+
pip install . # 普通安装
|
|
16
|
+
pip install -e . # 开发模式(改代码即时生效)
|
|
17
|
+
pip install -e ".[dev]" # 含开发依赖(pytest/matplotlib/build/twine)
|
|
18
|
+
|
|
19
|
+
# 构建分发包
|
|
20
|
+
pip install build
|
|
21
|
+
python -m build
|
|
22
|
+
# → dist/geoahsi-1.2.0-py3-none-any.whl (可直接 pip install)
|
|
23
|
+
# → dist/geoahsi-1.2.0.tar.gz
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
安装后可直接用 `geoahsi` 命令行工具:
|
|
27
|
+
```bash
|
|
28
|
+
geoahsi -i D:/test/EMIT_xxx.nc -o D:/test/output
|
|
29
|
+
geoahsi -i D:/test/EMIT_xxx.nc -o D:/test/output --raw # 额外输出 mus_center + fd
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## 结构
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
123/
|
|
36
|
+
├── geoahsi/ # 核心库(零 GUI 依赖)
|
|
37
|
+
│ ├── emit_reader.py # 影像读取(EmitReader)
|
|
38
|
+
│ ├── classifier.py # 光谱分析核心(MicaClassifier + 全部算法 + 并行 worker)
|
|
39
|
+
│ ├── renderer.py # 结果封装(ResultRenderer + HSI + GeoTIFF + DEFAULT_MUS_TABLE)
|
|
40
|
+
│ ├── mica_engine.py # MicaEngine facade(组合三者,保留公共 API)
|
|
41
|
+
│ ├── __init__.py
|
|
42
|
+
│ └── data/ # 全部内置资源
|
|
43
|
+
│ ├── splib06b # USGS 光谱库(21MB)
|
|
44
|
+
│ ├── rf.json # 矿物规则库(77 矿物 + 混合配方 + 波长映射)
|
|
45
|
+
│ └── color_table.json # 矿物 RGB 颜色表(77 矿物)
|
|
46
|
+
├── requirements.txt
|
|
47
|
+
├── test_lib.py # 端到端自测
|
|
48
|
+
└── visualize_*.py # top-10 特征 PDF 生成
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
**全部资源内置** `geoahsi/data/`:splib06b / rf.json / color_table.json / DEFAULT_MUS_TABLE 常量。
|
|
52
|
+
`MicaEngine()` 和 `MicaClassifier.from_paths()` / `ResultRenderer.from_paths()` **零参数**即可构造,库仅依赖输入 EMIT NetCDF 影像。
|
|
53
|
+
|
|
54
|
+
三组件通过 `ClassificationResult` 数据契约衔接:
|
|
55
|
+
```
|
|
56
|
+
EmitReader.load ─► (spectrum, lon, lat, w, bp) # 坏波段已剔除
|
|
57
|
+
│
|
|
58
|
+
▼
|
|
59
|
+
MicaClassifier.classify(spectrum, w, bp) ─► ClassificationResult(fit, depth, num, mus_center, ...)
|
|
60
|
+
│
|
|
61
|
+
▼
|
|
62
|
+
ResultRenderer.render ─► (orth_rgb, color_enhanced, mus_image)
|
|
63
|
+
│
|
|
64
|
+
▼
|
|
65
|
+
ResultRenderer.write_tiff ─► 3 × GeoTIFF
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## 外部资源
|
|
69
|
+
|
|
70
|
+
| 资源 | 用途 | 状态 |
|
|
71
|
+
|---|---|---|
|
|
72
|
+
| USGS splib06b | 光谱库 | **已内置** `geoahsi/data/splib06b` |
|
|
73
|
+
| rf.json | 矿物规则库 | **已内置** `geoahsi/data/rf.json` |
|
|
74
|
+
| 矿物颜色表 | 矿物→RGB | **已内置** `geoahsi/data/color_table.json` |
|
|
75
|
+
| 白云母色表 | mus_image 着色 | **已内置** `DEFAULT_MUS_TABLE` 常量 |
|
|
76
|
+
| EMIT L2A NetCDF | 输入影像 | 外部(必传) |
|
|
77
|
+
|
|
78
|
+
## 安装
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
pip install -r requirements.txt
|
|
82
|
+
# GDAL 通过 conda:
|
|
83
|
+
conda install -c conda-forge gdal
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## 用法
|
|
87
|
+
|
|
88
|
+
### 方式一:facade(最简,自动加载资源)
|
|
89
|
+
|
|
90
|
+
```python
|
|
91
|
+
from geoahsi import MicaEngine
|
|
92
|
+
|
|
93
|
+
engine = MicaEngine() # 零参数,全部资源内置
|
|
94
|
+
|
|
95
|
+
spectrum, lon, lat, w, bp = engine.load_emit("./EMIT_xxx.nc") # 坏波段已剔除
|
|
96
|
+
orth_rgb, color_enhanced, mus_image = engine.spectrum_analysis(
|
|
97
|
+
spectrum, w, bp, n_workers=8
|
|
98
|
+
)
|
|
99
|
+
engine.write_tiff("./EMIT_xxx", lon, lat, orth_rgb, color_enhanced, mus_image)
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### 方式二:直接用三组件(核心库,自包含 from_paths)
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
from geoahsi.emit_reader import EmitReader
|
|
106
|
+
from geoahsi.classifier import MicaClassifier
|
|
107
|
+
from geoahsi.renderer import ResultRenderer
|
|
108
|
+
|
|
109
|
+
# 三组件各自零参数构造(全内置)
|
|
110
|
+
clf = MicaClassifier.from_paths()
|
|
111
|
+
rnd = ResultRenderer.from_paths()
|
|
112
|
+
|
|
113
|
+
# 读影像
|
|
114
|
+
spectrum, lon, lat, w, bp = EmitReader.load("./EMIT_xxx.nc")
|
|
115
|
+
|
|
116
|
+
# 分类 → ClassificationResult(无颜色/图像)
|
|
117
|
+
result = clf.classify(spectrum, w, bp, n_workers=8)
|
|
118
|
+
|
|
119
|
+
# 渲染 + 输出
|
|
120
|
+
orth, color, mus = rnd.render(result)
|
|
121
|
+
rnd.write_tiff("./EMIT_xxx", lon, lat, orth, color, mus)
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### 单像元 Top-N 识别
|
|
125
|
+
|
|
126
|
+
```python
|
|
127
|
+
engine = MicaEngine() # 零参数,全内置
|
|
128
|
+
spectrum, lon, lat, w, bp = engine.load_emit("./EMIT_xxx.nc")
|
|
129
|
+
pixel = spectrum[row, col, :] # 已是有效波段,无需再切片
|
|
130
|
+
top = engine.classify_spectrum(pixel, w, bp, top_n=10)
|
|
131
|
+
# [{"name": "muscovite_medAl", "fit": 0.98, "fd": 0.13}, ...]
|
|
132
|
+
# 传 pdf_path=... 可额外输出 Top-N 特征连续统去除多页 PDF
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### 单像元 vs 单条参考光谱匹配
|
|
136
|
+
|
|
137
|
+
按 rf.json 中指定矿物的专家规则匹配单条像元光谱,可选生成匹配过程可视化 PDF
|
|
138
|
+
(逐特征连续统去除 + 每道关卡 PASS/REJECT 判定,仿 pixel_features.pdf)。
|
|
139
|
+
|
|
140
|
+
```python
|
|
141
|
+
engine = MicaEngine()
|
|
142
|
+
spectrum, lon, lat, w, bp = engine.load_emit("./EMIT_xxx.nc")
|
|
143
|
+
pixel = spectrum[row, col, :]
|
|
144
|
+
|
|
145
|
+
r = engine.match_reference(
|
|
146
|
+
pixel, w, bp,
|
|
147
|
+
mineral_key="calcite.8+montmorilloniteNa.2_mix_intimate", # rf.json 中的 key
|
|
148
|
+
pdf_path="./match.pdf", # 可选;不传则只返回结果不出图
|
|
149
|
+
)
|
|
150
|
+
# {"name": "...", "fit": 0.9457, "fd": 0.0659, "accept": True}
|
|
151
|
+
# fit 为 NaN 表示被某道专家规则关卡否决(accept=False)
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
`mineral_key` 可用 `list(engine.rf.keys())` 查看全部 77 个候选(纯端元如 `calcite` /
|
|
155
|
+
`muscovite_medAl`,混合如 `calcite.8+montmorilloniteNa.2_mix_intimate`)。
|
|
156
|
+
|
|
157
|
+
## 主要 API
|
|
158
|
+
|
|
159
|
+
| 组件 | 方法 | 说明 |
|
|
160
|
+
|---|---|---|
|
|
161
|
+
| `EmitReader.load(path)` | 静态 | 读 EMIT NetCDF + 坏波段剔除 → `spectrum, lon, lat, w, bp` |
|
|
162
|
+
| `MicaClassifier.from_paths(rf, splib)` | 类方法 | 加载资源构造分类器 |
|
|
163
|
+
| `MicaClassifier.classify(spectrum, w, bp, ...)` | | 整景分类 → `ClassificationResult` |
|
|
164
|
+
| `MicaClassifier.classify_spectrum(spectrum, w, bp, top_n)` | | 单光谱 Top-N |
|
|
165
|
+
| `MicaClassifier.get_resample(w, bp)` | | 参考光谱重采样 |
|
|
166
|
+
| `ResultRenderer.from_paths(txt, tif)` | 类方法 | 加载颜色表构造渲染器 |
|
|
167
|
+
| `ResultRenderer.render(result)` | | `ClassificationResult` → 3 张 RGB 图 |
|
|
168
|
+
| `ResultRenderer.write_tiff(path, lon, lat, ...)` | 静态 | 写 3 张 GeoTIFF |
|
|
169
|
+
| `ResultRenderer.plot_features_pdf(...)` | 静态 | Top-N 特征连续统去除多页 PDF |
|
|
170
|
+
| `ResultRenderer.plot_rule_match_pdf(...)` | 静态 | 单矿物匹配过程可视化 PDF |
|
|
171
|
+
| `MicaEngine(...)` | facade | 组合三者的便捷入口 |
|
|
172
|
+
| `MicaEngine.load_emit(path)` | 静态 | 委托 `EmitReader.load` |
|
|
173
|
+
| `MicaEngine.spectrum_analysis(spectrum, w, bp, ...)` | | 整景分类 + 渲染 |
|
|
174
|
+
| `MicaEngine.classify_spectrum(spectrum, w, bp, top_n, pdf_path)` | | 单像元 Top-N(+可选 PDF) |
|
|
175
|
+
| `MicaEngine.match_reference(spectrum, w, bp, mineral_key, pdf_path)` | | 单像元 vs 单条参考光谱匹配(+可选过程 PDF) |
|
|
176
|
+
| `MicaEngine.write_tiff(path, lon, lat, ...)` | | 写 3 张 GeoTIFF |
|
|
177
|
+
|
|
178
|
+
## 参数
|
|
179
|
+
|
|
180
|
+
- `n_workers`:矿物级并行进程数。`<=1` 串行;`None` 默认 `min(cpu_count, 8)`。
|
|
181
|
+
- `spectrum_analysis` 支持 `progress_callback` / `log_callback` / `cancel_flag` 回调。
|
|
182
|
+
- `match_reference` 的 `mineral_key` 必须为 `rf.json` 中已有的 key,否则抛 `KeyError`(提示可用示例)。
|
|
183
|
+
- `classify_spectrum` / `match_reference` 的 `pdf_path` 需 `matplotlib`(`pip install 'geoahsi[viz]'`)。
|
|
184
|
+
|
|
185
|
+
## 性能
|
|
186
|
+
|
|
187
|
+
实测(1280×1242 EMIT 影像,24 核机器):
|
|
188
|
+
- 串行 ~175s,并行 nw=8 ~80s。
|
|
189
|
+
- 输出与 `mica_app.py` 原版逐比特一致(闭式 2×2 最小二乘 + det==0 奇异守卫)。
|
|
190
|
+
|
|
191
|
+
## 算法
|
|
192
|
+
|
|
193
|
+
- 连续统去除 + 闭式 2×2 最小二乘拟合(R² + 吸收深度)。
|
|
194
|
+
- 三层过滤:连续统约束 → 诊断特征 + 非特征排除 → 加权约束。
|
|
195
|
+
- 可选深度比值约束(`rf.json` 的 `max_depth_ratio_feat1_over_feat0`,6 个白云母纯端元)。
|
|
196
|
+
- 白云母 2.2μm 吸收中心抛物线拟合 → 10 档着色。
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"""GeoAHSI — EMIT 高光谱矿物识别引擎(USGS MICA 算法)。
|
|
2
|
+
|
|
3
|
+
公共 API:MicaEngine(facade,零参数构造,全资源内置)。
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from importlib.metadata import PackageNotFoundError, version as _version
|
|
7
|
+
|
|
8
|
+
try:
|
|
9
|
+
__version__ = _version("geoahsi")
|
|
10
|
+
except PackageNotFoundError: # 源码树直接运行(未安装)
|
|
11
|
+
__version__ = "0.0.0+unknown"
|
|
12
|
+
|
|
13
|
+
from .mica_engine import MicaEngine, ProcessResult
|
|
14
|
+
|
|
15
|
+
__all__ = ["MicaEngine", "ProcessResult", "__version__"]
|