diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/README.md b/README.md index da53350..f4ae5a8 100644 --- a/README.md +++ b/README.md @@ -1,31 +1,36 @@ - # 高光谱塑料分类工具 ![CC BY-NC](https://i.creativecommons.org/l/by-nc/4.0/88x31.png) -[![Python Version](https://img.shields.io/badge/python-3.12%252B-blue)](https://www.python.org/) +[![Python Version](https://img.shields.io/badge/python-3.12%2B-blue)](https://www.python.org/) ## 基于高光谱成像和深度学习的微塑料材料分类与识别工具 ### 功能特性 - 支持BIL格式高光谱数据读取和处理 -- 使用UNet模型进行图像分割和掩膜生成 -- 多种塑料材料的分类识别 +- 使用Cellpose/UNet模型进行图像分割和掩膜生成 +- 支持9种塑料材料分类识别(ABS、HDPE、LDPE、PA6、PET、PP、PS、PTFE、PVC) +- 二次分类支持(HDPE/LDPE精细区分) - 背景校正和光谱特征提取 +- 自动波长重采样(支持不同波段数的高光谱相机) +- 智能滤纸区域检测 - 输出ENVI标准格式分类结果 +- 波段选择工具(基于ANOVA F-score和LDA准则) +- 滤纸背景样本光谱提取工具 ### 安装 #### 前置要求 -- Python 3.12 +- Python 3.12+ - CUDA (可选,用于GPU加速) -- 足够的内存处理高光谱数据 -- 固态硬盘 +- 足够的内存处理高光谱数据(建议16GB+) +- 固态硬盘(推荐,处理大文件时更高效) + #### 安装步骤 1. 克隆仓库: ```bash - git clone - cd hyperspec-plastic-classification + git clone + cd micro_plastic ``` 2. 安装依赖: @@ -36,111 +41,214 @@ ### 使用方法 -#### 基本用法 +#### 主程序:高光谱塑料分类 + +**基本用法** ```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文件路径 | -| --output_path | 是 | 无 | 输出目录路径 | -| --model_path | 是 | 无 | 分类模型路径 | -| --unet_path | 否 | ./unet_pytorch/logs/best_epoch_weights.pth | UNet模型权重路径 | +| `--bil_path` | 是 | 无 | 输入BIL文件路径 | +| `--output_path` | 是 | 无 | 输出文件路径(.dat格式) | +| `--model_path` | 是 | 无 | 主分类模型路径(.m文件) | -#### 示例 +**示例** ```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 +# 基础用法 +python main.py --bil_path ./data/input.bil --output_path ./results/output.dat --model_path ./models/svm.m # 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/ -├── main.py # 主程序入口 +micro_plastic/ +├── main.py # 主程序入口(高光谱分类流程) +├── main_batch_nosample.py # 批量处理版本(无样本生成) +├── mainv1.py # 主程序历史版本 +├── maintest.py # 测试版本 +├── chose_bands.py # 波段选择工具 +├── fliter_sample_spectral.py # 滤纸背景样本提取工具 ├── bil2rgb.py # BIL转RGB模块 -├── unet_pytorch/ # UNet模型相关 -│ ├── predict_rgb.py -│ └── logs/ -│ └── best_epoch_weights.pth # 预训练UNet权重 -├── classification_model/ # 分类模型 -│ └── Parallel/ -│ └── predict_plastic.py -├── modelsave/ -│ └── svm.m # 预训练分类模型 -├── shape_spectral.py # 光谱特征提取 -├── shape_spectral_background.py # 背景校正 +├── shape_spectral.py # 光谱与形状特征提取 +├── shape_spectral_background.py # 背景光谱计算 +├── extact_shape.py # 形状特征提取与背景校正 +├── mask.py # 图像分割与掩膜生成(Cellpose) +├── onlyspectral_background.py # 纯光谱背景处理 +├── only_mask.py # 掩膜处理工具 +├── get_glcm.py # GLCM纹理特征提取 +├── outputs2dataframe.py # 结果转换为DataFrame +├── 多模型.py # 多模型集成工具 +├── spectral_shape_class.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 # 项目依赖 └── README.md # 项目说明 ``` -![img.png](img.png) + ### 输入输出格式 #### 输入文件格式 -- BIL 格式高光谱数据文件 (.bil) -- 对应的 HDR 头文件 (.hdr) +- **BIL格式高光谱数据文件** (`.bil`):Band Interleaved by Line格式 +- **HDR头文件** (`.hdr`):包含图像尺寸、波段数、波长等信息 #### 输出文件格式 -- ENVI 分类结果文件 (.dat) -- ENVI 头文件 (.hdr) +- **ENVI分类结果文件** (`.dat`):分类结果图像 +- **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格式高光谱数据 -2. 转换为RGB图像 -3. 使用UNet模型生成掩膜 -4. 提取光谱特征 -5. 应用背景校正 -6. 数据清理和过滤 -7. 使用分类模型预测材料类型 -8. 保存ENVI格式分类结果 +1. **输入验证**:检查BIL/HDR文件完整性,验证波段数(需≥160波段) +2. **HDR补齐**:自动添加波长信息(如缺失) +3. **RGB生成**:将BIL数据转换为RGB图像(使用波段9, 59, 159) +4. **图像分割**:使用Cellpose生成微塑料掩膜和滤纸掩膜 +5. **特征提取**:提取每个颗粒的光谱特征和形状特征 +6. **背景校正**:用滤纸背景光谱对样本光谱进行校正 +7. **波长重采样**:如需要,重采样到训练相机波长(237通道) +8. **数据清理**:过滤面积<500像素、轮廓点不足的样本 +9. **主分类**:使用SVM等模型进行9类分类 +10. **二次分类**:对HDPE/LDPE类别进行精细分类 +11. **后处理**:识别并修正类别7/8中的阴影误分类 +12. **轮廓收缩**:对轮廓进行1像素腐蚀,避免相邻粘连 +13. **结果保存**:输出ENVI格式分类结果 -### 支持的塑料类型 +### 分类模型说明 -工具支持以下塑料材料的分类: +#### 支持的分类器类型 -| 类别编号 | 材料名称 | -|----------|----------| -| 1 | ABS | -| 2 | HDPE | -| 3 | LDPE | -| 4 | PA6 | -| 5 | PET | -| 6 | PP | -| 7 | PS | -| 8 | PTFE | -| 9 | PVC | +| 模型类型 | 说明 | 适用场景 | +|----------|-------------------------|----------------------| +| SVM | 支持向量机 | 小样本、高维特征 | +| RF | 随机森林 | 通用场景、特征重要性分析 | +| XGBoost | 极端梯度提升 | 大规模数据、高精度需求 | +| LightGBM | 轻量梯度提升 | 大规模数据、快速训练 | +| CNN | 卷积神经网络 | 深度特征学习 | +| SAE+CNN | 堆叠自编码器+CNN | 无监督预训练+微调 | + +#### 波段选择算法 + +| 算法 | 说明 | +|----------|-----------------------------| +| PCA | 主成分分析降维 | +| SPA | 连续投影算法 | +| CARS | 竞争性自适应重加权采样 | +| GA | 遗传算法特征选择 | +| ReliefF | 基于实例的特征权重算法 | +| UVE | 无信息变量消除法 | +| MRMR | 最大相关最小冗余 | ### 依赖库 -主要依赖的 Python 库: +**核心依赖** +- `numpy` - 数值计算 +- `pandas` - 数据处理 +- `opencv-python` - 图像处理 +- `scikit-learn` - 机器学习 +- `torch`/`torchvision` - 深度学习框架 +- `spectral` - 高光谱数据处理 +- `cellpose` - 细胞/颗粒分割(通过mask.py集成) +- `plantcv` - 植物/颗粒计算机视觉 -- opencv-python -- numpy -- matplotlib -- pandas -- pywavelets -- scikit-learn -- torch +**其他重要依赖** +- `scipy` - 科学计算 +- `matplotlib` - 可视化 +- `PyWavelets` - 小波变换 +- `joblib` - 模型序列化 +- `tqdm` - 进度条 +- `xgboost`/`lightgbm`/`catboost` - 梯度提升库 -完整依赖请查看 `requirements.txt` 文件。 - -### 许可证 - -本项目采用 Creative Commons 非商业许可证。 +完整依赖列表请查看 `requirements.txt` +### 训练相机波长 +模型训练使用的237波段波长范围(912.36nm - 1706.6nm),系统自动进行波长对齐和重采样。 ### 常见问题 @@ -150,22 +258,53 @@ hyperspec-plastic-classification/ 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) -项目地址:[https://github.com/yourusername/hyperspec-plastic-classification](https://github.com/yourusername/hyperspec-plastic-classification) +作者:北京依锐思 +邮箱:[huilai_zhang@126.com](mailto:huilai_zhang@126.com) +项目地址:[https://github.com/yourusername/micro_plastic](https://github.com/yourusername/micro_plastic) ### 更新日志 -- v1.0.0 (2025-08-26) - 初始版本发布 - - 支持BIL格式高光谱数据处理 - - 集成UNet分割和SVM分类 - - 输出ENVI格式分类结果 +#### v1.1.0 (2026-04-14) +- 新增波段选择工具 `chose_bands.py` +- 新增滤纸背景样本提取工具 `fliter_sample_spectral.py` +- 优化波长重采样逻辑,支持更多高光谱相机 +- 改进类别7/8的后处理阴影识别算法 +- 添加轮廓收缩功能,避免相邻颗粒粘连 +- 更新项目文档和结构说明 + +#### v1.0.0 (2025-08-26) +- 初始版本发布 +- 支持BIL格式高光谱数据处理 +- 集成Cellpose分割和SVM分类 +- 输出ENVI格式分类结果 +- 支持9种塑料材料分类 diff --git a/fliter_sample_spectral.py b/fliter_sample_spectral.py index 84368ee..b844b06 100644 --- a/fliter_sample_spectral.py +++ b/fliter_sample_spectral.py @@ -1,7 +1,7 @@ from bil2rgb import process_bil_files from shape_spectral import process_images 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 os import matplotlib @@ -10,9 +10,51 @@ from shape_spectral_background import process_images_background from mask import detect_microplastic_mask_from_array 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') +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): hdr_path = bil_path.replace('.bil', '.hdr') 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 -def process_single_bil(bil_path): +def process_single_bil(bil_path, num_masks=50, rng_seed=None): """ - 处理单个BIL文件 + 处理单个BIL文件,生成滤纸背景样本的光谱特征行,并返回DataFrame """ try: print(f"\n{'=' * 60}") @@ -212,45 +254,47 @@ def process_single_bil(bil_path): print("Processing BIL file to generate RGB image...") rgb_img = process_bil_files(bil_path) - # 修改hdr - change_hdr_file(bil_path) + # HDR:仅在缺失 wavelength 时补齐;并尽量对齐训练相机波长(与 main.py 一致) + change_hdr_file(bil_path, TRAIN_WAVELENGTHS) - # 生成掩膜,mask为16位的塑料标签掩膜 + # 生成掩膜:返回塑料掩膜 + 滤纸掩膜 print("Generating mask...") mask, filter_mask_original = detect_microplastic_mask_from_array( image=rgb_img, filter_method='threshold', diameter=None, 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...") - # 清理plantcv的observations,确保只包含当前处理的塑料掩膜数据 - pcv.observations = {} + pcv.observations = {} # 清理plantcv状态 df = process_images(bil_path, new_mask_array) - # 背景校正 - print("Applying background correction...") - df_correct = process_images_background(bil_path, mask) - df.iloc[:, 1:169] = df.iloc[:, 1:169].div(df_correct, axis=1) + # 背景校正(用整图的滤纸背景光谱作为除数)+ 可选重采样到训练相机波长 + print("Applying background correction (+ optional resample)...") + bg_spectrum = process_images_background(bil_path, mask) + df = apply_background_and_optional_resample_for_samples(df, bg_spectrum, bil_path) - # 数据清理 + # 数据清理:去NA、轮廓点数不足、面积过小过滤(与 main.py 对齐) print("Cleaning data...") df = df.dropna() 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] 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 except Exception as e: @@ -261,50 +305,45 @@ def process_single_bil(bil_path): def main(): - # 单个文件或文件夹路径 + # 支持文件或目录;新增可调样本数量与随机种子,便于复现 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 - # 确保输出目录存在 - output_dir = os.path.dirname(output_csv_path) - os.makedirs(output_dir, exist_ok=True) + os.makedirs(os.path.dirname(output_csv_path), exist_ok=True) - # 判断是文件还是文件夹 if os.path.isfile(bil_path_or_folder): bil_files = [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')] print(f"Found {len(bil_files)} BIL files to process") else: print(f"Error: {bil_path_or_folder} is not a valid file or directory") return - # 初始化CSV文件(写入表头) is_first_row = True total_objects = 0 for i, bil_path in enumerate(bil_files, 1): 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: - # 边处理边写入CSV df.to_csv( 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, - header=is_first_row # 只在第一行写入表头 + header=is_first_row ) total_objects += len(df) is_first_row = False print(f" -> {len(df)} objects appended to CSV file") - # 显示统计信息 if total_objects > 0: print(f"\nSummary:") 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}") else: print("\nNo results to save.") diff --git a/项目交接文档.md b/项目交接文档.md new file mode 100644 index 0000000..6ea9fd2 --- /dev/null +++ b/项目交接文档.md @@ -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