博客
关于我
PIL及matplotlib:OSError: cannot identify image file錯誤及解決方式
阅读量:291 次
发布时间:2019-03-03

本文共 10898 字,大约阅读时间需要 36 分钟。

PIL及matplotlib:OSError: cannot identify image file錯誤及解決方式

前言

這個錯誤是在使用PIL及matplotlib來讀圖(.jpg檔)的時候發生的。

以下是讀圖時所使用的指令:

from PIL import ImageImage.open('xxx.jpg')

及:

import matplotlib.pyplot as pltplt.imread('xxx.jpg')

這個錯誤只有在讀某個特定的圖檔時才會發生。

但是後來去檢查圖片,卻發現可以用一般的圖片瀏覽器打開,並且看不出什麼問題。

錯誤訊息

使用PIL讀圖時報的錯:

OSErrorTraceback (most recent call last)

<ipython-input-4-ac0decf8a181> in <module>()
----> 1 Image.open(’./images/aireplane/21.jpg’)
/usr/local/lib/python3.5/dist-packages/PIL/Image.py in open(fp, mode)
2517 fp.close()
2518 raise IOError(“cannot identify image file %r”
-> 2519 % (filename if filename else fp))
2520
2521 #
OSError: cannot identify image file ‘./images/aireplane/21.jpg’

使用matplotlib讀圖時報的錯:

OSErrorTraceback (most recent call last)

<ipython-input-3-62fde97010d1> in <module>()
----> 1 im=plt.imread(’./images/aireplane/21.jpg’)

/usr/local/lib/python3.5/dist-packages/matplotlib/pyplot.py in imread(*args, **kwargs)

2312 @docstring.copy_dedent(_imread)
2313 def imread(*args, **kwargs):
-> 2314 return _imread(*args, **kwargs)
2315
2316

/usr/local/lib/python3.5/dist-packages/matplotlib/image.py in imread(fname, format)

