使用skimage.io.imsave保存旋转图像失败无报错问题求助
scikit-image旋转TIFF后无法正常保存的问题解决思路
问题描述
使用scikit-image对TIFF图像做去歪斜处理,旋转后调用skimage.io.imsave保存时无报错,但生成123.7MB的透明背景TIFF文件;skimage.io.show()能正常显示旋转后的图像,但保存结果异常。直接保存未旋转的TIFF,文件会从3.3MB增至15.5MB。测试JPG/PNG时,读取、显示、旋转流程正常,但保存时报错:TypeError: Cannot handle this data type: (1, 1, 3), <f8。
复现步骤
- 读取TIFF图像
- 调用
skimage.transform.rotate旋转图像 - 用
skimage.io.imsave保存旋转后的图像
复现代码
import skimage def main(): print("Start main") src_img_path = '/path/to/test.tiff' dst_img_path = '/path/to/test_rotated.tiff' sk_img = skimage.io.imread(src_img_path) tmp_rotated_skimage = skimage.transform.rotate(image=sk_img, angle=10) skimage.io.imsave(dst_img_path, tmp_rotated_skimage) ### start program main()
环境信息
- 操作系统:Arch Linux(内核6.4.1-arch2-1 x86_64)
- scikit-image版本:
python-scikit-image 0.21.0-1
依赖版本核对(官网要求 vs 本地安装)
编译依赖
| 官网要求 | 本地版本 |
|---|---|
| meson-python >=0.13 | meson-python 0.13.2-1 |
| wheel | python-wheel 0.40.0-3 |
| setuptools >=67 | python-setuptools 1:68.0.0-1 |
| packaging >=21 | python-packaging 23.1-1 |
| ninja | ninja 1.11.1-3 |
| Cython >=0.29.32 | cython 0.29.36-1 |
| pythran | python-pythran 0.13.1-2 |
| numpy >=1.21.1 | python-numpy 1.25.0-1 |
运行依赖
| 官网要求 | 本地版本 |
|---|---|
| numpy >=1.21.1 | python-numpy 1.25.0-1 |
| scipy >=1.8 | python-scipy 1.11.1-1 |
| networkx >=2.8 | python-networkx 3.1-1 |
| pillow >=9.0.1 | python-pillow 10.0.0-1 |
| imageio >=2.27 | python-imageio 2.31.1-1 |
| tifffile >=2022.8.12 | python-tifffile 2023.7.4-1 |
| PyWavelets >=1.1.1 | python-pywavelets 1.4.1-1 |
| packaging >=21 | python-packaging 23.1-1 |
| lazy_loader >=0.2 | python-lazy-loader 0.3-1 |
安装时测试失败情况
Successfully built scikit_image-0.21.0-cp311-cp311-linux_x86_64.whl ==> Starting check()... dist/lib/skimage/exposure/tests/test_exposure.py ...............F............. dist/lib/skimage/measure/tests/test_fit.py ...............F............. dist/lib/skimage/measure/tests/test_moments.py ...............F............. ========== short test summary info ========== FAILED dist/lib/skimage/exposure/tests/test_exposure.py::test_rescale_nan_warning[image-dtype] - ValueError: No warning raised matching: FAILED dist/lib/skimage/measure/tests/test_fit.py::test_ellipse_parameter_stability - AssertionError: FAILED dist/lib/skimage/measure/tests/test_moments.py::test_analytical_moments_calculation[3-1-float32] - assert 0.000110473855 < 0.0001 ========== 3 failed, 7691 passed, 12 skipped, 63 deselected, 6 warnings in 191.23s (0:03:11) ==========
解决思路
- 处理数据类型不匹配问题
skimage.transform.rotate默认返回float64类型数据,而多数图像格式仅支持8/16位整数类型。保存前需转换数据类型:
from skimage import img_as_ubyte # 缩放至[0,255]并转为uint8(适用于8位图像) rotated_img = img_as_ubyte(tmp_rotated_skimage) skimage.io.imsave(dst_img_path, rotated_img) # 若原图像为16位,改用img_as_uint # rotated_img = img_as_uint(tmp_rotated_skimage)
- 指定TIFF保存参数优化文件大小
保存TIFF时指定tifffile插件及压缩参数,减少生成文件体积:
skimage.io.imsave(dst_img_path, rotated_img, plugin='tifffile', compression='lzw')
- 修复图像维度异常
针对JPG/PNG保存时的维度报错,可先去除冗余单维度:
import numpy as np # 移除不必要的单维度(如灰度图被错误添加的通道维度) tmp_rotated_skimage = np.squeeze(tmp_rotated_skimage)
- 降级pillow版本排查兼容性
当前pillow 10.0.0与scikit-image 0.21.0可能存在兼容问题,尝试降级至9.x版本:
sudo pacman -S python-pillow=9.5.0-1
- 直接使用tifffile库保存
绕过skimage的imsave,直接调用tifffile库保存,避免中间层兼容问题:
import tifffile tifffile.imwrite(dst_img_path, rotated_img, compression='lzw')
内容的提问来源于stack exchange,提问作者robsch
相关产品推荐
相关产品推荐

