KURORO BLOGのロゴ

このエントリーをはてなブックマークに追加
OpenCVで使われるimreadとは?使い方から配列が画像になる仕組みを解説

OpenCVで使われるimreadとは?使い方から配列が画像になる仕組みを解説

今回はOpenCVで使われるimreadに関して、使用法から配列が画像になる仕組み等、徹底解説いたしました。配列が画像になる仕組みを知りたい、なんとなくimreadを使っていた方へおすすめです。ぜひ最後までご確認ください。

目次
  1. そもそもOpenCVで使われるimreadとは?
    1. なぜ多次元配列にするの?
  2. OpenCVで使われるimread関数の定義
    1. imread関数を用いて、グレースケールで画像を読み込む際の注意点
  3. OpenCVで使われるimread関数を利用する際の注意点【2点】
    1. imread関数から例外を返すことはない
    2. imread関数を利用してうまく画像が読み込めない
  4. まとめ
  5. 参考文献
目次を開く⬇︎

そもそもOpenCVで使われるimreadとは?

OpenCVで使われるimreadとは、画像ファイルを読み込んで、多次元配列(numpy.ndarray)にするものを意味します。

なぜ多次元配列にするの?

それでは、なぜ画像を多次元配列へ変換するのでしょう?

画像を多次元配列へ変更する理由としては、

  • カラー画像など、精度が求められる画像に対して、極め細かく画像を表示するため。
  • OpenCV内に含まれる、関数の処理を容易にするため。
  • 画像の加工や書き出しなどの演算処理を、高速化するため。

が挙げられます。

確かに画像の加工や書き出しなどの結果が遅いと、実運用を考える場合に、悩みの種になりそうなので、高速化は必要ですね。

OpenCVで使われるimread関数の定義

imread関数は、

1# cv2(OpenCV)を利用する宣言を行う。
2import cv2
3
4# imread : 画像ファイルを読み込んで、多次元配列(numpy.ndarray)にする。
5# 第一引数 : 画像のファイルパス
6##################
7# 第二引数(任意) : 画像の形式を指定。
8# cv2.IMREAD_COLOR or 1を指定する場合 : (画像をカラー(RGB)で読み込む。 第二引数を指定しない場合にも選ばれる。デフォルト。)
9# RGBとは? : https://ja.wikipedia.org/wiki/RGB
10# cv2.IMREAD_UNCHANGED or -1を指定する場合 : (画像をカラー(RGB)に透過度を加えた形式(RGBA)で読み込む。)
11# RGBAとは? : https://japan.zdnet.com/glossary/exp/RGBA/?s=4
12# 透過度(透過率)とは? : https://www.kenko-tokina.co.jp/faq/0073.html#:~:text=%E3%80%8C%E9%80%8F%E9%81%8E%E7%8E%87%E3%80%8D%E3%81%AF%E3%80%81%E3%82%AC%E3%83%A9%E3%82%B9,%E3%81%A8%E3%81%84%E3%81%86%E3%81%93%E3%81%A8%E3%81%AB%E3%81%AA%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82
13# cv2.IMREAD_GRAYSCALE or 0を指定する場合 : (画像をグレースケールで読み込む。)
14# グレースケールとは? : https://www.shinkohsha.co.jp/blog/monochrome-shirokuro-grayscale/
15################## 
16##################
17# 戻り値 
18# cv2.IMREAD_COLOR or 1を指定した場合 : 行(高さ) x 列(幅) x 色の三次元配列(numpy.ndarray)が返される。
19# cv2.IMREAD_UNCHANGED or -1を指定した場合 : 行(高さ) x 列(幅) x 色の三次元配列(numpy.ndarray)が返される。
20# cv2.IMREAD_GRAYSCALE or 0を指定した場合 : 行(高さ) x 列(幅)の二次元配列(numpy.ndarray)が返される。
21# ファイルが存在しない場合や例外が発生した場合等 : None
22##################
23# ※ 行(高さ) x 列(幅)の二次元配列(numpy.ndarray, グレースケール)画像を保存して、再度cv2.imread()の第二引数で(cv2.IMREAD_COLOR or 1 もしくは cv2.IMREAD_UNCHANGED or -1)を指定して画像を読み込むと、行(高さ) x 列(幅) x 色の三次元配列(numpy.ndarray)が返されます。
24img = cv2.imread('./xxx.xxx')

で定義されます。

例えば以下のようなコードを作成すると、

1import cv2
2
3# imread : 画像ファイルを読み込んで、多次元配列(numpy.ndarray)にする。
4# 第一引数 : 画像のファイルパス
5# 戻り値 : 行 x 列 x 色の三次元配列(numpy.ndarray)が返される。
6img = cv2.imread('./xxx.xxx')
7
8# shape : 画像の形状を返す。
9# (列数, 行数, チャンネル数)
10# チャンネルとは? : http://www.cg-ya.net/2dcg/aboutimage/basic-knowledge-degitalimage/
11# (例) : (382, 640, 3)
12print(img.shape)
13
14# 三次元配列を返す。
15# (例)
16# [
17# [
18# [234 237 228]
19# ...
20# [202 209 194]
21# ]
22# [
23# [10 27 16]
24# ...
25# [36 67 46]
26# ]
27# [
28# [34 51 40]
29# ...
30# [50 81 60]
31# ]
32# ]
33# [34 51 40], [50 81 60]などは、色の状態(BGR)を表します。
34# ※ 左からBGR[B, G, R]形式を表しています。左からRGB[R, G, B]形式でないことをご注意ください。
35# BGRに関する公式ドキュメント : https://docs.opencv.org/4.5.2/d4/da8/group__imgcodecs.html#ga288b8b3da0892bd651fce07b3bbd3a56
36print(img)
37
38# 色の状態(BGR)のBの部分を255(白色)にする。
39# : の意味 : 「全ての」を表す。
40# 参考 -> https://qiita.com/ken_yoshi/items/4cbe3abb7d46c5252fdd
41img[:, :, (0)] = 255
42
43# imwrite : 画像の保存を行う関数
44# imwriteについて : https://kuroro.blog/python/i0tNE1Mp8aEz8Z7n6Ggg/
45# 第一引数 : 保存先の画像ファイル名
46# 第二引数 : 多次元配列(numpy.ndarray)
47cv2.imwrite('./output.jpg', img)

