デジタル画像と
簡単な画像処理2
Digital Image Processing 2013 4/1
OpenCVで画像処理のプログラムを
書こう
ここで,次の内容について学習する。
1.画像の表現
2.画像の生成
3.画素値の操作
4.画像の表示
5.画像の保存
Digital Image Processing 2013 4/2
1.
OpenCV
における画像の表現
Digital Image Processing 2013 4/3
OpenCVでは,一枚の画像を一つの「Mat」型変数で表現する。
新しい画像の生成:
変数の定義だけでは,画像を作ることはできない。
画像の「実体」を作る方法:
①
画像ファイルから入力する。
②
大きさと種類を指定して,新しい画像を作る。
2
画像の生成
Digital Image Processing 2013 4/4
①
画像ファイルから入力する方法
画像ファイルから画像を作るための関数は
Mat
imread
(const string&
ファイル名
, int flags);
この関数は,指定した名前の画像ファイルから,画像を読み込み,
読み込んだ画像を
Mat
型の値として返す。
第
2
引数の
flags
は,画像を入力するときの変換方法を指定し,実際
に使用できるのは下記の三つである。
CV_LOAD_IMAGE_UNCHANGED 無変換(画像ファイルの内容と同じ) CV_LOAD_IMAGE_GRAYSCALE 常に濃淡画像に変換する CV_LOAD_IMAGE_COLOR 常にカラー画像に変換する 注意: 画像形式上の変換である。つまり,1画素にR,G,Bの3つの値を持 たせる。濃淡画像に自動的に着色することはしない。Digital Image Processing 2013 4/5
Imread
関数の使用例:
1.“
sample.jpg”
という画像ファイルをそのまま読み込み、変数
image1
に代入する。
Mat image1 = imread(“sample.jpg”, CV_LOAD_IMAGE_UNCHANGED);
或いは、
Mat image1:
image1 = imread(“sample.jpg”, CV_LOAD_IMAGE_UNCHANGED);
2
.“
sample.png”
という画像ファイルを濃淡画像として読み込み、変数
image
2に代入する。
Mat image2 = imread(“sample.pngg”, CV_LOAD_IMAGE_GRAYSCALE);
或いは、
Mat image2:
image2 = imread(“sample.pngg”, CV_LOAD_IMAGE_GRAYSCALE);
Digital Image Processing 2013 4/6
読み込んだ画像の情報の取り出し
1.画像データの有無
画像データは Mat型変数名.dataに保存されている。 画像データは無いとき (例えば、存在しないファイル,間違ったファイル名の画像をimread関数で読むとき), Mat型変数名.data はNULLになる。 例: /* “sample.jpg”の画像ファイルを読み込む*/Mat image1 = imread(“sample.jpg”, CV_LOAD_IMAGE_UNCHANGED); /* 画像の読み込みは失敗したら、メッセッジを表示し、プログラムを終了させる” */
if (image1.data == NULL) { printf(“Can not read sample.jpg.¥n”);
exit(1); /* プログラムを終了させる関数。引数は整数の終了コード*/
Digital Image Processing 2013 4/7
画像の大きさ(縦、横幅)
,
種類
画像の縦幅(行): Mat型変数名.rows 画像の横幅(列):Mat型変数名.cols 画像のチャンネル数: Mat型変数名.channels() 濃淡画像の場合は「1」、カラー画像の場合は「3」 例: /* image1の縦幅、横幅を表示する*/printf("The size is %d X %d pixel¥n", image1.cols, image1.rows); /* image1の種類の判定と表示*/
if (image1.channels() == 1) printf("image1 is a grey image.¥n"); else if (image1.channels() == 3)
printf("image1 is a RGB color image.¥n");
Digital Image Processing 2013 4/8
②
大きさと種類を指定して,新しい画像を作る方法
指定した大きさ,種類の画像を新しく生成し,Mat型変数に代入するとき,Mat クラス(C++の概念で,C言語の構造体の拡張である)の構築子(constructor, Mat型の変数を作るための関数で、名前はMatである)を使って行う。 Mat型構築子に引数が3個あり,それぞれ「縦幅」、「横幅」、「種類」を指定する。 「縦幅」、「横幅」は整数で,単位は画素である。 「種類」の指定には、OpenCVで用意した定数を使う。 濃淡画像を作る時は CV_8U1 カラー画像を作る時は CV_8U3 を指定する。 例1:100行x200列の濃淡画像を作り変数yimgに代入する。Mat yimg = Mat(100, 200, CV_8U1);
或いは、
Mat yimg(100, 200, CV_8U1);
例2:240行x360列のカラー画像を作り変数rgbimgに代入する。
Mat rgbimg = Mat(240, 360, CV_8U3);
或いは、
Mat rgbimg(240, 360, CV_8U3);
3
画素値の操作
Digital Image Processing 2013 4/9
3.1
濃淡画素値の操作
濃淡画像の場合,座標が(x, y)の位置にある画素値は
Mat型変数.at<uchar>(y, x) を使って,unsigned char(符号なし文字型,8ビット の符号なし整数型)の変数と同じように使うことができる。
例1:image2の(30,40)の座標にある画素値の表示
printf(“image2(30, 40) = %d¥n", image2.at<uchar>(40, 30));
例2:image2の(30,40)の座標にある画素値2倍にして,画像の元の場所に代入
image2.at<uchar>(40, 30) = image2.at<uchar>(40, 30) * 2;
Digital Image Processing 2013 4/10
3.2
カラー画素値の操作
カラー画像の場合,座標が(x, y)の位置にある画素値は
Mat型変数.at<Vec3b>(y, x) を使って,Vec3b(3個の符号なし文字型要素から 構成される3次元ベクトル型)の変数と同じように使うことができる。
Vec3b型の整数i番目の要素は, Vec3b型変数(i)を使って,unsigned char型の 変数と同じように使うことができる。また,3個の要素からVec3b型のベクトルを作る 時,Vec3bの構築子を利用することができる。
例1:image3の(30,40)の座標にある画素値の表示
Vec3b pixel = image3.at<Vec3b>(40, 30);
printf(“Red=%d Green=%d Blue=%d¥n", pixel(2), pixel(1), pixel(0));
例2:image3の(30,40)の座標にある画素値2倍にして,画像の元の場所に代入
Vec3b pixel = image3.at<Vec3b>(40, 30);
image3.at<Vec3b>(40, 30) = Vec3b(pixel(0)*2, pixel(1)*2, pixel(2)*2);
例3:image3の(30,40)の座標にある画素値をimage4の(13,24)の座標に代入
image4.at<Vec3b>(24, 13) = image3.at<Vec3b>(40, 30);
Digital Image Processing 2013 4/11
3.3
画像コピーの例
Mat型変数の代入は,画像の「実体」を渡すことであり,つまり,代入先の画素値を 変えれば,元の画像の画素値も変わる。 画像のコピーを作りたい場合,コピー元と同じ種類,大きさの新しい画像を作り,元 の画像の内容(全ての画素)を新しい画像にコピーする必要がある。 例:image1をimage2にコピーする。int width = image1.cols, height = image1.rows, ch = image1.channels(); Mat image2;
if (ch == 1) {
image2 = Mat(height, width, CV_8U1); for (int y = 0; y < height; y++) {
for (int x = 0; x < height; x++) image2.at<uchar>(y,x) = image1.at<uchar>(y,x); }
}
else if (ch == 3) {
image2 = Mat(height, width, CV_8U3); for (int y = 0; y < height; y++) {
for (int x = 0; x < height; x++) image2.at<Vec3b>(y,x) = image1.at<Vec3b>(y,x); }
}
4
画像の表示
Digital Image Processing 2013 4/12
4.1
表示用のウィンドウの用意
OpenCVでは,画像を表示するために,namedWindows関数を使って表示用の ウィンドウを先に用意する必要がある。 namedWindow(ウィンドウタイトル, CV_WINDOW_AUTOSIZE); ウィンドウタイトルとは,ウィンドウの上に表示される文字列のことである。4.2
画像の表示
画像を表示するとき,imshow関数を使う。 imshow(ウィンドウタイトル,Mat型変数);5
画像の保存
Digital Image Processing 2013 4/13
Mat型変数表現される画像を画像ファイルに保存するとき,imwrite関数を使う。 imwrite(ファイル名, Mat型変数);
注意:imwriteは「画像ファイル名」の拡張子画像ファイルの形式を選択するために, 拡張子は間違ったり,省略したりすると,imwriteは失敗してしまう。
画像ファイル名の正しい例:
mypicture.jpg toyota.png cat.gif art.tif background.bmp 不適切のファイル名の例:
paper.doc note.txt test.tex figure.ai kouen.pptx
各画素の値
画素値
=
元の画素値
+
定数
効果:.画像は明るく(或いは暗く)なる
調整後の画素値 0 元の画素値 無変換画素値変換曲線
定数> 0 の場合: 画素値が増える ⇒画像が明るくなる 定数< 0 の場合: 画素値が減る ⇒画像が暗くなる 定数> 0 定数< 0画素値の変更1(足し算)
Digital Image Processing 2013 4/14
+50
+100
+150
注目-50
-100
-150
注目 無変換 k各画素の値
画素値
=
元の画素値
×
定数
効果:
明るいものは
より明るく(暗く)
なる
定数>1.0 定数< 1.0 定数> 1.0 の場合:画素値の大きいも のはより大幅に大きくなる ⇒ 明るい画素と暗い画素の差が大き くなる 定数< 1.0 の場合: 画素値の大きいも のはより大幅に小さくなる ⇒ 明るい画素と暗い画素の差が小さ くなる画素値の変更2(掛け算)
調整後の画素値 0 元の画素値画素値変換曲線
Digital Image Processing 2013 4/17
×
1.5
画素値を計算する際の注意事項
1.コンピュータは計算を素直に行う
繰上げはどこまでもでき、借りるのはいつでも可能 仮に,計算結果を保存するために,10数の2桁分しかない場合を考える。 コンピュータで計算すると、こうなる。 60 10 + 50 - 30 110 …999999980 ⇒ 10 ⇒ 80 画素値は一般的に,8桁の2進数で表現する。その範囲は0~255である。 したがって,画素値の計算でも上記の例の現象が発生する可能性がある。Digital Image Processing 2013 4/19
例:
画素値=
240 + 50
2
進数で表現すると
240
11110000
+
50
⇒ +
110010
290
1
00100010
溢れ!=2
=256
結果を画素に代入するとき、
溢れたものは「捨てられる」ために、
画素値
=
240 + 50 –
256 =
34
逆に小さくなった
!
8Digital Image Processing 2013 4/20
例:
画素値=
40
-
50
2
進数で表現すると
1+1
40
1 00101000
-
50
⇒ -
00110010
-10
11110110
上位から借りたもの=256
Digital Image Processing 2013 4/21
画素値の演算における
Overflow
の対処
計算結果を画素に代入する前に、
1)
Overflow
が起きているかを判断
2)
発生したら、画素が表現できる範囲内から計算結果
に最も近い値にする。
飽和処理
>
≤
≤
<
=
255
;
255
255
0
;
0
;
0
計算結果
計算結果
計算結果
計算結果
画素値
Digital Image Processing 2013 4/22