OpenCV – 画像を読み込み、保存を行う方法

目次

概要

OpenCV で cv2.imread() で画像を読み込む、cv2.imwrite() で画像を保存する方法について解説します。

cv2.imread – 画像を読み込む

retval = cv2.imread(filename[, flags])
引数
filename str
ファイル名
flags ImreadModes cv2.IMREAD_COLOR
読み込み方法
返り値
名前 説明
retval 読み込んだ画像

sample.jpg

In [1]:
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'
In [2]:
img = cv2.imread("not_found.jpg")
assert img is not None, "読み込みに失敗しました"
[ WARN:0@101.571] global loadsave.cpp:241 findDecoder imread_(‘not_found.jpg’): can’t open/read file: check file path/integrity
————————————————————————— AssertionError Traceback (most recent call last) Input In [3], in <cell line: 2>() 1 img = cv2.imread(not_found.jpg) —-> 2 assert img is not None, 読み込みに失敗しました AssertionError: 読み込みに失敗しました

読み込みに失敗した場合のチェック項目

  • ファイルパスが間違っていないか確認する
    • os.path.abspath() を使用して絶対パスを確認し、そのパスに画像ファイルが存在することを確認します。
    • ファイルパスが raw 文字列として指定されているか確認します。 (特に Windows の場合、パスにバックスラッシュが含まれている場合など)
  • ファイルパスに日本語などの 2 バイト文字が含まれていないか確認します。 2 バイト文字が含まれると、画像の読み込みに失敗する場合があります。可能であれば、ファイルパスに英数字のみを使用することを検討します。

画像の読み込みに失敗する最も一般的な要因は、ファイルパスが間違っている場合です。相対パスで指定する場合は、カレントディレクトリがどこになっているかを確認し、そのカレントディレクトリを基準に正しく画像のパスが指定されているかを os モジュールを使って確認しましょう。

In [3]:
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 画像を読み込む場合
In [4]:
# グレースケール形式で読み込む場合
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 を返します。

In [5]:
# 画像を書き込む。
ret = cv2.imwrite("output.jpg", img)
assert ret, "出力に失敗"

cv2.imencode – 画像をエンコードする

画像をファイルに保存する代わりにバイト列に変換する場合は、cv2.imencode() を使用します。この関数は、指定したファイル形式で画像をエンコードし、バイト列として取得できます。返り値は、エンコードが成功したかどうかを示す retval と、バイト列 buf になります。buf は uint8 型の NumPy 配列です。

In [6]:
# jpg 形式にエンコードする。
retval, buf = cv2.imencode(".png", img)
print(buf.shape, buf.dtype)  # (26736, 1) uint8
(222570, 1) uint8

cv2.imdecode – 画像をデコードする

jpgpng のバイナリデータを表すバイト列をデコードして画像にするには、cv2.imdecode を使用します。バイナリデータを表す uint8 型の 1 次元の ndarray 配列を渡します。

In [7]:
# jpg 形式からデコードする。
img = cv2.imdecode(buf, cv2.IMREAD_UNCHANGED)
print(img.shape, img.dtype)  # (239, 200, 4) uint8
(356, 500, 3) uint8

コメント

コメントする

目次