OpenCV – imread で画像の読み込み、imwrite で画像を保存をする方法

概要
OpenCV で cv2.imread() で画像を読み込む、cv2.imwrite() で画像を出力する方法について解説します。
cv2.imread – 画像を読み込む
retval = cv2.imread(filename[, flags])
filename | str | |
ファイル名 | ||
flags | ImreadModes | cv2.IMREAD_COLOR |
読み込み方法 |
名前 | 説明 | ||
---|---|---|---|
retval | 読み込んだ画像 |
import cv2
import numpy as np
from IPython.display import Image, display
from matplotlib import pyplot as plt
def imshow(img):
"""ndarray 配列をインラインで Notebook 上に表示する。
"""
ret, encoded = cv2.imencode(".jpg", img)
display(Image(encoded))
# 画像を読み込む。
img = cv2.imread("sample.jpg")
画像の読み込みに失敗した場合
なんらかの理由で読み込みに失敗した場合は、エラーにはならず、None が返ります。
その場合、その後の処理でエラーになってしまうので、cv2.imread()
の返り値は None でないことを必ずチェックするようにしましょう。
後続の処理でよくあるエラー例
error: OpenCV(4.2.0) /io/opencv/modules/imgproc/src/color.cpp:182: error: (-215:Assertion failed) !_src.empty() in function 'cvtColor'
img = cv2.imread("not_found.jpg")
assert img is not None, "読み込みに失敗しました"
読み込みに失敗した場合のチェック項目
- ファイルパスが間違っていないかどうか
- os.path.abspath() で絶対パスを確認し、そこに画像ファイルがあることを確認する
- ファイルパスが raw 文字列になっているかどうか (Windows の場合)
- ファイルパスに日本語など2バイト文字が含まれていないかどうか
- 2バイト文字が含まれる場合、読み込みに失敗する場合があります
読み込みに失敗する要因として、一番多いのはファイルパスが間違っている場合です。相対パスで指定する場合は、カレントパスがどこになっているか、カレントパスを基準に正しく画像があるパスを指定できているかを os
モジュールを使って確認しましょう。
以下の場合、カレントパスは /data/notebook/pystyle/opencv/opencv-imread-imwrite
になっていて、相対パス sample.jpg
を絶対パスに直した /data/notebook/pystyle/opencv/opencv-imread-imwrite/sample.jpg
に画像ファイルが存在していなければならないことを意味します。
import os
filepath = "sample.jpg"
print("カレントパス", os.getcwd())
print("filepath が指す絶対パス", os.path.abspath(filepath))
print("ファイルが存在するかどうか", os.path.isfile(filepath))
カレントパス /data/notebook/pystyle/opencv/opencv-imread-imwrite filepath が指す絶対パス /data/notebook/pystyle/opencv/opencv-imread-imwrite/sample.jpg ファイルが存在するかどうか True
Windows の場合、ファイルパスの区切り文字 \
はエスケープが必要です。r"<ファイルパス>"
として raw 文字列を使いましょう。
filepath = r"C:\Users\hoge\Desktop\sample.jpg"
flags – 読み込み方法を設定する
デフォルトでは、元画像が1チャンネルや4チャンネルであっても、読み込んだ際に3チャンネル画像に変換されます。flags
引数でこの挙動を制御できます。例えば、アルファチャンネル付きの透過 png を読み込む場合は、cv2.IMREAD_UNCHANGED
を指定します。
# グレースケール形式で読み込む場合
img = cv2.imread("sample.jpg", flags=cv2.IMREAD_GRAYSCALE)
print(img.shape) # (225, 300)
# BGR 形式で読み込む場合 (デフォルト)
img = cv2.imread("sample.jpg", flags=cv2.IMREAD_COLOR)
print(img.shape) # (225, 300, 3)
# 元データのまま読み込む場合
img = cv2.imread("sample.jpg", flags=cv2.IMREAD_UNCHANGED)
print(img.shape) # (239, 200, 4)
(356, 500) (356, 500, 3) (356, 500, 3)
cv2.imwrite – 画像を出力する
retval = cv2.imwrite(filename, img[, params])
filename | str | |
ファイル名 | ||
img | ndarray | |
保存する画像 | ||
params | list of int | list() |
パラメータ |
名前 | 説明 | ||
---|---|---|---|
retval | 出力に成功したかどうか |
# 画像を書き込む。
ret = cv2.imwrite("output.jpg", img)
assert ret, "出力に失敗"
cv2.imencode – 画像をエンコードする
画像をファイルに保存する代わりにバイト列に変換する場合は cv2.imencode
を使用します。
返り値は成功したかどうかを表す retval
とバイト列 buf
になります。buf
は uint8 型の ndarray です。
# jpg 形式にエンコードする。
retval, buf = cv2.imencode(".png", img)
print(buf.shape, buf.dtype) # (26736, 1) uint8
(222570, 1) uint8
cv2.imdecode – 画像をデコードする
jpg
や png
のバイナリデータを表すバイト列をデコードして画像にするには、cv2.imdecode
を使用します。バイナリデータを表す uint8 型の1次元の ndarray 配列を渡します。
# jpg 形式からデコードする。
img = cv2.imdecode(buf, cv2.IMREAD_UNCHANGED)
print(img.shape, img.dtype) # (239, 200, 4) uint8
(356, 500, 3) uint8
-
前の記事
OpenCV – cv2.matchTemplate でテンプレートマッチングを行う方法 2020.08.29
-
次の記事
OpenCV – モルフォロジー演算 (膨張、収縮、オープニング、クロージング) 2020.08.30