日本語pathのファイルをopenCVが読んでくれないのでPILで読んでから渡した


python環境の画像処理にopenCVを使っているんですが、cv2.imread()は日本語パスのファイルを開いてくれません。そこでPILで読んできてopenCVで扱えるように並べ替えることにしました。

実行環境

python 3.6.4
opencv-python == 4.0.0.21
Pillow == 5.0.0

openCVで読んだ場合

まずopenCVで読んだらどうなるか確認しておきます。

python
import cv2
import matplotlib.pyplot as plt
img_cv = cv2.imread('./tomato.jpg')
plt.imshow(cv2.cvtColor(img_cv, cv2.COLOR_BGR2RGB))
plt.show()


読めました。

cv2.imread()で読むとnumpy.ndarrayになっているので、そのままで値が見えます。

python
img_cv[0][:5]
out
array([[53, 67, 19],
       [53, 69, 16],
       [47, 64,  7],
       [48, 66,  5],
       [53, 74, 11]], dtype=uint8)

これが再現できればOKです。

PILで読み込み

PILで同じファイルを開いてみます。

python
from PIL import Image
img = Image.open('./tomato.jpg')
img


PILの方が読むのは簡単ですね。

これをnumpy.arrayに変換します。

python
img_arr = np.array(img)
img_arr
out
array([[19, 67, 53],
       [16, 69, 53],
       [ 7, 64, 47],
       [ 5, 66, 48],
       [11, 74, 53]], dtype=uint8)

numpy.arrayにはできましたが、先ほどcv2.imreadで読んだものとは順番が違います。PIL.Image.open()はRGB、cv2.imread()はBGRの順で読んできますので、並べ替えてやる必要があります。

python
img_arr2 = img_arr[:,:,::-1]
img_arr2[0][:5]
out
array([[53, 67, 19],
       [53, 69, 16],
       [47, 64,  7],
       [48, 66,  5],
       [53, 74, 11]], dtype=uint8)

同じになりました。

まとめ

openCVで読む場合

python
import cv2
img = cv2.imread('./tomato.jpg')
img

PILで読んで並べ替える場合

python
from PIL import Image
img = Image.open('./tomato.jpg')
img_arr = np.array(img)
img_arr = img_arr[:,:,::-1]
img_arr

処理時間も大差ないようなのでこれで良さそうです。

おしまい