1276
1277 if ext not in handlers:
-> 1278 im = pilread(fname)
1279 if im is None:
1280 raise ValueError('Only know how to handle extensions: %s; ’

/usr/local/lib/python3.5/dist-packages/matplotlib/image.py in pilread(fname)

1254 except ImportError:
1255 return None
-> 1256 with Image.open(fname) as image:
1257 return pil_to_array(image)
1258

/usr/local/lib/python3.5/dist-packages/PIL/Image.py in open(fp, mode)

2517 fp.close()
2518 raise IOError(“cannot identify image file %r”
-> 2519 % (filename if filename else fp))
2520
2521 #

OSError: cannot identify image file ‘./images/aireplane/21.jpg’

問題排查

問題的解決方法是筆者不經意發現的。

因為PIL跟matplotlib都無法讀圖,所以想安裝其它的包試試看。

一開始試了opencv-python,安裝完成後,發現使用:

import cv2cv2.imread('xxx.jpg')

可以成功讀圖。

後來試了scikit-image,安裝完成後,使用:

import skimageskimage.io.imread('xxx.jpg')

也可以成功讀圖。

skimage安裝完成後,筆者嘗試使用PIL跟matplotlib再次讀圖,發現竟然都成功了!

後來回去看skimage安裝的log:

Collecting scikit-image

Downloading (25.2MB)
100% |################################| 25.2MB 67kB/s eta 0:00:011 15% |#### | 3.9MB 842kB/s eta 0:00:26
Requirement already satisfied: matplotlib>=2.0.0 in /usr/local/lib/python3.5/dist-packages (from scikit-image)
Collecting PyWavelets>=0.4.0 (from scikit-image)
Downloading (4.4MB)
100% |################################| 4.4MB 268kB/s ta 0:00:011
Collecting pillow>=4.3.0 (from scikit-image)
Downloading (2.0MB)
100% |################################| 2.0MB 392kB/s ta 0:00:011
Requirement already satisfied: scipy>=0.17.0 in /usr/local/lib/python3.5/dist-packages (from scikit-image)
Collecting cloudpickle>=0.2.1 (from scikit-image)
Downloading
Collecting dask[array]>=0.9.0 (from scikit-image)
Downloading (685kB)
100% |################################| 686kB 612kB/s ta 0:00:011 26% |######## | 184kB 576kB/s eta 0:00:01
Collecting networkx>=1.8 (from scikit-image)
Downloading (1.7MB)
100% |################################| 1.7MB 391kB/s ta 0:00:011 47% |############### | 808kB 31.1MB/s eta 0:00:01
Requirement already satisfied: six>=1.10.0 in /usr/local/lib/python3.5/dist-packages (from scikit-image)
Requirement already satisfied: pytz in /usr/local/lib/python3.5/dist-packages (from matplotlib>=2.0.0->scikit-image)
Requirement already satisfied: numpy>=1.7.1 in /usr/local/lib/python3.5/dist-packages (from matplotlib>=2.0.0->scikit-image)
Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.5/dist-packages (from matplotlib>=2.0.0->scikit-image)
Requirement already satisfied: pyparsing!=2.0.0,!=2.0.4,!=2.1.2,!=2.1.6,>=1.5.6 in /usr/local/lib/python3.5/dist-packages (from matplotlib>=2.0.0->scikit-image)
Requirement already satisfied: python-dateutil in /usr/local/lib/python3.5/dist-packages (from matplotlib>=2.0.0->scikit-image)
Collecting toolz>=0.7.3; extra == “array” (from dask[array]>=0.9.0->scikit-image)
Downloading (45kB)
100% |################################| 51kB 618kB/s ta 0:00:011
Collecting decorator>=4.3.0 (from networkx>=1.8->scikit-image)
Downloading
Building wheels for collected packages: networkx, toolz
Running bdist_wheel for networkx … done
Stored in directory: /root/.cache/pip/wheels/68/f8/29/b53346a112a07d30a5a84d53f19aeadaa1a474897c0423af91
Running bdist_wheel for toolz … done
Stored in directory: /root/.cache/pip/wheels/f4/0c/f6/ce6b2d1aa459ee97cc3c0f82236302bd62d89c86c700219463
Successfully built networkx toolz
Installing collected packages: PyWavelets, pillow, cloudpickle, toolz, dask, decorator, networkx, scikit-image
Found existing installation: Pillow 4.2.1
Uninstalling Pillow-4.2.1:
Successfully uninstalled Pillow-4.2.1
Found existing installation: decorator 4.1.2
Uninstalling decorator-4.1.2:
Successfully uninstalled decorator-4.1.2
Successfully installed PyWavelets-1.0.1 cloudpickle-0.6.1 dask-1.0.0 decorator-4.3.0 networkx-2.2 pillow-5.3.0 scikit-image-0.14.1 toolz-0.9.0
You are using pip version 9.0.1, however version 18.1 is available.
You should consider upgrading via the ‘pip install --upgrade pip’ command.

發現它卸載了4.2.1版的Pillow並重新安裝了5.3.0版。

因此我們可以猜測,問題就是出在Pillow的版本上。

後來筆者做個實驗,重新使用:

pip install Pillow==4.2.0

來將Pillow還原成舊版。這時問題果然又出現了!

所以問題確定是出在Pillow的版本上!

解決方法

既然知道了問題是出在Pillow的版本上,那麼使用以下其中一個指令來升級Pillow就可以解決問題:

pip install Pillow==5.3.0pip install --upgrade Pillow

後記

這個問題的解決辦法是升級Pillow,但是為何升級個Pillow就改變了PIL及matplotlib的行為呢?

筆者後來去查了PIL跟Pillow的關係及matplotlib讀圖的方式,將之記錄於下。

PIL跟Pillow的關係

去查看:

Pillow is the friendly PIL fork by Alex Clark and Contributors. PIL is the Python Imaging Library by Fredrik Lundh and Contributors.

去查看PIL的訊息:

As more time passes since the last PIL release (1.1.7 in 2009), the likelihood of a new PIL release decreases. However, we’ve yet to hear an official “PIL is dead” announcement.

總結一下:PIL自2009年以來就沒有再推出新的版本,而Pillow則是PIL的fork。

這又衍生出一個問題:既然Pillow是用pip install Pillow來安裝,但是為何在python裡卻是下import PIL來調用呢?

首先在python裡查看包的路徑:

import PILPIL

<module ‘PIL’ from ‘/usr/local/lib/python3.5/dist-packages/PIL/init.py’>

發現目錄名稱確實是PIL。

再去下載whl檔做驗證:

wget https://files.pythonhosted.org/packages/bc/cc/b6e47b0075ca4267855d77850af7ea4194d2fc591664f1d70e5151b50637/Pillow-5.3.0-cp35-cp35m-manylinux1_x86_64.whl

接著查看whl檔的內容,發現Pillow的whl檔確實是有PIL的。

unzip Pillow-5.3.0-cp35-cp35m-manylinux1_x86_64.whl

Archive: Pillow-5.3.0-cp35-cp35m-manylinux1_x86_64.whl

inflating: Pillow-5.3.0.dist-info/WHEEL
inflating: Pillow-5.3.0.dist-info/top_level.txt
inflating: Pillow-5.3.0.dist-info/zip-safe
inflating: Pillow-5.3.0.dist-info/LICENSE
inflating: Pillow-5.3.0.dist-info/METADATA
inflating: Pillow-5.3.0.dist-info/RECORD
inflating: PIL/GimpGradientFile.py
inflating: PIL/PcfFontFile.py
inflating: PIL/FliImagePlugin.py
inflating: PIL/ImageCms.py
inflating: PIL/ImageFont.py
inflating: PIL/FtexImagePlugin.py
inflating: PIL/BmpImagePlugin.py
inflating: PIL/ImageFile.py
inflating: PIL/TarIO.py
inflating: PIL/PixarImagePlugin.py
inflating: PIL/XbmImagePlugin.py
inflating: PIL/IcnsImagePlugin.py
inflating: PIL/features.py
inflating: PIL/MpoImagePlugin.py
inflating: PIL/BufrStubImagePlugin.py
inflating: PIL/ExifTags.py
inflating: PIL/_tkinter_finder.py
inflating: PIL/_binary.py
inflating: PIL/DcxImagePlugin.py
inflating: PIL/McIdasImagePlugin.py
inflating: PIL/ContainerIO.py
inflating: PIL/GribStubImagePlugin.py
inflating: PIL/ImageMorph.py
inflating: PIL/GifImagePlugin.py
inflating: PIL/ImageWin.py
inflating: PIL/SunImagePlugin.py
inflating: PIL/ImtImagePlugin.py
inflating: PIL/PcxImagePlugin.py
inflating: PIL/ImagePath.py
inflating: PIL/ImageFilter.py
inflating: PIL/IptcImagePlugin.py
inflating: PIL/init.py
inflating: PIL/_imagingmorph.cpython-35m-x86_64-linux-gnu.so
inflating: PIL/Image.py
inflating: PIL/XVThumbImagePlugin.py
inflating: PIL/PdfParser.py
inflating: PIL/WmfImagePlugin.py
inflating: PIL/ImageDraw.py
inflating: PIL/MicImagePlugin.py
inflating: PIL/_imagingtk.cpython-35m-x86_64-linux-gnu.so
inflating: PIL/FitsStubImagePlugin.py
inflating: PIL/SpiderImagePlugin.py
inflating: PIL/PpmImagePlugin.py
inflating: PIL/GimpPaletteFile.py
inflating: PIL/BlpImagePlugin.py
inflating: PIL/ImageMode.py
inflating: PIL/ImageColor.py
inflating: PIL/ImageShow.py
inflating: PIL/EpsImagePlugin.py
inflating: PIL/PalmImagePlugin.py
inflating: PIL/MpegImagePlugin.py
inflating: PIL/SgiImagePlugin.py
inflating: PIL/Hdf5StubImagePlugin.py
inflating: PIL/Jpeg2KImagePlugin.py
inflating: PIL/BdfFontFile.py
inflating: PIL/WalImageFile.py
inflating: PIL/DdsImagePlugin.py
inflating: PIL/TgaImagePlugin.py
inflating: PIL/XpmImagePlugin.py
inflating: PIL/JpegPresets.py
inflating: PIL/ImagePalette.py
inflating: PIL/_version.py
inflating: PIL/_imagingmath.cpython-35m-x86_64-linux-gnu.so
inflating: PIL/ImageDraw2.py
inflating: PIL/ImImagePlugin.py
inflating: PIL/ImageTransform.py
inflating: PIL/PaletteFile.py
inflating: PIL/ImageStat.py
inflating: PIL/_util.py
inflating: PIL/MspImagePlugin.py
inflating: PIL/GdImageFile.py
inflating: PIL/ImageOps.py
inflating: PIL/ImageGrab.py
inflating: PIL/TiffTags.py
inflating: PIL/PdfImagePlugin.py
inflating: PIL/ImageChops.py
inflating: PIL/GbrImagePlugin.py
inflating: PIL/ImageEnhance.py
inflating: PIL/PSDraw.py
inflating: PIL/FontFile.py
inflating: PIL/ImageMath.py
inflating: PIL/ImageSequence.py
inflating: PIL/PsdImagePlugin.py
inflating: PIL/_imaging.cpython-35m-x86_64-linux-gnu.so
inflating: PIL/IcoImagePlugin.py
inflating: PIL/TiffImagePlugin.py
inflating: PIL/OleFileIO.py
inflating: PIL/JpegImagePlugin.py
inflating: PIL/CurImagePlugin.py
inflating: PIL/PngImagePlugin.py
inflating: PIL/_webp.cpython-35m-x86_64-linux-gnu.so
inflating: PIL/WebPImagePlugin.py
inflating: PIL/_imagingft.cpython-35m-x86_64-linux-gnu.so
inflating: PIL/ImageTk.py
inflating: PIL/_imagingcms.cpython-35m-x86_64-linux-gnu.so
inflating: PIL/FpxImagePlugin.py
inflating: PIL/ImageQt.py
inflating: PIL/PyAccess.py
inflating: PIL/PcdImagePlugin.py
inflating: PIL/.libs/libopenjp2-e366d6b0.so.2.1.0
inflating: PIL/.libs/libwebpdemux-eba3dc32.so.2.0.4
inflating: PIL/.libs/liblcms2-a6801db4.so.2.0.8
inflating: PIL/.libs/liblzma-6cd627ed.so.5.2.4
inflating: PIL/.libs/libpng16-898afbbd.so.16.35.0
inflating: PIL/.libs/libtiff-8a6d997d.so.5.3.0
inflating: PIL/.libs/libjpeg-3fe7dfc0.so.9.3.0
inflating: PIL/.libs/libwebp-8ccd29fd.so.7.0.2
inflating: PIL/.libs/libz-a147dcb0.so.1.2.3
inflating: PIL/.libs/libfreetype-7ce95de6.so.6.16.1
inflating: PIL/.libs/libwebpmux-1c63fe99.so.3.0.2

所以我們可以發現,雖然pip包的名字是Pillow,但是因為安裝後文件夾的名稱是PIL,所以必須用import PIL

而我們升級Pillow後,PIL文件夾的內容會被改變。我們重啟python後再用import PIL時就會得到新版的Pillow。

matplotlib讀圖的方式

為何重新安裝Pillow,matplotlib讀圖時發生的問題就一併解決了呢?

首先去的頁面查看:

Loading image data is supported by the Pillow library. Natively, matplotlib only supports PNG images. The commands shown below fall back on Pillow if the native read fails.

這句話說明了matplotlib的原生讀圖程式只能讀.png檔;如果是.png以外的檔案,matplotlib則會調用Pillow來讀圖。

這個錯誤是發生在讀.jpg檔時,這代表matplotlib實際上是透過Pillow來讀的。

這也就解釋了為何升級了Pillow,matplotlib的行為就跟著改變了。

參考連結

转载地址:http://qmtm.baihongyu.com/

你可能感兴趣的文章
2020电工(初级)考试及电工(初级)考试软件
查看>>
2020N1叉车司机模拟考试题库及N1叉车司机复审模拟考试
查看>>
2020熔化焊接与热切割考试及熔化焊接与热切割考试题库
查看>>
2020年G3锅炉水处理报名考试及G3锅炉水处理考试申请表
查看>>
2020年制冷与空调设备运行操作答案解析及制冷与空调设备运行操作考试总结
查看>>
2020年保育员(初级)考试资料及保育员(初级)新版试题
查看>>
2020年茶艺师(高级)考试内容及茶艺师(高级)考试申请表
查看>>
2021年烟花爆竹经营单位安全管理人员考试及烟花爆竹经营单位安全管理人员考试试卷
查看>>
2021年过氧化工艺试题及答案及过氧化工艺考试平台
查看>>
2021年重氮化工艺考试题库及重氮化工艺考试报名
查看>>
2021年车工(高级)考试总结及车工(高级)试题及答案
查看>>
2021年压力焊证考试及压力焊实操考试视频
查看>>
2021年低压电工考试及低压电工考试申请表
查看>>
2021年低压电工考试及低压电工考试申请表
查看>>
2021年A特种设备相关管理(电梯)考试APP及A特种设备相关管理(电梯)复审考试
查看>>
2021年美容师(初级)考试报名及美容师(初级)新版试题
查看>>
2021年N1叉车司机考试题及N1叉车司机复审模拟考试
查看>>
2021年危险化学品经营单位主要负责人考试APP及危险化学品经营单位主要负责人多少钱
查看>>
2021年T电梯修理考试技巧及T电梯修理模拟考试软件
查看>>
2021年R2移动式压力容器充装考试题及R2移动式压力容器充装找答案
查看>>