使用OpenCV超分辨率提升Sentinel2 SWIR图像分辨率遇报错求助
问题分析与解决方案
核心报错原因
该报错源于输入图像与EDSR模型的格式、维度或数据类型不匹配,结合Sentinel-2 SWIR场景,具体诱因包括:
- EDSR_x2模型针对3通道RGB训练,但SWIR是单波段图像,通道数不兼容
- OpenCV读取JP2格式时依赖
openjp2库,配置缺失会导致图像数据损坏 - 图像宽/高不是缩放因子(2)的整数倍,引发模型内部形状计算溢出
- Sentinel-2 SWIR为16位深度,而模型默认处理8位数据
分步解决步骤
1. 正确读取单波段JP2图像
使用IMREAD_UNCHANGED参数读取原始16位单波段数据,避免自动转换为3通道:
import cv2 import numpy as np # 读取原始16位单波段SWIR图像 img = cv2.imread("img.jp2", cv2.IMREAD_UNCHANGED) # 验证图像形状,应为(高度, 宽度)的单通道格式 print(img.shape)
2. 适配模型的3通道输入
将单波段数据复制为3通道,匹配EDSR的输入要求:
# 单通道转3通道 img_3ch = np.repeat(img[..., np.newaxis], 3, axis=-1)
3. 转换为8位数据格式
将16位DN值缩放到0-255的8位范围,适配模型的数据类型要求:
# 16位转8位(Sentinel-2 DN值范围通常为0-10000,可按需调整) img_8bit = cv2.normalize(img_3ch, None, 0, 255, cv2.NORM_MINMAX, dtype=cv2.CV_8U)
4. 调整图像尺寸为2的整数倍
确保宽高是缩放因子的整数倍,避免计算溢出:
h, w = img_8bit.shape[:2] # 裁剪到最近的偶数尺寸 new_h = h - (h % 2) new_w = w - (w % 2) img_resized = img_8bit[:new_h, :new_w]
5. 执行超分辨率并导出结果
sr = cv2.dnn_superres.DnnSuperResImpl_create() sr.readModel("EDSR_x2.pb") sr.setModel("edsr", 2) result = sr.upsample(img_resized) # 提取单波段结果(输入为复制的3通道,取任意一个通道即可) result_swir = result[..., 0] # 可选:转换回16位DN值范围 result_swir_16bit = cv2.normalize(result_swir, None, 0, 10000, cv2.NORM_MINMAX, dtype=cv2.CV_16U) # 保存结果 cv2.imwrite("result.jp2", result_swir_16bit)
额外排查:JP2读取环境验证
若cv2.imread返回None,说明OpenCV未启用openjp2支持,需重新安装:
- 使用conda安装:
conda install -c conda-forge opencv opencv-contrib-python - 或编译OpenCV时勾选
WITH_OPENJP2选项
内容的提问来源于stack exchange,提问作者Tim
相关产品推荐
相关产品推荐

