2.画像の簡単操作
                   OpenCV入門  目次 ← 前 次→

2.1 画像を表す変数と画像生成

 OpenCVでは,画像はMat型変数で表現されます。Matという名前は matrix、つまり行列の略です。


2.1.1 濃淡画像の生成

 濃淡画像とは、色はなく、明るさ情報しか持たない画像のことで、白黒写真、グレー画像、明度画像などと呼ばれることがあります。
OpenCVでは、画像の行数、列数と一画素のデータ型を指定して、新しい画像を宣言します。

 画像を行列として表現するために、画像の縦幅=行数、横幅=列数 になります。プログラムの中で、次のように画像変数を宣言
します。

  Mat 新しい画像変数名(縦幅, 横幅, CV_8UC1);

或いは、
  Mat 新しい画像変数名 = Mat(縦幅, 横幅, CV_8UC1);

CV_8UC1はOpenCVでは、8ビット、符号なし、1チャンネルのデータ、つまり、1個のunsigned char型のデータタイプを示す定数です。

例: 240行、320列の濃淡画像grey_imageを生成したいとき、下記のコードで行うことができます。
  Mat grey_image(240, 320, CV_8UC1);
或いは、
  Mat grey_image = Mat(240, 320, CV_8UC1);


2.1.2 カラー画像の生成
 カラー画像は、一画素にR,G,Bの三原色の明るさが入っています。

カラーを生成する場合、次のようにします。
  Mat 新しい画像変数名(縦幅, 横幅, CV_8UC3);
或いは、
  Mat 新しい画像変数名 = Mat(縦幅, 横幅, CV_8UC3);

  CV_8UC3はOpenCVでは、8ビット、符号なし、3チャンネルのデータ、つまり、3個のunsigned char型の要素の配列を示す定数です。

例: 480行、640列の濃淡画像color_imageを生成したいとき、下記のコードで行うことができます。
  Mat color_image(480, 640, CV_8UC3);
或いは、
  Mat color_image = Mat(480, 640, CV_8UC3);


2.2 画像の情報の所得

 仮にある画像がMat型の変数imageで表現されているとすると,その画像の横幅、縦幅の情報が次のように取得します。

  int width = image.cols, height = image.rows;

  cols: columns、つまり列の数を意味 し、rowsは行数を意味します。


2.3 画素値の取得

 ある濃淡画像 grey_image と カラー画像 rgb_image があると仮定します。

● 濃淡画像の画素値の読出し
 grey_imageの位置が(x,y)にある画素の値は次のように得ることができます。

      int p = grey_image.at<uchar>(y, x);

 カラー画像の画素値の読出し
 同様に、rgb_imageの位置が(x,y)にある画素の値(red, green, blue)は 次のように得ることができます。

  Vec3b
p = rgb_image.at<Vec3b>(y, x);
  int blue   = p(0);
  int green = p(1);
 
int red     = p(2);

2.4 画素値の設定

● 濃淡画像の画素値の設定
 grey_imageの位置が(x,y)にある画素の値を100に設定したい場合、次のようにします。

   grey_image.at<uchar>(y, x) = 100;

 カラー画像の画素値の設定
 同様に、rgb_imageの位置が(x,y)にある画素の値を赤=10緑=20青=30に設定した い時、次のようにします。
 Vec3b p=Vec3b(302010);
 
  rgb_image.at<Vec3b>(y, x) = p;

或いは
 
rgb_image.at<Vec3b>(y, x) = Vec3b(302010);

2.5 画像 ファイルの読出し
 画像ファイルから画像を呼び出して、Mat型変数に代入するために、imread関数を使います。imread関数の戻り値の型はMatで、
一つ目の引数は読み出したい画像ファイルの名前を表す文字列で、2つ目の引数は画像ファイルの読み出し方を指定する定数です。
例えば、画像ファイルの名前は "my.jpg"を読みだして、Mat型変数imgに代入したいとき、次のようにします。

  Mat img = imread("my.jpg", CV_LOAD_IMAGE_UNCHANGED);

画像ファイルには、濃淡画像やカラー画像がありますが、
◎ 濃淡画像を濃淡画像とし、カラー画像をカラー画像として読み込みたいとき、
                                                                              2番めの引数を CV_LOAD_IMAGE_UNCHANGED に
