概要
OpenCV で cv2.imread()
で画像を読み込む、cv2.imwrite()
で画像を保存する方法について解説します。
cv2.imread – 画像を読み込む
retval = cv2.imread(filename[, flags])
filename | str | |
ファイル名 | ||
flags | ImreadModes | cv2.IMREAD_COLOR |
読み込み方法 |
名前 | 説明 | ||
---|---|---|---|
retval | 読み込んだ画像 |
import cv2
# 画像を読み込む。
img = cv2.imread("sample.jpg")
画像の読み込みに失敗した場合
なんらかの理由で画像の読み込みに失敗した場合、cv2.imread() はエラーは発生せず、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 モジュールを使って確認しましょう。
import os
filepath = "sample.jpg"
print("カレントディレクトリ", os.getcwd())
print("filepath が指す絶対パス", os.path.abspath(filepath))
print("ファイルが存在するかどうか", os.path.isfile(filepath))
カレントディレクトリ /data/notebook/pystyle.info/画像処理/OpenCV/opencv-imread-imwrite filepath が指す絶対パス /data/notebook/pystyle.info/画像処理/OpenCV/opencv-imread-imwrite/sample.jpg ファイルが存在するかどうか True
Windows の場合、ファイルパスの区切り文字 \
はエスケープが必要です。しかし、r"<ファイルパス>"
として raw 文字列を使うと、バックスラッシュをそのまま使用できるため、ファイルパスの指定が簡単になります。
filepath = "C:\\Users\\hoge\\Desktop\\sample.jpg" # raw 文字列でない場合は、エスケープが必要
filepath = r"C:\Users\hoge\Desktop\sample.jpg" # raw 文字列の場合
flags – 読み込み方法を設定する
デフォルトでは、画像が 1 チャンネル (グレースケール) や 4 チャンネル (RGBA) であっても、cv2.imread()
で読み込むと 3 チャンネル (BGR) 画像に変換されます。flags
引数を使うことでこの挙動を制御できます。例えば、アルファチャンネル付きの透過 PNG 画像を読み込む場合は、cv2.IMREAD_UNCHANGED
を指定することで、元のチャンネル数を保持したまま画像を読み込むことができます。
cv2.IMREAD_GRAYSCALE
- グレースケール画像の読み込む場合
- カラー画像をグレースケール画像に変換して読み込む場合
cv2.IMREAD_UNCHANGED
- 透過 PNG 画像を読み込む場合
# グレースケール形式で読み込む場合
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 | 出力に成功したかどうか |
ファイルの保存は、cv2.imwrite()
で行います。出力に失敗した場合、False
を返します。
# 画像を書き込む。
ret = cv2.imwrite("output.jpg", img)
assert ret, "出力に失敗"
cv2.imencode – 画像をエンコードする
画像をファイルに保存する代わりにバイト列に変換する場合は、cv2.imencode()
を使用します。この関数は、指定したファイル形式で画像をエンコードし、バイト列として取得できます。返り値は、エンコードが成功したかどうかを示す retval
と、バイト列 buf
になります。buf
は uint8 型の NumPy 配列です。
# 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
コメント