当方の環境は以下で
Python 3.7.0
Pillow 5.3.0
numpy 1.15.4
質問者さんと同一のコードで期待通り読み込めました。しかしながら質問者さんが挙げておられるコードを若干変更すると再現できました。
python
1image_buf = urllib.request.urlopen(url).read()
2image_raw = io.BytesIO(image_buf)
3image_input = Image.open(image_raw)
4
5print(type(image_input))
6# <class 'PIL.JpegImagePlugin.JpegImageFile'>
7print(image_input.size)
8# (64, 64)
9
10# ============= 追加:ここから =============
11image_raw.close() # 画像の内容に一度もアクセスせず(loadを行わず)入力ファイルを閉じる
12# ============= 追加:ここまで =============
13image_np = np.asarray(image_input)
14
15print(image_np)
16# <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=48x48 at 0x22116560C18>
17# これはアドレスが出てるというより、オリジナルのImageインスタンスを唯一の要素とする
18# スカラのndarrayになったと認識すべきです。
19
20print(type(image_np))
21# <class 'numpy.ndarray'>
22print(image_np.shape)
23# ()
24print(image_np.dtype)
25# object
また例えば上記のように明示的にcloseしてなくても
Python
1with io.BytesIO(image_buf) as image_raw:
2 image_input = Image.open(image_raw)
3
4print(type(image_input))
5
6image_np = np.asarray(image_input)
7...
とすれば当然同じことが起きます。
実際のコードでは途中でimage_rawを閉じているようなことはありませんか?もしそうならnumpy.ndarrayへ変換し終わるまでは入力ファイルを閉じないようにすればうまくいくと思います。
なぜこのようなことが起きるかの推測:
numpyがPILの画像からndarrayへ変換する際にimage_input.__array_interface__
を通じて配列データを取り出そうとするようです。それまでに画素データのアクセスがない場合、そこで初めて実際の画像データのロードが行われますが、その際入力ファイルが閉じられていると当然画像のロードに失敗します。これは推測ですがnumpyが__array_interface__
プロパティーをアクセスする過程で例外を検知した場合「だまって」例外を握りつぶし、オリジナルのインスタンス(PIL.JpegImagePlugin.JpegImageFile)を唯一の要素とするスカラとして「しれっと」ndarrayへ変換してしまうのではないでしょうか。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/11/29 05:05