Pynote

Python、機械学習、画像処理について

OpenCV - imread()、imwrite() で画像をファイルに入出力する

概要

OpenCV で imread()、imwrite() で画像をファイルに入出力する方法について

画像を読み込む。

imread() で画像をファイルから読み込める。

retval = cv2.imread(filename[, flags])

ファイルパスが間違っている等で読み込みに失敗した場合は None を返す。

import cv2

img = cv2.imread('sample.png')
if img is None:
    # 読み込みに失敗した場合は None が返る。
    print('failed to load image.')

第2引数で読み込む際に画像を指定の形式に変換できる。
デフォルトでは BGR 形式の画像を返す。

# グレースケール形式で読み込む場合
img = cv2.imread('sample.png', flags=cv2.IMREAD_GRAYSCALE)
print(img.shape)  # (225, 300)

# BGR 形式で読み込む場合 (デフォルト)
img = cv2.imread('sample.png', flags=cv2.IMREAD_COLOR)
print(img.shape)  # (225, 300, 3)

# 元データのまま読み込む場合
img = cv2.imread('sample.png', flags=cv2.IMREAD_UNCHANGED)
print(img.shape)  # (239, 200, 4)

OpenCV は画像のチャンネル順を BGR として扱うため、imread() で読み込んだ画像を PIL や matplotlib など他のライブラリで扱う際は注意する。

from PIL import Image

pil_img = np.array(Image.open('sample.png'))
cv_img = cv2.imread('sample.png', flags=cv2.IMREAD_UNCHANGED)

# (100, 100) の画素値。チャンネル順が逆になっていることがわかる。
print('PIL (RGB)', pil_img[100, 100])  # PIL (RGB) [222 224 224 255]
print('OpenCV (BGR)', cv_img[100, 100])  # OpenCV (BGR) [224 224 222 255]

画像の読み込みに失敗する場合

1. パスが間違っている。
2. パスに日本語が含まれている。
OpenCV は、2バイト文字に対応していないので、パスに日本語が含まれていると読み込みに失敗する。
3. ファイルが壊れている、または対応していない。
jpg、png、gif、bmp などよく使われる形式は大抵対応しているので、このケースはあまりないかもしれない。

パスの指定は相対パスまたは絶対パスで指定する。
Windows の場合、パスの \ マークはエスケープが必要な文字なので、エスケープする代わりに raw 文字列を使うとよい。

cv2.imread(r'C:\Users\UserName\Desktop\sample.jpg')

相対パスの場合、スクリプトを実行しているディレクトリを起点にして指定する。

cv2.imread(r'imgs\sample.jpg')

画像を書き込む

imwrite() で画像をファイルへ出力できる。

retval = cv2.imwrite(filename, img[, params])

出力に成功した場合は True、失敗した場合は False を返す。

# 画像を読み込む。
img = cv2.imread('sample.png', cv2.IMREAD_UNCHANGED)

# 画像を書き込む。
ret = cv2.imwrite('other.png', img)
if not ret:
    print('Failed to write image.')

画像をエンコード/デコードする。

imencode() で画像を jpg, png など指定したフォーマットにエンコードしたバイト列を得ることができる。

retval, buf = cv2.imencode(ext, img[, params])

imdecode() で jpg, png などでエンコードされたバイト列を画像に変換できる。

retval = cv2.imdecode(buf, flags)
# 画像を読み込む。
img = cv2.imread('sample.png', cv2.IMREAD_UNCHANGED)

# jpg 形式にエンコードする。
retval, buf = cv2.imencode('.png', img)
print(buf.shape, buf.dtype)  # (26736, 1) uint8

# jpg 形式からデコードする。
img = cv2.imdecode(buf, cv2.IMREAD_UNCHANGED)
print(img.shape, img.dtype)  # (239, 200, 4) uint8