以下の画像のように画像を描画します。

print(img)で出力される三次元配列からどのように画像が作られているのか、イメージ画像

imwriteに関しては、OpenCVで使われるimwriteとは?imwriteの定義から使用例をご紹介でまとめていますので、詳しく知りたい方は是非ご確認ください。

imread関数を用いて、グレースケールで画像を読み込む際の注意点

先ほどは「OpenCVで使われるimread関数の定義」に関して解説いたしました。

解説する中で、imread関数の第二引数へcv2.IMREAD_GRAYSCALE or 0を追加すると、グレースケールで画像を読み込めることをお伝えしました。

しかし厳密にグレースケールの画像を利用したい場合は、cvtColor関数の活用をおすすめします。

なぜならOpenCVで実装された変換処理(関数)ではなく、OSによるコーデックに依存する変換処理が行われるためです。

引用 : When using IMREAD_GRAYSCALE, the codec's internal grayscale conversion will be used, if available. Results may differ to the output of cvtColor()

cvtColor関数を用いてグレースケールする場合は、こちらのコードをご利用ください。

1import cv2
2
3img = cv2.imread('./xxx.xxx')
4
5# cvtColor : 画像の色空間(色)の変更を行う関数。
6# cvtColorについて : https://kuroro.blog/python/7IFCPLA4DzV8nUTchKsb/
7# 第一引数 : 多次元配列(numpy.ndarray)
8# 第二引数 : 変更前の画像の色空間(色)と、変更後の画像の色空間(色)を示す定数を設定。
9# cv2.COLOR_BGR2GRAY : BGR(Blue, Green, Red)形式の色空間(色)を持つ画像をグレースケール画像へ変更する。
10img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
11
12# imwrite : 画像の保存を行う関数
13# imwriteについて : https://kuroro.blog/python/i0tNE1Mp8aEz8Z7n6Ggg/
14# 第一引数 : 保存先の画像ファイル名
15# 第二引数 : 多次元配列(numpy.ndarray)
16cv2.imwrite('./output.jpg', img)

cvtColorに関しては、OpenCVで使われるcvtcolorとは?cvtcolorの活用例を徹底紹介でまとめていますので、詳しく知りたい方は是非ご確認ください。

OpenCVで使われるimread関数を利用する際の注意点【2点】

最後にimread関数を利用する際の注意点として、

  • imread関数から例外を返すことはない
  • imread関数を利用してうまく画像が読み込めない

に関して、解説いたします。

imread関数から例外を返すことはない

imread関数で対応していない画像フォーマットや、存在しない画像ファイルパスを読み込んだ場合でも、imread関数から例外を返すことはありません。

imread関数を用いて正しく画像が読み込めているのか、確認するためにも以下のようなコードを記述しましょう。

1import cv2
2
3img = cv2.imread('./xxx.xxx')
4
5# 画像が正しく読み込めた場合
6if img:
7    print('img found')
8# 画像が正しく読み込めなかった場合
9else:
10    print('img not found')
11    exit()
12
13# 以下続きの処理

またimread関数で対応できる、画像フォーマットを事前確認しておくと、円滑に実装が進められます。

  • 【引用】以下 imread関数で対応している、画像フォーマット一覧
  • Windows bitmaps : *.bmp, *.dib (always supported)
  • JPEG files : *.jpeg, *.jpg, *.jpe (see the Note section)
  • JPEG 2000 files : *.jp2 (see the Note section)
  • Portable Network Graphics : *.png (see the Note section)
  • WebP : *.webp (see the Note section)
  • Portable image format : *.pbm, *.pgm, *.ppm *.pxm, *.pnm (always supported)
  • PFM files : *.pfm (see the Note section)
  • Sun rasters : *.sr, *.ras (always supported)
  • TIFF files : *.tiff, *.tif (see the Note section)
  • OpenEXR Image files : *.exr (see the Note section)
  • Radiance HDR : *.hdr, *.pic (always supported)
  • Raster and Vector geospatial data supported by GDAL (see the Note section)

imread関数を利用してうまく画像が読み込めない

imread関数を利用してうまく画像が読み込めない場合は、画像ファイルパスを書き間違えている可能性があります。

画像ファイルパスを指定する方法としては、

の2種類があり、どちらかをご利用ください。

カレントディレクトリ(現在のディレクトリ)の確認コード

1import os
2
3# カレントディレクトリ(現在のディレクトリ)をprintする。
4print(os.getcwd())

まとめ

  • OpenCVで使われるimreadとは、画像ファイルを読み込んで、多次元配列(numpy.ndarray)にするものを意味する。
  • 画像を多次元配列へ変更する理由としては、以下3点があげられる。
  • カラー画像など、精度が求められる画像に対して、極め細かく画像を表示するため。
  • OpenCV内に含まれる、関数の処理を容易にするため。
  • 画像の加工や書き出しなどの演算処理を、高速化するため。

参考文献