update:更新readme
This commit is contained in:
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
311
README.md
311
README.md
@ -1,31 +1,36 @@
|
|||||||
|
|
||||||
# 高光谱塑料分类工具
|
# 高光谱塑料分类工具
|
||||||
|
|
||||||

|

|
||||||
[](https://www.python.org/)
|
[](https://www.python.org/)
|
||||||
|
|
||||||
## 基于高光谱成像和深度学习的微塑料材料分类与识别工具
|
## 基于高光谱成像和深度学习的微塑料材料分类与识别工具
|
||||||
|
|
||||||
### 功能特性
|
### 功能特性
|
||||||
- 支持BIL格式高光谱数据读取和处理
|
- 支持BIL格式高光谱数据读取和处理
|
||||||
- 使用UNet模型进行图像分割和掩膜生成
|
- 使用Cellpose/UNet模型进行图像分割和掩膜生成
|
||||||
- 多种塑料材料的分类识别
|
- 支持9种塑料材料分类识别(ABS、HDPE、LDPE、PA6、PET、PP、PS、PTFE、PVC)
|
||||||
|
- 二次分类支持(HDPE/LDPE精细区分)
|
||||||
- 背景校正和光谱特征提取
|
- 背景校正和光谱特征提取
|
||||||
|
- 自动波长重采样(支持不同波段数的高光谱相机)
|
||||||
|
- 智能滤纸区域检测
|
||||||
- 输出ENVI标准格式分类结果
|
- 输出ENVI标准格式分类结果
|
||||||
|
- 波段选择工具(基于ANOVA F-score和LDA准则)
|
||||||
|
- 滤纸背景样本光谱提取工具
|
||||||
|
|
||||||
### 安装
|
### 安装
|
||||||
|
|
||||||
#### 前置要求
|
#### 前置要求
|
||||||
- Python 3.12
|
- Python 3.12+
|
||||||
- CUDA (可选,用于GPU加速)
|
- CUDA (可选,用于GPU加速)
|
||||||
- 足够的内存处理高光谱数据
|
- 足够的内存处理高光谱数据(建议16GB+)
|
||||||
- 固态硬盘
|
- 固态硬盘(推荐,处理大文件时更高效)
|
||||||
|
|
||||||
#### 安装步骤
|
#### 安装步骤
|
||||||
1. 克隆仓库:
|
1. 克隆仓库:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone
|
git clone <repository_url>
|
||||||
cd hyperspec-plastic-classification
|
cd micro_plastic
|
||||||
```
|
```
|
||||||
|
|
||||||
2. 安装依赖:
|
2. 安装依赖:
|
||||||
@ -36,111 +41,214 @@
|
|||||||
|
|
||||||
### 使用方法
|
### 使用方法
|
||||||
|
|
||||||
#### 基本用法
|
#### 主程序:高光谱塑料分类
|
||||||
|
|
||||||
|
**基本用法**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python main.py --bil_path /path/to/input.bil --output_path /path/to/output --model_path /path/to/model.m
|
python main.py --bil_path /path/to/input.bil --output_path /path/to/output.dat --model_path /path/to/model.m
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 参数说明
|
**参数说明**
|
||||||
|
|
||||||
| 参数 | 必需 | 默认值 | 描述 |
|
| 参数 | 必需 | 默认值 | 描述 |
|
||||||
|-----------------|------|-----------------------------------------------------|--------------------------------|
|
|-----------------|------|-----------------------------------------------------|--------------------------------|
|
||||||
| --bil_path | 是 | 无 | 输入BIL文件路径 |
|
| `--bil_path` | 是 | 无 | 输入BIL文件路径 |
|
||||||
| --output_path | 是 | 无 | 输出目录路径 |
|
| `--output_path` | 是 | 无 | 输出文件路径(.dat格式) |
|
||||||
| --model_path | 是 | 无 | 分类模型路径 |
|
| `--model_path` | 是 | 无 | 主分类模型路径(.m文件) |
|
||||||
| --unet_path | 否 | ./unet_pytorch/logs/best_epoch_weights.pth | UNet模型权重路径 |
|
|
||||||
|
|
||||||
#### 示例
|
**示例**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 使用默认UNet权重
|
# 基础用法
|
||||||
python main.py --bil_path ./data/input.bil --output_path ./results --model_path ./models/svm.m
|
python main.py --bil_path ./data/input.bil --output_path ./results/output.dat --model_path ./models/svm.m
|
||||||
|
|
||||||
# 指定所有参数
|
|
||||||
python main.py --bil_path ./data/input.bil --output_path ./results --model_path ./models/svm.m --unet_path ./custom_unet_weights.pth
|
|
||||||
|
|
||||||
# Windows系统示例
|
# Windows系统示例
|
||||||
python main.py --bil_path "C:\Users\HyperSpec\test\MPData2.bil" --output_path "C:\Users\HyperSpec\test" --model_path ".\classification_model\modelsave\svm.m" --unet_path ".\unet_pytorch\logs\best_epoch_weights.pth"
|
python main.py --bil_path "C:\Data\test.bil" --output_path "C:\Results\output.dat" --model_path ".\models\svm.m"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### 波段选择工具
|
||||||
|
|
||||||
|
基于ANOVA F-score和LDA准则选择最优波段组合,用于假彩色合成:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python chose_bands.py --csv /path/to/spectral_data.csv --top_k 30 --top_triplets 10
|
||||||
|
```
|
||||||
|
|
||||||
|
**参数说明**
|
||||||
|
|
||||||
|
| 参数 | 必需 | 默认值 | 描述 |
|
||||||
|
|-------------------|------|--------|-----------------------------------------------|
|
||||||
|
| `--csv` | 是 | 无 | 输入CSV文件(首列为类别,其余为光谱列) |
|
||||||
|
| `--top_k` | 否 | 30 | 预筛选的最佳单波段数量 |
|
||||||
|
| `--top_triplets` | 否 | 10 | 输出的最佳三波段组合数量 |
|
||||||
|
| `--map_order` | 否 | auto | RGB映射顺序:auto或wavelength_bgr |
|
||||||
|
|
||||||
|
#### 滤纸背景样本提取工具
|
||||||
|
|
||||||
|
从滤纸区域提取背景样本光谱(用于构建背景训练数据集):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python fliter_sample_spectral.py
|
||||||
|
```
|
||||||
|
|
||||||
|
该脚本需要修改内部路径配置:
|
||||||
|
- `bil_path_or_folder`: 输入BIL文件或目录路径
|
||||||
|
- `output_csv_path`: 输出CSV文件路径
|
||||||
|
- `num_masks`: 每个图像生成的背景样本数量(默认50)
|
||||||
|
- `rng_seed`: 随机种子,保证可复现性
|
||||||
|
|
||||||
### 项目结构
|
### 项目结构
|
||||||
|
|
||||||
```
|
```
|
||||||
hyperspec-plastic-classification/
|
micro_plastic/
|
||||||
├── main.py # 主程序入口
|
├── main.py # 主程序入口(高光谱分类流程)
|
||||||
|
├── main_batch_nosample.py # 批量处理版本(无样本生成)
|
||||||
|
├── mainv1.py # 主程序历史版本
|
||||||
|
├── maintest.py # 测试版本
|
||||||
|
├── chose_bands.py # 波段选择工具
|
||||||
|
├── fliter_sample_spectral.py # 滤纸背景样本提取工具
|
||||||
├── bil2rgb.py # BIL转RGB模块
|
├── bil2rgb.py # BIL转RGB模块
|
||||||
├── unet_pytorch/ # UNet模型相关
|
├── shape_spectral.py # 光谱与形状特征提取
|
||||||
│ ├── predict_rgb.py
|
├── shape_spectral_background.py # 背景光谱计算
|
||||||
│ └── logs/
|
├── extact_shape.py # 形状特征提取与背景校正
|
||||||
│ └── best_epoch_weights.pth # 预训练UNet权重
|
├── mask.py # 图像分割与掩膜生成(Cellpose)
|
||||||
├── classification_model/ # 分类模型
|
├── onlyspectral_background.py # 纯光谱背景处理
|
||||||
│ └── Parallel/
|
├── only_mask.py # 掩膜处理工具
|
||||||
│ └── predict_plastic.py
|
├── get_glcm.py # GLCM纹理特征提取
|
||||||
├── modelsave/
|
├── outputs2dataframe.py # 结果转换为DataFrame
|
||||||
│ └── svm.m # 预训练分类模型
|
├── 多模型.py # 多模型集成工具
|
||||||
├── shape_spectral.py # 光谱特征提取
|
├── spectral_shape_class.py # 光谱形状分类工具
|
||||||
├── shape_spectral_background.py # 背景校正
|
├── classification_model/ # 分类模型库
|
||||||
|
│ ├── Classification/ # 分类算法
|
||||||
|
│ │ ├── Cls.py # 主要分类接口(SVM/RF/XGB等)
|
||||||
|
│ │ ├── ClassicCls.py # 经典机器学习分类器
|
||||||
|
│ │ ├── ClassicClsHY.py # 经典分类器(HY版本)
|
||||||
|
│ │ ├── DeepCls.py # 深度学习分类器
|
||||||
|
│ │ ├── CNN.py # CNN模型
|
||||||
|
│ │ ├── CNN_SAE.py # CNN+SAE模型
|
||||||
|
│ │ ├── CNN_Transfomer.py # CNN+Transformer模型
|
||||||
|
│ │ ├── CNN_HYper.py # 超参数优化CNN
|
||||||
|
│ │ ├── CNN_deepseek.py # DeepSeek优化CNN
|
||||||
|
│ │ ├── SAE.py # 自编码器
|
||||||
|
│ │ └── *_网格搜索.py # 网格搜索优化版本
|
||||||
|
│ ├── WaveSelect/ # 波段选择算法
|
||||||
|
│ │ ├── Pca.py # 主成分分析
|
||||||
|
│ │ ├── Spa.py # 连续投影算法
|
||||||
|
│ │ ├── Spa_acc.py # 加速SPA
|
||||||
|
│ │ ├── GA.py # 遗传算法
|
||||||
|
│ │ ├── Cars.py # CARS算法
|
||||||
|
│ │ ├── ReliefF.py # ReliefF算法
|
||||||
|
│ │ ├── Uve.py # UVE算法
|
||||||
|
│ │ ├── MRMR.py # 最大相关最小冗余
|
||||||
|
│ │ ├── Lar.py # LARS算法
|
||||||
|
│ │ └── centry.py # 信息熵算法
|
||||||
|
│ ├── Preprocessing/ # 预处理
|
||||||
|
│ │ └── Preprocessing.py # 光谱预处理方法
|
||||||
|
│ ├── DataLoad/ # 数据加载
|
||||||
|
│ │ └── DataLoad.py # 数据加载接口
|
||||||
|
│ ├── Evaluate/ # 评估
|
||||||
|
│ │ └── RgsEvaluate.py # 回归评估指标
|
||||||
|
│ └── Parallel/ # 并行处理
|
||||||
|
│ ├── predict_plastic.py # 塑料分类预测接口
|
||||||
|
│ └── test.py # 测试脚本
|
||||||
|
├── modelsave/ # 预训练模型存储
|
||||||
|
│ └── svm.m # 默认SVM分类模型
|
||||||
├── requirements.txt # 项目依赖
|
├── requirements.txt # 项目依赖
|
||||||
└── README.md # 项目说明
|
└── README.md # 项目说明
|
||||||
```
|
```
|
||||||

|
|
||||||
### 输入输出格式
|
### 输入输出格式
|
||||||
|
|
||||||
#### 输入文件格式
|
#### 输入文件格式
|
||||||
- BIL 格式高光谱数据文件 (.bil)
|
- **BIL格式高光谱数据文件** (`.bil`):Band Interleaved by Line格式
|
||||||
- 对应的 HDR 头文件 (.hdr)
|
- **HDR头文件** (`.hdr`):包含图像尺寸、波段数、波长等信息
|
||||||
|
|
||||||
#### 输出文件格式
|
#### 输出文件格式
|
||||||
- ENVI 分类结果文件 (.dat)
|
- **ENVI分类结果文件** (`.dat`):分类结果图像
|
||||||
- ENVI 头文件 (.hdr)
|
- **ENVI头文件** (`.hdr`):包含类别定义、像素大小等信息
|
||||||
|
|
||||||
|
**输出类别定义**
|
||||||
|
|
||||||
|
| 像素值 | 类别名称 | 说明 |
|
||||||
|
|--------|------------|--------------------|
|
||||||
|
| 0 | background | 背景/滤纸 |
|
||||||
|
| 1 | ABS | 丙烯腈-丁二烯-苯乙烯 |
|
||||||
|
| 2 | HDPE | 高密度聚乙烯 |
|
||||||
|
| 3 | LDPE | 低密度聚乙烯 |
|
||||||
|
| 4 | PA6 | 尼龙6 |
|
||||||
|
| 5 | PET | 聚对苯二甲酸乙二醇酯 |
|
||||||
|
| 6 | PP | 聚丙烯 |
|
||||||
|
| 7 | PS | 聚苯乙烯 |
|
||||||
|
| 8 | PTFE | 聚四氟乙烯 |
|
||||||
|
| 9 | PVC | 聚氯乙烯 |
|
||||||
|
|
||||||
### 处理流程
|
### 处理流程
|
||||||
|
|
||||||
1. 读取BIL格式高光谱数据
|
1. **输入验证**:检查BIL/HDR文件完整性,验证波段数(需≥160波段)
|
||||||
2. 转换为RGB图像
|
2. **HDR补齐**:自动添加波长信息(如缺失)
|
||||||
3. 使用UNet模型生成掩膜
|
3. **RGB生成**:将BIL数据转换为RGB图像(使用波段9, 59, 159)
|
||||||
4. 提取光谱特征
|
4. **图像分割**:使用Cellpose生成微塑料掩膜和滤纸掩膜
|
||||||
5. 应用背景校正
|
5. **特征提取**:提取每个颗粒的光谱特征和形状特征
|
||||||
6. 数据清理和过滤
|
6. **背景校正**:用滤纸背景光谱对样本光谱进行校正
|
||||||
7. 使用分类模型预测材料类型
|
7. **波长重采样**:如需要,重采样到训练相机波长(237通道)
|
||||||
8. 保存ENVI格式分类结果
|
8. **数据清理**:过滤面积<500像素、轮廓点不足的样本
|
||||||
|
9. **主分类**:使用SVM等模型进行9类分类
|
||||||
|
10. **二次分类**:对HDPE/LDPE类别进行精细分类
|
||||||
|
11. **后处理**:识别并修正类别7/8中的阴影误分类
|
||||||
|
12. **轮廓收缩**:对轮廓进行1像素腐蚀,避免相邻粘连
|
||||||
|
13. **结果保存**:输出ENVI格式分类结果
|
||||||
|
|
||||||
### 支持的塑料类型
|
### 分类模型说明
|
||||||
|
|
||||||
工具支持以下塑料材料的分类:
|
#### 支持的分类器类型
|
||||||
|
|
||||||
| 类别编号 | 材料名称 |
|
| 模型类型 | 说明 | 适用场景 |
|
||||||
|----------|----------|
|
|----------|-------------------------|----------------------|
|
||||||
| 1 | ABS |
|
| SVM | 支持向量机 | 小样本、高维特征 |
|
||||||
| 2 | HDPE |
|
| RF | 随机森林 | 通用场景、特征重要性分析 |
|
||||||
| 3 | LDPE |
|
| XGBoost | 极端梯度提升 | 大规模数据、高精度需求 |
|
||||||
| 4 | PA6 |
|
| LightGBM | 轻量梯度提升 | 大规模数据、快速训练 |
|
||||||
| 5 | PET |
|
| CNN | 卷积神经网络 | 深度特征学习 |
|
||||||
| 6 | PP |
|
| SAE+CNN | 堆叠自编码器+CNN | 无监督预训练+微调 |
|
||||||
| 7 | PS |
|
|
||||||
| 8 | PTFE |
|
#### 波段选择算法
|
||||||
| 9 | PVC |
|
|
||||||
|
| 算法 | 说明 |
|
||||||
|
|----------|-----------------------------|
|
||||||
|
| PCA | 主成分分析降维 |
|
||||||
|
| SPA | 连续投影算法 |
|
||||||
|
| CARS | 竞争性自适应重加权采样 |
|
||||||
|
| GA | 遗传算法特征选择 |
|
||||||
|
| ReliefF | 基于实例的特征权重算法 |
|
||||||
|
| UVE | 无信息变量消除法 |
|
||||||
|
| MRMR | 最大相关最小冗余 |
|
||||||
|
|
||||||
### 依赖库
|
### 依赖库
|
||||||
|
|
||||||
主要依赖的 Python 库:
|
**核心依赖**
|
||||||
|
- `numpy` - 数值计算
|
||||||
|
- `pandas` - 数据处理
|
||||||
|
- `opencv-python` - 图像处理
|
||||||
|
- `scikit-learn` - 机器学习
|
||||||
|
- `torch`/`torchvision` - 深度学习框架
|
||||||
|
- `spectral` - 高光谱数据处理
|
||||||
|
- `cellpose` - 细胞/颗粒分割(通过mask.py集成)
|
||||||
|
- `plantcv` - 植物/颗粒计算机视觉
|
||||||
|
|
||||||
- opencv-python
|
**其他重要依赖**
|
||||||
- numpy
|
- `scipy` - 科学计算
|
||||||
- matplotlib
|
- `matplotlib` - 可视化
|
||||||
- pandas
|
- `PyWavelets` - 小波变换
|
||||||
- pywavelets
|
- `joblib` - 模型序列化
|
||||||
- scikit-learn
|
- `tqdm` - 进度条
|
||||||
- torch
|
- `xgboost`/`lightgbm`/`catboost` - 梯度提升库
|
||||||
|
|
||||||
完整依赖请查看 `requirements.txt` 文件。
|
完整依赖列表请查看 `requirements.txt`
|
||||||
|
|
||||||
### 许可证
|
|
||||||
|
|
||||||
本项目采用 Creative Commons 非商业许可证。
|
|
||||||
|
|
||||||
|
### 训练相机波长
|
||||||
|
|
||||||
|
模型训练使用的237波段波长范围(912.36nm - 1706.6nm),系统自动进行波长对齐和重采样。
|
||||||
|
|
||||||
### 常见问题
|
### 常见问题
|
||||||
|
|
||||||
@ -150,22 +258,53 @@ hyperspec-plastic-classification/
|
|||||||
|
|
||||||
2. **处理大型文件时内存不足**
|
2. **处理大型文件时内存不足**
|
||||||
|
|
||||||
考虑减少处理区域或增加系统内存
|
考虑减少处理区域或增加系统内存,建议使用固态硬盘。
|
||||||
|
|
||||||
3. **分类结果不准确**
|
3. **BIL文件波段数不足**
|
||||||
|
|
||||||
检查输入数据质量,确认模型是否适合当前数据类型
|
程序需要至少160个波段(用于RGB生成),且推荐237波段以获得最佳分类效果。
|
||||||
|
|
||||||
|
4. **分类结果不准确**
|
||||||
|
|
||||||
|
- 检查输入数据质量
|
||||||
|
- 确认HDR文件包含正确的波长信息
|
||||||
|
- 验证模型与当前数据类型匹配
|
||||||
|
|
||||||
|
5. **HDR文件缺少波长信息**
|
||||||
|
|
||||||
|
程序会自动检测并追加默认波长信息,但建议提供完整的HDR文件。
|
||||||
|
|
||||||
|
### 开发计划
|
||||||
|
|
||||||
|
- [ ] 支持更多高光谱数据格式(如ENVI、TIFF)
|
||||||
|
- [ ] 添加可视化界面
|
||||||
|
- [ ] 集成更多深度学习模型
|
||||||
|
- [ ] 支持在线学习/增量学习
|
||||||
|
- [ ] 添加更多后处理选项
|
||||||
|
|
||||||
|
### 许可证
|
||||||
|
|
||||||
|
本项目采用 Creative Commons 非商业许可证 (CC BY-NC 4.0)。
|
||||||
|
|
||||||
### 联系方式
|
### 联系方式
|
||||||
|
|
||||||
作者:[北京依锐思]
|
作者:北京依锐思
|
||||||
邮箱:[huilai_zhang@126.com](mailto:your.email@example.com)
|
邮箱:[huilai_zhang@126.com](mailto:huilai_zhang@126.com)
|
||||||
项目地址:[https://github.com/yourusername/hyperspec-plastic-classification](https://github.com/yourusername/hyperspec-plastic-classification)
|
项目地址:[https://github.com/yourusername/micro_plastic](https://github.com/yourusername/micro_plastic)
|
||||||
|
|
||||||
### 更新日志
|
### 更新日志
|
||||||
|
|
||||||
- v1.0.0 (2025-08-26)
|
#### v1.1.0 (2026-04-14)
|
||||||
初始版本发布
|
- 新增波段选择工具 `chose_bands.py`
|
||||||
- 支持BIL格式高光谱数据处理
|
- 新增滤纸背景样本提取工具 `fliter_sample_spectral.py`
|
||||||
- 集成UNet分割和SVM分类
|
- 优化波长重采样逻辑,支持更多高光谱相机
|
||||||
- 输出ENVI格式分类结果
|
- 改进类别7/8的后处理阴影识别算法
|
||||||
|
- 添加轮廓收缩功能,避免相邻颗粒粘连
|
||||||
|
- 更新项目文档和结构说明
|
||||||
|
|
||||||
|
#### v1.0.0 (2025-08-26)
|
||||||
|
- 初始版本发布
|
||||||
|
- 支持BIL格式高光谱数据处理
|
||||||
|
- 集成Cellpose分割和SVM分类
|
||||||
|
- 输出ENVI格式分类结果
|
||||||
|
- 支持9种塑料材料分类
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
from bil2rgb import process_bil_files
|
from bil2rgb import process_bil_files
|
||||||
from shape_spectral import process_images
|
from shape_spectral import process_images
|
||||||
import cv2
|
import cv2
|
||||||
from classification_model.Parallel.predict_plastic import predict_and_save
|
# from classification_model.Parallel.predict_plastic import predict_and_save # 本脚本不分类,可移除
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import os
|
import os
|
||||||
import matplotlib
|
import matplotlib
|
||||||
@ -10,9 +10,51 @@ from shape_spectral_background import process_images_background
|
|||||||
from mask import detect_microplastic_mask_from_array
|
from mask import detect_microplastic_mask_from_array
|
||||||
import plantcv as pcv
|
import plantcv as pcv
|
||||||
|
|
||||||
|
# 直接复用 main.py 中的成熟实现,避免重复逻辑和不一致
|
||||||
|
from main import (
|
||||||
|
TRAIN_WAVELENGTHS,
|
||||||
|
read_wavelengths_from_hdr,
|
||||||
|
resample_spectra_matrix,
|
||||||
|
apply_background_no_resample,
|
||||||
|
change_hdr_file,
|
||||||
|
)
|
||||||
|
|
||||||
matplotlib.use('TkAgg')
|
matplotlib.use('TkAgg')
|
||||||
|
|
||||||
|
|
||||||
|
def apply_background_and_optional_resample_for_samples(df, bg_spectrum, bil_path):
|
||||||
|
# 先做背景校正(自动识别以 wavelength_ 或 band_ 开头的光谱列,且长度不一致时尾部对齐)
|
||||||
|
df = apply_background_no_resample(df, bg_spectrum)
|
||||||
|
|
||||||
|
# 再判断是否需要重采样到训练波长
|
||||||
|
src_waves = read_wavelengths_from_hdr(bil_path)
|
||||||
|
need_resample = (
|
||||||
|
src_waves.size > 0 and (
|
||||||
|
src_waves.size != len(TRAIN_WAVELENGTHS) or
|
||||||
|
not np.allclose(src_waves, TRAIN_WAVELENGTHS, atol=1e-2)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
if not need_resample:
|
||||||
|
return df
|
||||||
|
|
||||||
|
# 识别光谱列并重采样
|
||||||
|
spec_cols = [c for c in df.columns if isinstance(c, str) and (c.startswith('wavelength_') or c.startswith('band_'))]
|
||||||
|
if not spec_cols:
|
||||||
|
raise ValueError("未找到光谱列(以 wavelength_ 或 band_ 开头)")
|
||||||
|
|
||||||
|
X_src = df[spec_cols].to_numpy(dtype=np.float64)
|
||||||
|
X_dst = resample_spectra_matrix(X_src, src_waves, TRAIN_WAVELENGTHS)
|
||||||
|
|
||||||
|
# 用 band_{i} 替换光谱列,保持与 main.py 一致
|
||||||
|
spec_col_names = [f"band_{i+1}" for i in range(len(TRAIN_WAVELENGTHS))]
|
||||||
|
df = pd.concat([
|
||||||
|
df.drop(columns=spec_cols),
|
||||||
|
pd.DataFrame(X_dst, columns=spec_col_names, index=df.index)
|
||||||
|
], axis=1)
|
||||||
|
return df
|
||||||
|
|
||||||
|
|
||||||
def read_hdr_file(bil_path):
|
def read_hdr_file(bil_path):
|
||||||
hdr_path = bil_path.replace('.bil', '.hdr')
|
hdr_path = bil_path.replace('.bil', '.hdr')
|
||||||
with open(hdr_path, 'r') as f:
|
with open(hdr_path, 'r') as f:
|
||||||
@ -199,9 +241,9 @@ def generate_new_mask(filter_mask_original, mask, num_masks=50, bil_path=None):
|
|||||||
return new_mask_array
|
return new_mask_array
|
||||||
|
|
||||||
|
|
||||||
def process_single_bil(bil_path):
|
def process_single_bil(bil_path, num_masks=50, rng_seed=None):
|
||||||
"""
|
"""
|
||||||
处理单个BIL文件
|
处理单个BIL文件,生成滤纸背景样本的光谱特征行,并返回DataFrame
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
print(f"\n{'=' * 60}")
|
print(f"\n{'=' * 60}")
|
||||||
@ -212,45 +254,47 @@ def process_single_bil(bil_path):
|
|||||||
print("Processing BIL file to generate RGB image...")
|
print("Processing BIL file to generate RGB image...")
|
||||||
rgb_img = process_bil_files(bil_path)
|
rgb_img = process_bil_files(bil_path)
|
||||||
|
|
||||||
# 修改hdr
|
# HDR:仅在缺失 wavelength 时补齐;并尽量对齐训练相机波长(与 main.py 一致)
|
||||||
change_hdr_file(bil_path)
|
change_hdr_file(bil_path, TRAIN_WAVELENGTHS)
|
||||||
|
|
||||||
# 生成掩膜,mask为16位的塑料标签掩膜
|
# 生成掩膜:返回塑料掩膜 + 滤纸掩膜
|
||||||
print("Generating mask...")
|
print("Generating mask...")
|
||||||
mask, filter_mask_original = detect_microplastic_mask_from_array(
|
mask, filter_mask_original = detect_microplastic_mask_from_array(
|
||||||
image=rgb_img,
|
image=rgb_img,
|
||||||
filter_method='threshold',
|
filter_method='threshold',
|
||||||
diameter=None,
|
diameter=None,
|
||||||
flow_threshold=0.4,
|
flow_threshold=0.4,
|
||||||
cellprob_threshold=0.0
|
cellprob_threshold=-1,
|
||||||
|
model_path=None,
|
||||||
|
detect_filter=True
|
||||||
)
|
)
|
||||||
|
|
||||||
# 根据滤纸掩膜和微塑料掩膜生成新的掩膜,在滤纸掩膜内塑料掩膜外,随机位置生成大小为35*35大小的掩膜,数量为50个
|
# 生成新的随机背景小块掩膜(在滤纸内且不与塑料重叠)
|
||||||
new_mask_array = generate_new_mask(filter_mask_original, mask)
|
if rng_seed is not None:
|
||||||
|
np.random.seed(int(rng_seed))
|
||||||
|
new_mask_array = generate_new_mask(filter_mask_original, mask, num_masks=num_masks, bil_path=bil_path)
|
||||||
|
|
||||||
# 提取特征
|
# 提取光谱与形状特征(仅限新背景小块)
|
||||||
print("Extracting features from BIL file...")
|
print("Extracting features from BIL file...")
|
||||||
# 清理plantcv的observations,确保只包含当前处理的塑料掩膜数据
|
pcv.observations = {} # 清理plantcv状态
|
||||||
pcv.observations = {}
|
|
||||||
df = process_images(bil_path, new_mask_array)
|
df = process_images(bil_path, new_mask_array)
|
||||||
|
|
||||||
# 背景校正
|
# 背景校正(用整图的滤纸背景光谱作为除数)+ 可选重采样到训练相机波长
|
||||||
print("Applying background correction...")
|
print("Applying background correction (+ optional resample)...")
|
||||||
df_correct = process_images_background(bil_path, mask)
|
bg_spectrum = process_images_background(bil_path, mask)
|
||||||
df.iloc[:, 1:169] = df.iloc[:, 1:169].div(df_correct, axis=1)
|
df = apply_background_and_optional_resample_for_samples(df, bg_spectrum, bil_path)
|
||||||
|
|
||||||
# 数据清理
|
# 数据清理:去NA、轮廓点数不足、面积过小过滤(与 main.py 对齐)
|
||||||
print("Cleaning data...")
|
print("Cleaning data...")
|
||||||
df = df.dropna()
|
df = df.dropna()
|
||||||
df = df[df['contour'].apply(lambda x: len(x) > 1 if isinstance(x, list) else True)]
|
df = df[df['contour'].apply(lambda x: len(x) > 1 if isinstance(x, list) else True)]
|
||||||
df = df[df['area'] >= 400]
|
df = df[df['area'] >= 500]
|
||||||
|
|
||||||
# 添加文件名列(不含扩展名)
|
# 添加文件名列(不含扩展名)
|
||||||
filename = os.path.splitext(os.path.basename(bil_path))[0]
|
filename = os.path.splitext(os.path.basename(bil_path))[0]
|
||||||
df.insert(0, 'filename', filename)
|
df.insert(0, 'filename', filename)
|
||||||
|
|
||||||
print(f"Extracted {len(df)} objects from {os.path.basename(bil_path)}")
|
print(f"Extracted {len(df)} background objects from {os.path.basename(bil_path)}")
|
||||||
|
|
||||||
return df
|
return df
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -261,50 +305,45 @@ def process_single_bil(bil_path):
|
|||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
# 单个文件或文件夹路径
|
# 支持文件或目录;新增可调样本数量与随机种子,便于复现
|
||||||
bil_path_or_folder = r"D:\Data\Traindata-11"
|
bil_path_or_folder = r"D:\Data\Traindata-11"
|
||||||
output_csv_path = r"E:\plastic\plastic\output\滤纸样本光谱\11.csv"
|
output_csv_path = r"E:\plastic\plastic\output\滤纸样本光谱\11.csv"
|
||||||
|
num_masks = 50
|
||||||
|
rng_seed = 42
|
||||||
|
|
||||||
# 确保输出目录存在
|
os.makedirs(os.path.dirname(output_csv_path), exist_ok=True)
|
||||||
output_dir = os.path.dirname(output_csv_path)
|
|
||||||
os.makedirs(output_dir, exist_ok=True)
|
|
||||||
|
|
||||||
# 判断是文件还是文件夹
|
|
||||||
if os.path.isfile(bil_path_or_folder):
|
if os.path.isfile(bil_path_or_folder):
|
||||||
bil_files = [bil_path_or_folder]
|
bil_files = [bil_path_or_folder]
|
||||||
elif os.path.isdir(bil_path_or_folder):
|
elif os.path.isdir(bil_path_or_folder):
|
||||||
# 搜索所有.bil文件
|
|
||||||
bil_files = [os.path.join(bil_path_or_folder, f) for f in os.listdir(bil_path_or_folder) if f.endswith('.bil')]
|
bil_files = [os.path.join(bil_path_or_folder, f) for f in os.listdir(bil_path_or_folder) if f.endswith('.bil')]
|
||||||
print(f"Found {len(bil_files)} BIL files to process")
|
print(f"Found {len(bil_files)} BIL files to process")
|
||||||
else:
|
else:
|
||||||
print(f"Error: {bil_path_or_folder} is not a valid file or directory")
|
print(f"Error: {bil_path_or_folder} is not a valid file or directory")
|
||||||
return
|
return
|
||||||
|
|
||||||
# 初始化CSV文件(写入表头)
|
|
||||||
is_first_row = True
|
is_first_row = True
|
||||||
total_objects = 0
|
total_objects = 0
|
||||||
|
|
||||||
for i, bil_path in enumerate(bil_files, 1):
|
for i, bil_path in enumerate(bil_files, 1):
|
||||||
print(f"\n[{i}/{len(bil_files)}] Processing file...")
|
print(f"\n[{i}/{len(bil_files)}] Processing file...")
|
||||||
df = process_single_bil(bil_path)
|
df = process_single_bil(bil_path, num_masks=num_masks, rng_seed=rng_seed)
|
||||||
|
|
||||||
if df is not None and len(df) > 0:
|
if df is not None and len(df) > 0:
|
||||||
# 边处理边写入CSV
|
|
||||||
df.to_csv(
|
df.to_csv(
|
||||||
output_csv_path,
|
output_csv_path,
|
||||||
mode='a' if not is_first_row else 'w', # 第一行写入模式为'w',后续追加'w'
|
mode='a' if not is_first_row else 'w',
|
||||||
index=False,
|
index=False,
|
||||||
header=is_first_row # 只在第一行写入表头
|
header=is_first_row
|
||||||
)
|
)
|
||||||
total_objects += len(df)
|
total_objects += len(df)
|
||||||
is_first_row = False
|
is_first_row = False
|
||||||
print(f" -> {len(df)} objects appended to CSV file")
|
print(f" -> {len(df)} objects appended to CSV file")
|
||||||
|
|
||||||
# 显示统计信息
|
|
||||||
if total_objects > 0:
|
if total_objects > 0:
|
||||||
print(f"\nSummary:")
|
print(f"\nSummary:")
|
||||||
print(f" Total files processed: {len(bil_files)}")
|
print(f" Total files processed: {len(bil_files)}")
|
||||||
print(f" Total objects detected: {total_objects}")
|
print(f" Total background objects collected: {total_objects}")
|
||||||
print(f" Output file: {output_csv_path}")
|
print(f" Output file: {output_csv_path}")
|
||||||
else:
|
else:
|
||||||
print("\nNo results to save.")
|
print("\nNo results to save.")
|
||||||
|
|||||||
415
项目交接文档.md
Normal file
415
项目交接文档.md
Normal file
@ -0,0 +1,415 @@
|
|||||||
|
# 高光谱塑料分类工具 - 项目交接文档
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 一、项目概述
|
||||||
|
|
||||||
|
### 1.1 项目基本信息
|
||||||
|
| 项目属性 | 内容 |
|
||||||
|
|---------|------|
|
||||||
|
| **项目名称** | 高光谱塑料分类工具 (Hyperspectral Plastic Classification) |
|
||||||
|
| **项目目的** | 基于高光谱成像和深度学习的微塑料材料分类与识别 |
|
||||||
|
| **开发语言** | Python 3.12 |
|
||||||
|
| **当前版本** | v1.0.0 (2025-08-26) |
|
||||||
|
| **许可证** | Creative Commons 非商业许可证 |
|
||||||
|
|
||||||
|
### 1.2 核心功能
|
||||||
|
- 支持BIL格式高光谱数据读取和处理
|
||||||
|
- 使用UNet模型进行图像分割和掩膜生成
|
||||||
|
- 支持9种塑料材料分类识别
|
||||||
|
- 背景校正和光谱特征提取
|
||||||
|
- 输出ENVI标准格式分类结果
|
||||||
|
|
||||||
|
### 1.3 支持的塑料类型
|
||||||
|
|
||||||
|
| 类别编号 | 材料名称 | 英文缩写 |
|
||||||
|
|---------|---------|---------|
|
||||||
|
| 1 | 丙烯腈-丁二烯-苯乙烯共聚物 | ABS |
|
||||||
|
| 2 | 高密度聚乙烯 | HDPE |
|
||||||
|
| 3 | 低密度聚乙烯 | LDPE |
|
||||||
|
| 4 | 尼龙6 | PA6 |
|
||||||
|
| 5 | 聚对苯二甲酸乙二醇酯 | PET |
|
||||||
|
| 6 | 聚丙烯 | PP |
|
||||||
|
| 7 | 聚苯乙烯 | PS |
|
||||||
|
| 8 | 聚四氟乙烯 | PTFE |
|
||||||
|
| 9 | 聚氯乙烯 | PVC |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、项目结构
|
||||||
|
|
||||||
|
```
|
||||||
|
micro_plastic/
|
||||||
|
├── main.py # 主程序入口(核心流程)
|
||||||
|
├── fliter_sample_spectral.py # 滤纸背景样本光谱提取工具
|
||||||
|
├── bil2rgb.py # BIL转RGB模块
|
||||||
|
├── mask.py # 图像分割/掩膜生成
|
||||||
|
├── shape_spectral.py # 光谱特征提取
|
||||||
|
├── shape_spectral_background.py # 背景校正计算
|
||||||
|
├── extact_shape.py # 特征提取工具(含二次分类背景校正)
|
||||||
|
├── chose_bands.py # 波段选择工具
|
||||||
|
├── get_glcm.py # GLCM纹理特征提取
|
||||||
|
├── only_mask.py # 仅掩膜处理
|
||||||
|
├── spectral_shape_class.py # 光谱形状分类
|
||||||
|
├── main_batch_nosample.py # 批量处理(无样本)
|
||||||
|
├── maintest.py / mainv1.py # 测试/旧版本入口
|
||||||
|
├── 多模型.py # 多模型处理脚本
|
||||||
|
├── time.py # 时间相关工具
|
||||||
|
├── outputs2dataframe.py # 输出转换工具
|
||||||
|
├── bil2rgb.py # BIL转RGB工具
|
||||||
|
|
||||||
|
├── classification_model/ # 分类模型模块
|
||||||
|
│ ├── Classification/ # 分类算法
|
||||||
|
│ │ ├── ClassicCls.py # 经典分类器
|
||||||
|
│ │ ├── ClassicClsHY.py # 经典分类器(优化版)
|
||||||
|
│ │ ├── ClassicCls_网格搜索.py # 网格搜索参数优化
|
||||||
|
│ │ ├── Cls.py # 基础分类器
|
||||||
|
│ │ ├── Cls_网格搜索.py # 分类器网格搜索
|
||||||
|
│ │ ├── Cls_超参数.py # 超参数调优
|
||||||
|
│ │ ├── DeepCls.py # 深度学习分类器
|
||||||
|
│ │ ├── CNN.py # CNN模型
|
||||||
|
│ │ ├── CNN_deepseek.py # DeepSeek优化CNN
|
||||||
|
│ │ ├── CNN_HYper.py # 超参数CNN
|
||||||
|
│ │ ├── CNN_SAE.py # CNN+SAE模型
|
||||||
|
│ │ ├── CNN_Transfomer.py # CNN+Transformer
|
||||||
|
│ │ ├── SAE.py # 堆叠自编码器
|
||||||
|
│ │ └── CNN_网格搜索.py # CNN网格搜索
|
||||||
|
│ │
|
||||||
|
│ ├── WaveSelect/ # 波长选择算法
|
||||||
|
│ │ ├── WaveSelcet.py # 主入口
|
||||||
|
│ │ ├── Cars.py # CARS算法
|
||||||
|
│ │ ├── GA.py # 遗传算法
|
||||||
|
│ │ ├── Lar.py # LARS算法
|
||||||
|
│ │ ├── MRMR.py # 最大相关最小冗余
|
||||||
|
│ │ ├── Pca.py # 主成分分析
|
||||||
|
│ │ ├── ReliefF.py # ReliefF算法
|
||||||
|
│ │ ├── Spa.py # SPA算法
|
||||||
|
│ │ ├── Spa_acc.py # SPA精确版
|
||||||
|
│ │ └── Uve.py # UVE算法
|
||||||
|
│ │
|
||||||
|
│ ├── DataLoad/ # 数据加载
|
||||||
|
│ │ └── DataLoad.py # 数据加载器
|
||||||
|
│ │
|
||||||
|
│ ├── Preprocessing/ # 预处理
|
||||||
|
│ │ └── Preprocessing.py # 数据预处理
|
||||||
|
│ │
|
||||||
|
│ ├── Evaluate/ # 模型评估
|
||||||
|
│ │ └── RgsEvaluate.py # 回归评估
|
||||||
|
│ │
|
||||||
|
│ └── Parallel/ # 并行处理/预测
|
||||||
|
│ ├── predict_plastic.py # 塑料预测主入口
|
||||||
|
│ └── test.py # 测试脚本
|
||||||
|
│
|
||||||
|
├── README.md # 项目说明文档
|
||||||
|
├── requirements.txt # Python依赖列表
|
||||||
|
└── 项目交接文档.md # 本文件
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、技术栈与依赖
|
||||||
|
|
||||||
|
### 3.1 核心依赖库
|
||||||
|
|
||||||
|
| 库名称 | 版本 | 用途 |
|
||||||
|
|--------|------|------|
|
||||||
|
| torch | 2.8.0 | 深度学习框架 |
|
||||||
|
| torchvision | 0.23.0 | 图像处理工具 |
|
||||||
|
| opencv-python | 4.12.0 | 计算机视觉 |
|
||||||
|
| numpy | 2.2.6 | 数值计算 |
|
||||||
|
| pandas | - | 数据处理 |
|
||||||
|
| scikit-learn | 1.6.1 | 机器学习 |
|
||||||
|
| scipy | 1.15.3 | 科学计算 |
|
||||||
|
| matplotlib | 3.10.3 | 数据可视化 |
|
||||||
|
| spectral | - | 高光谱数据处理 |
|
||||||
|
| PyWavelets | 1.8.0 | 小波变换 |
|
||||||
|
| plantcv | - | 植物/图像分析 |
|
||||||
|
|
||||||
|
### 3.2 完整依赖安装
|
||||||
|
```bash
|
||||||
|
pip install -r requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 四、核心流程说明
|
||||||
|
|
||||||
|
### 4.1 主程序处理流程 (main.py)
|
||||||
|
|
||||||
|
```
|
||||||
|
1. 读取BIL格式高光谱数据
|
||||||
|
↓
|
||||||
|
2. 转换为RGB图像 (bil2rgb.py)
|
||||||
|
↓
|
||||||
|
3. 使用分割模型生成掩膜 (mask.py)
|
||||||
|
├─ 微塑料掩膜
|
||||||
|
└─ 滤纸背景掩膜
|
||||||
|
↓
|
||||||
|
4. 提取光谱特征 (shape_spectral.py)
|
||||||
|
↓
|
||||||
|
5. 计算背景光谱并校正 (shape_spectral_background.py)
|
||||||
|
↓
|
||||||
|
6. 数据清理和过滤
|
||||||
|
├─ 去NA值
|
||||||
|
├─ 过滤轮廓点数不足样本
|
||||||
|
└─ 过滤面积<500像素的样本
|
||||||
|
↓
|
||||||
|
7. 主要分类 (classification_model.Parallel.predict_plastic)
|
||||||
|
↓
|
||||||
|
8. 二次分类(HDPE/LDPE精细分类)
|
||||||
|
↓
|
||||||
|
9. 后处理类别7/8阴影识别
|
||||||
|
↓
|
||||||
|
10. 保存ENVI格式分类结果
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.2 关键参数配置
|
||||||
|
|
||||||
|
#### 训练相机波长(237通道,912.36-1706.6nm)
|
||||||
|
```python
|
||||||
|
TRAIN_WAVELENGTHS = [912.36, 915.68, 919, ..., 1703.3, 1706.6]
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 分类处理参数
|
||||||
|
- **主模型类型**: SVM
|
||||||
|
- **预处理方法1**: SS (Spectral Standardization)
|
||||||
|
- **预处理方法2**: None
|
||||||
|
|
||||||
|
#### 分割参数
|
||||||
|
- `flow_threshold`: 0.4
|
||||||
|
- `cellprob_threshold`: -1
|
||||||
|
- `filter_method`: 'threshold'
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 五、使用方法
|
||||||
|
|
||||||
|
### 5.1 基本用法
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python main.py --bil_path /path/to/input.bil --output_path /path/to/output --model_path /path/to/model.m
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.2 参数说明
|
||||||
|
|
||||||
|
| 参数 | 必需 | 默认值 | 描述 |
|
||||||
|
|------|------|--------|------|
|
||||||
|
| `--bil_path` | 是 | 无 | 输入BIL文件路径 |
|
||||||
|
| `--output_path` | 是 | 无 | 输出目录路径 |
|
||||||
|
| `--model_path` | 是 | 无 | 主分类模型路径 |
|
||||||
|
| `--unet_path` | 否 | ./unet_pytorch/logs/best_epoch_weights.pth | UNet模型权重路径 |
|
||||||
|
|
||||||
|
### 5.3 使用示例
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 使用默认UNet权重
|
||||||
|
python main.py --bil_path ./data/input.bil --output_path ./results --model_path ./models/svm.m
|
||||||
|
|
||||||
|
# 指定所有参数
|
||||||
|
python main.py --bil_path ./data/input.bil --output_path ./results --model_path ./models/svm.m --unet_path ./custom_unet_weights.pth
|
||||||
|
|
||||||
|
# Windows系统示例
|
||||||
|
python main.py --bil_path "C:\Users\HyperSpec\test\MPData2.bil" --output_path "C:\Users\HyperSpec\test" --model_path ".\classification_model\modelsave\svm.m"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.4 滤纸背景样本提取 (fliter_sample_spectral.py)
|
||||||
|
|
||||||
|
```python
|
||||||
|
# 处理单个文件或文件夹
|
||||||
|
bil_path_or_folder = r"D:\Data\Traindata-11"
|
||||||
|
output_csv_path = r"E:\plastic\plastic\output\滤纸样本光谱\11.csv"
|
||||||
|
num_masks = 50 # 生成的背景样本数量
|
||||||
|
rng_seed = 42 # 随机种子,保证可复现
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 六、输入输出格式
|
||||||
|
|
||||||
|
### 6.1 输入文件格式
|
||||||
|
|
||||||
|
| 文件类型 | 扩展名 | 说明 |
|
||||||
|
|---------|--------|------|
|
||||||
|
| 高光谱数据 | .bil | BIL格式高光谱数据 |
|
||||||
|
| 头文件 | .hdr | 对应的ENVI头文件 |
|
||||||
|
|
||||||
|
**HDR文件关键字段:**
|
||||||
|
```
|
||||||
|
samples = 1024 # 列数
|
||||||
|
lines = 1024 # 行数
|
||||||
|
bands = 237 # 波段数
|
||||||
|
wavelength = {912.36, 915.68, ...} # 波长列表
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6.2 输出文件格式
|
||||||
|
|
||||||
|
| 文件类型 | 扩展名 | 说明 |
|
||||||
|
|---------|--------|------|
|
||||||
|
| 分类结果 | .dat | ENVI分类结果数据 |
|
||||||
|
| 头文件 | .hdr | ENVI头文件(含类别定义)|
|
||||||
|
|
||||||
|
**输出HDR示例:**
|
||||||
|
```
|
||||||
|
ENVI
|
||||||
|
description = {Classification Result.}
|
||||||
|
samples = 1024
|
||||||
|
lines = 1024
|
||||||
|
bands = 1
|
||||||
|
classes = 10
|
||||||
|
class = { background, ABS, HDPE, LDPE, PA6, PET, PP, PS, PTFE, PVC }
|
||||||
|
data type = 2 # 16-bit整数
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 七、关键代码模块详解
|
||||||
|
|
||||||
|
### 7.1 main.py - 主流程控制
|
||||||
|
|
||||||
|
**核心函数:**
|
||||||
|
- `validate_inputs()` - 输入验证
|
||||||
|
- `generate_rgb()` - RGB生成
|
||||||
|
- `run_segmentation()` - 图像分割
|
||||||
|
- `extract_primary_features()` - 特征提取
|
||||||
|
- `compute_background_spectrum()` - 背景计算
|
||||||
|
- `apply_background_and_optional_resample()` - 背景校正+重采样
|
||||||
|
- `run_primary_classification()` - 主要分类
|
||||||
|
- `run_secondary_classification_if_needed()` - 二次分类
|
||||||
|
- `postprocess_class7_shadow()` - 阴影后处理
|
||||||
|
|
||||||
|
### 7.2 mask.py - 图像分割
|
||||||
|
|
||||||
|
**功能:**
|
||||||
|
- 微塑料颗粒检测
|
||||||
|
- 滤纸背景区域识别
|
||||||
|
- 返回微塑料掩膜和滤纸掩膜
|
||||||
|
|
||||||
|
**关键参数:**
|
||||||
|
- `flow_threshold`: 流动阈值
|
||||||
|
- `cellprob_threshold`: 细胞概率阈值
|
||||||
|
|
||||||
|
### 7.3 shape_spectral.py - 光谱特征提取
|
||||||
|
|
||||||
|
**功能:**
|
||||||
|
- 从BIL数据提取光谱特征
|
||||||
|
- 计算形状特征(轮廓、面积等)
|
||||||
|
- 使用PlantCV库
|
||||||
|
|
||||||
|
### 7.4 shape_spectral_background.py - 背景校正
|
||||||
|
|
||||||
|
**功能:**
|
||||||
|
- 计算滤纸背景光谱
|
||||||
|
- 用于后续背景校正
|
||||||
|
|
||||||
|
### 7.5 classification_model.Parallel.predict_plastic - 分类预测
|
||||||
|
|
||||||
|
**功能:**
|
||||||
|
- 加载训练好的模型
|
||||||
|
- 特征标准化
|
||||||
|
- 预测塑料类别
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 八、注意事项与常见问题
|
||||||
|
|
||||||
|
### 8.1 系统要求
|
||||||
|
- **Python版本**: 3.12+
|
||||||
|
- **内存**: 足够处理高光谱数据(建议16GB+)
|
||||||
|
- **存储**: 建议使用固态硬盘
|
||||||
|
- **GPU**: 可选,用于加速(CUDA支持)
|
||||||
|
|
||||||
|
### 8.2 常见问题
|
||||||
|
|
||||||
|
#### Q1: 运行时报错"ModuleNotFoundError"
|
||||||
|
**解决:** 确保已安装所有依赖
|
||||||
|
```bash
|
||||||
|
pip install -r requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Q2: 处理大型文件时内存不足
|
||||||
|
**解决:**
|
||||||
|
- 考虑减少处理区域
|
||||||
|
- 增加系统内存
|
||||||
|
- 分批处理数据
|
||||||
|
|
||||||
|
#### Q3: 分类结果不准确
|
||||||
|
**解决:**
|
||||||
|
- 检查输入数据质量
|
||||||
|
- 确认模型是否适合当前数据类型
|
||||||
|
- 验证波长范围是否匹配
|
||||||
|
|
||||||
|
#### Q4: BIL文件波段数不足
|
||||||
|
**解决:** 确保输入文件至少有160个波段(RGB生成需要索引9, 59, 159)
|
||||||
|
|
||||||
|
#### Q5: 特征维度不匹配错误
|
||||||
|
**解决:**
|
||||||
|
- 检查模型对应的`scaler_params.pkl`是否存在
|
||||||
|
- 确认训练时和预测时的特征维度一致
|
||||||
|
|
||||||
|
### 8.3 重要注意事项
|
||||||
|
|
||||||
|
1. **波长对齐**: 系统会自动检测输入波长与训练波长(237通道)是否匹配,不匹配时会自动重采样
|
||||||
|
2. **背景校正**: 使用滤纸区域光谱作为背景进行除法校正
|
||||||
|
3. **轮廓收缩**: 输出前会自动收缩轮廓1像素,避免颗粒相连
|
||||||
|
4. **阴影处理**: 类别7/8会进行阴影检测,低对比度区域会被标记为背景
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 九、模型文件说明
|
||||||
|
|
||||||
|
### 9.1 模型文件位置
|
||||||
|
```
|
||||||
|
classification_model/modelsave/
|
||||||
|
├── svm.m # 主分类模型(SVM)
|
||||||
|
├── scaler_params.pkl # 标准化参数
|
||||||
|
└── HDPELDPE_model/
|
||||||
|
└── svm.m # HDPE/LDPE二次分类模型
|
||||||
|
```
|
||||||
|
|
||||||
|
### 9.2 支持的模型类型
|
||||||
|
- SVM (支持向量机)
|
||||||
|
- Random Forest (随机森林)
|
||||||
|
- XGBoost/LightGBM (梯度提升)
|
||||||
|
- CNN (卷积神经网络)
|
||||||
|
- SAE+CNN (堆叠自编码器+CNN)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 十、开发历史与版本记录
|
||||||
|
|
||||||
|
### v1.0.0 (2025-08-26)
|
||||||
|
- 初始版本发布
|
||||||
|
- 支持BIL格式高光谱数据处理
|
||||||
|
- 集成UNet分割和SVM分类
|
||||||
|
- 输出ENVI格式分类结果
|
||||||
|
- 支持9种塑料材料分类
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 十一、联系方式
|
||||||
|
|
||||||
|
| 项目 | 信息 |
|
||||||
|
|------|------|
|
||||||
|
| **作者** | 北京依锐思 |
|
||||||
|
| **邮箱** | huilai_zhang@126.com |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 十二、待优化/已知问题
|
||||||
|
|
||||||
|
### 12.1 已知限制
|
||||||
|
1. 输入BIL文件波段数需≥160(RGB生成需求)
|
||||||
|
2. 滤纸检测依赖于阈值方法,对非标准滤纸可能需要调整参数
|
||||||
|
3. 二次分类仅针对HDPE/LDPE
|
||||||
|
|
||||||
|
### 12.2 建议改进方向
|
||||||
|
1. 增加更多二次分类场景(如PP/PS等易混淆材料)
|
||||||
|
2. 优化内存使用,支持更大文件流式处理
|
||||||
|
3. 添加GUI界面便于非技术用户使用
|
||||||
|
4. 增加批处理脚本的配置化能力
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**文档生成日期:** 2026-04-10
|
||||||
|
|
||||||
|
**文档版本:** 1.0
|
||||||
Reference in New Issue
Block a user