search
LoginSignup
90

More than 3 years have passed since last update.

posted at

updated at

Python OpenCV の cv2.imread 及び cv2.imwrite で日本語を含むファイルパスを取り扱う際の問題への対処について

概要

Python OpenCV で日本語を含むファイルパスを扱う際の以下2点の問題への対処方法の案.

  1. cv2.imread でファイルパスに日本語を含む画像を読み込もうとすると失敗する.
  2. cv2.imwrite を実行した際にファイルパスに含まれる日本語が化ける.

私の環境に問題...?

→ umyu様に「Windows & OpenCV の問題」とコメントいただきました.
アスキー文字にしか対応していないみたい.
Unicode Path/Filename for imread and imwrite · Issue

Currently, the imread and imwrite method only supports std::string as an input. This isn't working with non-ascii directories/paths. Therefore, the a software depends on OpenCV can not guaranty working on all maschines.

実行環境

  • Windows 10 64bit
  • Python 3.6.3 :: Anaconda custom (64-bit)
  • OpenCV 3.3.0

対策案

cv2.imread への対策案

cv2.imread を np.fromfile + cv2.imdecode に分解して実行する.

import numpy as np
import cv2
def imread(filename, flags=cv2.IMREAD_COLOR, dtype=np.uint8):
    try:
        n = np.fromfile(filename, dtype)
        img = cv2.imdecode(n, flags)
        return img
    except Exception as e:
        print(e)
        return None

cv2.imwrite への対策案

cv2.imwrite を cv2.imencode + np.ndarray.tofile に分解して実行する.

import numpy as np
import cv2
import os
def imwrite(filename, img, params=None):
    try:
        ext = os.path.splitext(filename)[1]
        result, n = cv2.imencode(ext, img, params)

        if result:
            with open(filename, mode='w+b') as f:
                n.tofile(f)
            return True
        else:
            return False
    except Exception as e:
        print(e)
        return False

#%% imread
# 通常imread,英語パス -> OK
path_english = r"C:\temp\Jelly beans.tiff"
img = cv2.imread(path_english)
type(img) # numpy.ndarray
img.size # 196608


# rename & copy file
import shutil
path_japanese = r"C:\temp\ジェリー ビーンズ.tiff"
shutil.copy(path_english, path_japanese)


# 通常imread,日本語パス -> NG
img = cv2.imread(path_japanese)
type(img) # NoneType


# 対策imread,日本語パス -> OK
img = imread(path_japanese)
type(img) # numpy.ndarray
img.size # 196608



#%% imwrite
# 通常imwrite,英語パス -> OK
path_english2 = r"C:\temp\Jelly beans.jpg"
cv2.imwrite(path_english2, img)

import os
os.path.exists(path_english2) # True


# 通常imwrite,日本語パス -> NG
path_japanese2 = r"C:\temp\Jelly ビーンズ.jpg"
cv2.imwrite(path_japanese2, img)

os.path.exists(path_japanese2) # False

import glob
glob.glob(r"C:\temp\*")
# ['C:\\temp\\Jelly beans.tiff',
#  'C:\\temp\\Jelly beans.jpg',
#  'C:\\temp\\Jelly 繝薙・繝ウ繧コ.jpg',   # ← 文字化け
#  'C:\\temp\\ジェリー ビーンズ.tiff']

# 対策imwrite,日本語パス -> OK
imwrite(path_japanese2, img)
os.path.exists(path_japanese2) # True

参考リンク

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
90