画像の読み書き

画像ファイルの読み込み

imread

OpenCV で画像ファイルを読み込むときは imread メソッドを使用する。このメソッドの第 1 引数には、画像へのパスを与える。第 2 引数には、画像ファイルの読み込みモードを指定する。imread で読みこまれた画像は BGR の並びで読み込まれる。一方で、matlablib や PIL などのパッケージでは RGB の並びで読み込まれる。そのため、パッケージ同士でやり取りする際に、色空間を変換する必要がある。

import cv2
img = cv2.imread('sample.jpg', cv2.IMREAD_COLOR)

また、imread メソッドでは、画像ファイルが実際に存在しなくても読み込みエラーが起こらない。imread を使う前に、Python の機能でファイルが存在しているかどうかを一度チェックした方がミスが少ない。

import os
import cv2

img_file = 'sample.jpg'

if not os.path.isfile(img_file):
   raise FileNotFoundError('Image file not found!')

img = cv2.imread(img_file)

読み込みモード

読み込みモードは、次の 3 種類が用意されている。省略した場合は、IMREAD_COLOR となる。

IMREAD_COLOR透明度を無視して、画像をカラー画像として読み込む。
IMREAD_GRAYSCALE画像をグレースケール画像として読み込む。
IMREAD_UNCHANGED透明度を含めて画像をカラー画像として読み込む。

対応フォーマット

imread が対応しているフォーマットには次のようなものがある。ただし、使用している OS に関連ライブラリーがインストールされていないとき、読み込めなかったりする場合がある。

Windows bitmaps.bmp .dib
JPEG, JPEG2000.jpeg .jpg .jpe .jp2
Portable Network Graphics.png
WebP.webp
Sun rasters.sr .ras
TIFF.tiff .tif
OpenEXR Image.exr
Radiance HDR.hdr .pic

データ型

OpenCV で読み込まれた画像のデータは配列として保存される。グレースケール画像の場合は、1 ピクセルに、黒色の明るさ(輝度;depth)が 1 つの値として保存される。この場合、色相として黒だけを使用しているので 1 チャンネルになる。また、輝度は、精度に応じて決めることができる。例えば、輝度を 255 段階調整できるようにするには 8-bit 型を使い、より高精度が必要な場合は 16-bit 型、32-bit 型や 64-bit 型を使用する。BGR カラー画像の場合は、1 ピクセルに青・緑・赤の 3 つの値を保存しておく必要があるので、3 チャンネルが必要になる。カラー画像の場合も、青・緑・赤の 3 色それぞれに対して輝度を調整できるようになる。

OpenCV では輝度の値域(depth)を定数として表している。8-bit の画像の場合は CV_8U、36-bit の画像の場合は CV_32F のように表している。Python を介して OpenCV を使うとき、 OpenCV 型が NumPy の型として表示される。例えば 8-bit ならば np.unit8、32-bit ならば np.unit32 などのように表される。

OpenCV で画像を読み込むとき、imread は読み込みモード(IMREAD_COLOR など)により読み込むチャンネル数を調整し、また画像の特徴に応じて輝度の値を調整している。16-bit あるいは 32-bit の画像の場合は CV_16F あるいは CV_32F として読み込まれるが、それ以外の場合は CV_8U として読み込まれる。OpenCV で読み込まれた画像の縦、横、チャンネル数、depth は、次のようにして確認できる。

ミチタネツケバナの写真
import cv2

img = cv2.imread('./data/chirsuta_1_w1024.jpg', cv2.IMREAD_COLOR)

height, width, channel = img.shape
data_type = img.dtype

print(height)
## 1052

print(width)
## 1024

print(channel)
## 3

print(data_type)
## unit8

b_channel = img[:, :, 0]
g_channel = img[:, :, 1]
r_channel = img[:, :, 2]

print(b_channel)
## [[48 43 42 ... 55 51 48]
##  [48 48 48 ... 48 48 52]
##  [47 51 51 ... 46 47 58]
##  ...
##  [18 13 35 ... 55 58 79]
##  [14  6 60 ... 58 62 87]
##  [19  0 66 ... 74 77 98]]

画像ファイルの保存

画像ファイルを保存するには、imwrite メソッドを使用する。このメソッドの第 1 引数にはファイル名、第 2 引数には保存したいオブジェクトを指定する。imwrite は、与えられたファイル名の拡張子から、画像のフォーマットを推定して、保存してくれる。

import cv2
img = cv2.imread('sample.jpg', cv2.IMREAD_COLOR)

cv2.imwrite('sample.jpg', img)

画像データをファイルに保存するとき、例えば JPEG ならば、その圧縮率を指定することができる。次のサンプルコードは、圧縮率を 90% に設定する例である。

import cv2
img = cv2.imread('sample.jpg', cv2.IMREAD_COLOR)

cv2.imwrite('sample.jpg', img, [int(cv2.IMWRITE_JPEG_QUALITY), 90])

JPEG のほかに、PNG の場合は IMWRITE_PNG_COMPRESSION、WebP の場合は IMWRITE_WEBP_QUALITY を用いて圧縮率を指定することができる。

対応フォーマット

画像オブジェクトの depth によってファイルに書き出せるフォーマットが異なる。ほとんどの場合、PNG、JPEG、TIFF に対応できる。一部、透明チャンネルを持った画像では PNG のみに書き出しができる。