2016. 7. 10.
2017. 9.24. OpenCV3.3.0とVisual C++ 2017で確認済み、このままで使用可
石立 喬

OpenCV3.1.0とVisual C++ 2015による画像処理と認識(2)

----- 原画像をRGB成分に分解してピクセル単位の画像処理をする -----

 画像処理には、画像の各ピクセルを個別に単独に変換するものと、注目するピクセルとその周辺のピクセルから総合的に結果を得るものとがある。前者は、画像反転、グレイスケール化、コントラスト変換などに用いられ、後者には、平滑化(ぼかし)、鮮鋭化、エッジ検出などへの応用がある。ここでは、前者について、画像をRGB成分に分解して処理し、再び画像に戻す方法を紹介する。
 ここに示す内容は、「OpenCVとVisual C++による画像処理と認識(2)」をOpenCV3.1.0とVisual C++ 2015で確認したものに過ぎず、説明を簡略化してあるので、理解を深めるためには、そちらも参照されたい。

ピクセルを単独に変換する画像処理の手順
◎原画像を読み込む
 原画像名をimage_srcとして、
  Mat image_src = imread("画像ファイル名")
を使用する。デフォルトでは、IMREAD_COLORが省略され、カラー画像として読み込まれる。グレイスケールとして読み込む場合には、
  imread("画像ファイル名", IMREAD_GRAYSCALE)
とする。画像のグレイスケール化は、読み込む際に、これを使用するだけでも実現できる。
◎処理後の画像を入れる場所を用意する
 原画像image_srcと同じサイズで同じタイプの画像で良い場合は、
  image_dst = image_src.clone()
で簡単に作れる。
◎原画像の任意座標位置のピクセルのRGB値を得る
 外部から,、Matクラスとして読み込んだ原画像image_srcから、任意座標位置のVec3b型ピクセル色データcolorを取得するには、
  Vec3b color = image_src.at<Vec3b>(y, x)
を使う。
 Vec3bは、テンプレートクラスのVec<uchar, 3>をtypedef(型定義)したもので、uchar型のRGB3チャンネルの値から成り、各チャンネルの値を得るには、
  r = image.at<Vec3b>(y, x)[2]
などを使う。RGBの順序が逆であることに注意されたい。添え字[0]はB(青)、[1]はG(緑)、[2]はR(赤)を抽出するのに用いられる。
◎上記RGB値を変換して、新しい処理後画像を構成する
 処理後画像をimage_dstとし、設定したい処理後のRGB値をr1、g1、b1とすると、
  image_dst.at<Vec3b>(y, x)[2] = r1
などで設定できる。
 画像反転(ネガ)の場合のように、
  r1 = 255 - r
を変換式とすると、
  image_dst.at<Vec3b>(y, x)[2] = 255 - image_src.at<Vec3b>(y, x)[2]
とすればよい。

プログラム
 図1は、OpenCV3.1.01用に作成したプログラムで、インクルードファイルの指定方法以外は、従来のOpenCV用と変わりはない(従来の、#include <openvv2/heighgui/heighgui.hpp>でもビルドでき、実行できる)。
27行は、すでに説明した反転(ネガ)用で、28行は、NTSCの式によりRGB値からグレイスケールの濃度を計算している。
 29行は、コントラストの強調用で、 画像のRGB各要素を、中間値128を中心に傾斜を1.5倍に高めている。
 例えば(Rの例では)、
  r1 = (r - 128) * 1.5 + 128 = 1.5 * r - 64
の式を用いる。rが大きい場合にはr1が255を超える恐れがあり、rが小さい場合には、r1が負になる場合もある。これらをunsined charの範囲に収めるには、OpenCVのテンプレート関数
  saturate_cast<uchar>
を用いる。これによれば、uchar型にキャストすると同時に、範囲外はクリップし、256以上は255に、負数は0に飽和(saturate)させてくれる。


図1 画像をRGBに分解し、RGB各値から新しいRGBを求め画像化する



図2 図1のプログラムの実行結果


結論
 画像処理の中では最も簡単な、ピクセル単位での変換を行った。OpenCV3.1.0になって変わったところは、インクルードファイルがopencv2/opencv.hppで良くなったことだけである。Matクラスによる画像の扱い方、画像処理手法の詳細については、過去のバージョンによる「OpenCVとVisual C++による画像処理と認識(2)」を参照されたい。








「Visual C++の勉強部屋」(目次)へ