● どんな場合でも、濃淡画像として読み込みたいとき、   2番めの引数を CV_LOAD_IMAGE_GRAYSCALE に
 どんな場合でも、カラー画像として読み込みたいとき、 2番めの引数を CV_LOAD_IMAGE_COLOR            に
指定します。

 画像の読出しという処理は、失敗する場合があります。指定したファイルは画像ファイルでなかったり、或いは存在しないとき、
imreadが失敗します。画像読み込みの失敗の判定は、読み込んだ画像を表す変数に、画像データがちゃんと入っているかを
チェックすれば分かります。
 次の例では、失敗したら、エラーメッセージを表示するコードを示します。
  if (img.data == 0) {
    printf("my.jpgの読み込みに失敗\n");
  }

2.6 画像を画像ファイルに保存する

 Mat型変数で表す画像を画像ファイルに保存するとき、imwrite関数を使います。imwriteに2つの引数があり、一つ目は画像ファイ ル名で、2つ目の引数は保存したい画像を表すう変数です。

 例:Mat型変数 image で表す画像を "My_Image.jpg" という名前のファイルに保存したいとき、次のようなコードを書きます。

   imwrite("My_Image.jpg",  image);
2.7 画像の 全ての画素値を設定する
 濃淡画像grey_imageの全ての画素の画素値を整数vにしたい場合、次のようにします。

    int v = 100;
   grey_image  = Scalar(v);
   // 或いは grey_image  = Scalar(100);

同様に、rgb_imageの全ての画素の画素値をrgbに設定したい時、次のよ うにします。
  int
b = 30;
  int g = 20;
  int
r = 10;

  rgb_image = Scalar(Vec3b(b, g, r));
  // 或いは rgb_image = Scalar(Vec3b(302010));

2.8 画像の全ての画素値に定数画素値を足す(引く)

濃淡画像grey_imageの全ての画素の画素値に
vを足した結果をnew_imageに保存したい場合、次のようにします。
    int v = 100;
   Mat new_image = grey_image  + Scalar(v);
   // 或いは new_image = grey_image  + Scalar(100);

同様に、rgb_imageの全ての画素の画素値
rgbを 足した結果をnew_rgbに保存したい時、次のようにします。
  int
b = 30;
  int g = 20;
  int
r = 10;
  Mat new_rgb = rgb_image + Scalar(Vec3b(b, g, r));
  // 或いは Mat new_rgb = rgb_image - Scalar(Vec3b(302010));

画素値を引く場合は同様にできます。

注意!
 上記の操作で得たのは、「飽和処理あり」の結果です。


2.9  画像の全ての画素値を定数倍にする

画像imageの全ての画素の画素値をk倍にし
た結果をnew_imageに保存したい場 合、次のようにします。
    double k = 0.5;
   Mat new_image = image  * k;
   // 或いは Mat new_image = image  * 0.5;


注意!
 上記の操作で得たのは、「飽和処理あり」の結果です。

2.10 画像同士の足算、引算

2枚の画像の対応する画素間の足算、引算を行い、結果を別の画像に保存したいとき、次のようにします。
     Mat image1 = image_a + image_b;
    Mat image2 = image_a - image_b;



注意!
 上記の操作で得たのは、「飽和処理あり」の結果です。

2.11 部分画像(部分矩形領域)

 画像の中の長方形領域だけを注目して処理したい時があります。例えば、画像の中の一部分を特別の色で塗りつぶしたり、その部分だけを別の画 像の指定する場所にコピーする時がある。この時、元の画像の部分画像を使うと便利です。
 ある画像の部分画像を指定するのに次のコードを書くと良いです。

 Mat 部分画像 = Mat(元画像, Rect(左上の角のX座標, 左上の角のY座標, 部分画像の横幅, 部分画像の縦幅));

注意: 部分画像は元の画像の指定した部分のコピーではなく、元の画像のその部分そのものです。つまり、部分画像の中身を改変すると、元の画 像の対応する部分が変化します。


2.12 画像の代入

 画像(Mat型変数)には代入演算子「=」があります。代入式の右のものの種類により、代入の「意味」が変わります。

● 画像1 = 画像2;
 この場合、画像1は画像2のコピーではない。画像1の中身は画像2と共有します。つまり、画像の中身は一つです。

● 画像1 = 画像の式;
 この場合、画像1は「画像の計算式の結果」のコピーです。
例: C = A + B; CはAとBの画素毎の和の結果画像です。

● 画像1 = 定数値;
 この場合、画像1はの全ての画素値は「定数値」になります。