浅谈read_image出错的解决办法
问题描述
在进行和图像有关的深度学习处理时,常常会调用到torchvision.io
中的一个函数read_image
。这个函数往往是图像送入模型的临门一脚,只要经过这个函数之后,图片按照路径被读入内存,经过transforms
之后输入模型。
然而,如果没有做好预处理,read_image
常常会报一些意外的错误之后退出,然后整个训练也随之中断了。本文想浅谈一下笔者个人遇到的问题并给出一些解决方案。
解决方案
仅支持RGB的色彩模式
read_image
只支持RGB的色彩模式,这很好理解也很合理。因为如果我们图片不只有RGB的话,就没办法保证读入的数据是有R,
G,
B三个通道的,它可能有4个通道(CMYK色彩模式的图片)或者只有1个通道(灰度图)。
灰度图很好理解,其实就是黑白照片那样。那CMYK呢,参考链接:
印刷四分色模式(CMYK)是彩色印刷时采用的一种套色模式,利用色料的三原色混色原理,加上黑色油墨,共计四种颜色混合叠加,形成所谓“全彩印刷”。四种标准颜色是:
- C:Cyan = 青色或“水蓝”
- M:Magenta = 洋红色或“紫色”
- Y:Yellow = 黄色
- K:Key plate 因实务上多使用黑色,所以也可以简单视为blacK
总之CMYK色彩模式是为了印刷品而存在的,如果一开始创作作品就是为了打印出来,会使用这个色彩模式避免后期打印出来之后色彩失真。
这两种特殊情况都比较好解决,强行转换为"RGB"色彩模式即可,可以借助Pillow库实现。
1 | from PIL import Image |
仅支持8bit的图片
这个报错一开始是感觉有点莫名其妙的,推测可能是有的图片会有10bit的色深。我个人观测了一下,一般会发生在PNG图片上,所以把所有的PNG图片都转换成RGB模式再保存一下就行了(不是好的解决方案,但可行)。
1 | if image_file.endswith(".png"): |
仅支持jpg或png图片
这个报错是因为加载了webp
或者其他格式的图片,因为webp
格式的可以包含透明度通道,因此通道数可能是3或4,这里退出也没啥问题。那还是转成RGB
模式再保存为就行了。
1 | if image_file.endswith(".webp"): |
读入了被截断的图片
有的时候用图片查看软件看的时候一张图片没啥问题,但是读进去的时候会报TRUNCATED IMAGE
的错误。图片可能本身发生了一些肉眼看不到的损坏,简单设置一下还是可以读进去的。
1 | # 错误处理,坏的图片也读进去 |
这样做了之后读进损坏图片不会报错,而是会在损坏部分用白色填充。如果需要构建干净的图片数据集,可以考虑关掉读入损坏图片,直接将报TRUNCATED IMAGE
的图片从数据集中删除掉。
读入了动图
这是最搞的,一张jpg
后缀的图片,读入时却报错只支持静态图片格式。然后切换Debug去看是哪张图片出问题了,好家伙,这个“jpg”文件在图像管理器中神奇地动了起来。这时候才明白这是张以"jpg"结尾的动图,所以才出问题。这个问题需要借助Python自带的imghdr
库实现对动图文件的识别。
1 | # 查看图片真实类型 |
动图实际上应该可以更进一步地处理,比如抽取其中一帧作为图像的输入。但是我觉得动图比较少,于是直接丢弃了。
小结
感觉read_image
出问题了,转换成RGB格式之后再保存一遍可以解决大多数问题。其他的比如动图问题或者图片被截断这样的问题,如果比较粗糙的处理就直接忽略掉这张图片,否则可以根据具体情况更进一步处理。
还有,预处理过的结果记得保存,不然每次都要预处理也很占时间。