Pynote

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

OpenCV - imread で画像を読み込む、imwrite で画像を保存する

画像を読み込む。(cv2.imread)

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

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

読み込みに失敗した場合は None を返す。

import os

import cv2

img_path = "sample.png"
img = cv2.imread(img_path)
if img is None:
    # 読み込みに失敗した場合は None が返る。
    print(f"Failed to load image. {os.path.abspath(img_path)}")

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

import cv2

# グレースケール形式で読み込む場合
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]

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

  • ファイルパスが間違っている。相対パスで指定した場合、スクリプトを実行したディレクトリが起点となるので注意する。
  • ファイルパスに日本語が含まれている。OpenCV は、2バイト文字に対応していないので、パスに日本語が含まれていると読み込みに失敗する。
  • ファイルが壊れている、または対応していない。jpg、png、gif、bmp など広く使われている形式は対応しているので、このケースはあまりないかもしれない。
  • Windows の場合、パスの \ マークはエスケープが必要な文字なので、エスケープする代わりに raw 文字列を使うとよい。
cv2.imread(r"C:\Users\UserName\Desktop\sample.jpg")

画像を書き込む。(cv2.imwrite)

cv2.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.")

画像をエンコード/デコードする。(cv2.imencode、cv2.imdecode)

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

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

cv2.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