c言語演習(2) - opencv

62
C言語演習(2) -OpenCVで画像処理 ‒ 2008-04-03

Upload: kosei-moriyama

Post on 18-Dec-2014

4.589 views

Category:

Technology


4 download

DESCRIPTION

OpenCVのイントロダクションとC言語の基礎(関数と構造体)について. 以前研究室の講義で使用してもので, 2008年当時の内容です.

TRANSCRIPT

Page 1: C言語演習(2) - OpenCV

C言語演習(2)

-OpenCVで画像処理 ‒2008-04-03

Page 2: C言語演習(2) - OpenCV

アジェンダ関数構造体 OpenCV• OpenCVとは•画像を読み込んで表示させる•四角形を描く•エッジ検出•テンプレートマッチング

Page 3: C言語演習(2) - OpenCV

関数

Page 4: C言語演習(2) - OpenCV

関数とは入力されたデータを加工し、出力するもの

printfやmainも関数

関数

入力 加工 出力

Page 5: C言語演習(2) - OpenCV

関数のメリット同じ処理を何度も書かなくてよい一度関数を作れば、何度も再利用できる

関数の中身の処理を気にしなくてもよい

Page 6: C言語演習(2) - OpenCV

例 二乗を返す関数”square”

関数名は”square” 整数nをうけとっている。 “return”で値を返す 返される値はint型

int square ( int n ){

return n*n;}

Page 7: C言語演習(2) - OpenCV

関数の書き方戻り値の型 関数名 ( 引数の宣言, 引数の宣言, … ){

処理}

引数は入力されるデータ(複数可)戻り値は出力する結果引数、戻り値がない場合もある•そのときは”void”

Page 8: C言語演習(2) - OpenCV

使い方

()の中に渡すデータ(引数)戻り値は代入(無視してもよい)

int main(void){int result;

result = square(5);

printf(“result is %d\n”, result);}

Page 9: C言語演習(2) - OpenCV

宣言

関数は使う前に宣言する

#include <stdio.h>

int square(int n); //宣言

int main(void){…

}

int square(int n) //関数本体{…

}

Page 10: C言語演習(2) - OpenCV

プロトタイプ宣言

関数の宣言のことを、プロトタイプ宣言という。

戻り値の型 関数名 (引数の宣言);

Page 11: C言語演習(2) - OpenCV

printfの宣言や本体はどこにある?

プロトタイプ宣言はヘッダファイル(stdio.h)に書かれている

本体はライブラリという別ファイルに書かれている

#include <stdio.h>

Int main(void){…

int printf(...); …

int printf(...){

…} …

stdio.h自作ファイル ライブラリ

Page 12: C言語演習(2) - OpenCV

構造体

Page 13: C言語演習(2) - OpenCV

構造体とはいろいろな変数を、一つにパッケージして、まとめて扱えるようにしたもの

Page 14: C言語演習(2) - OpenCV

例 座標をあつかう構造体struct point{int x; //x座標int y; //y座標

};

struct point pt1;

pt1.x = 5;pt1.y = pt1.x + 10;

printf(“%d, %d\n”, pt1.x, pt1.y);

Page 15: C言語演習(2) - OpenCV

定義の仕方struct 構造体名{変数の宣言};

構造体の中の変数のことを、メンバーという

メンバーはどのような型でもOK配列、構造体もメンバーにできる

Page 16: C言語演習(2) - OpenCV

使い方

struct 構造体の型名 名前;

“struct”を付けて、変数のように宣言する

名前.メンバー

メンバーにアクセスするときは、”.”を使う

Page 17: C言語演習(2) - OpenCV

構造体の入れ子struct st1{int n;int m;

};

struct st2{int l;struct st1 str;}

構造体の入れ子も可能今st2はメンバーにst1を持っている

Page 18: C言語演習(2) - OpenCV

構造体の入れ子struct st1 a;struct st2 b;

b.str = a;

b.str.n = 1;b.str.m = 2;

中の構造体のメンバーへアクセスするには、ドット演算子をつなげて書けばよい

Page 19: C言語演習(2) - OpenCV

OpenCV

Page 20: C言語演習(2) - OpenCV

OpenCVとは画像処理に便利な関数がたくさん入っているライブラリ•無料•インテルが作った•いろんな大学で使われている

Page 21: C言語演習(2) - OpenCV

画像処理人は、全ての情報の8割を視覚から得ている

よって、ロボット研究で画像をあつかうことは多い

Page 22: C言語演習(2) - OpenCV

画像を読み込んで表示させる

Page 23: C言語演習(2) - OpenCV

ヘッダファイル

OpenCVの関数を使うために読み込む

ほかには、”cxcore.h”や”cvaux.h”がある

#include “opencv/cv.h”#include “opencv/hightgui.h”

Page 24: C言語演習(2) - OpenCV

基本構造体

OpenCVでは、全ての画像を、この構造体であつかう

画像の幅、高さ、容量、色深度、チャンネル数、データ本体へのポインタなど、たくさんのメンバーを持つ

IplImage *img;

Page 25: C言語演習(2) - OpenCV

IplImageの中身typedef struct _IplImage{

int nSize; /* sizeof(IplImage) */int ID; /* バージョン (=0)*/int nChannels; /* OpenCV のほとんどの関数が,1,2,3および4チャンネルをサポートする */int alphaChannel; /* OpenCV では無視される */int depth; /* ピクセルの色深度のビット数 */char colorModel[4]; /* OpenCV では無視される */char channelSeq[4]; /* 同上 */int dataOrder; /* 0 - インタリーブカラーチャンネル.1 - 分離カラーチャンネル*/int origin; /* 0 - 左上原点, 1 - 左下原点(Windowsのビットマップ形式) */int align; /* 画像の行のアライメント(4 あるいは 8).OpenCV はこれを無視して,代わりにwidthStep を使用する. */int width; /* 画像のピクセル幅 */int height; /* 画像のピクセル高さ */struct _IplROI *roi;/* 画像 ROI.これが NULL でない場合,この特定の領域が処理の対象となる */struct _IplImage *maskROI; /* OpenCV では必ずNULL */void *imageId; /* 同上 */struct _IplTileInfo *tileInfo; /* 同上 */int imageSize; /* 画像データのバイトサイズ*/char *imageData; /* アライメントが調整された画像データへのポインタ */int widthStep; /* アライメントが調整された画像の行のバイトサイズ */int BorderMode[4]; /* 画像境界の設定.OpenCV では無視される */int BorderConst[4]; /* 同上 */char *imageDataOrigin; /* オリジナル画像データへのポインタ */

}IplImage;

Page 26: C言語演習(2) - OpenCV

画像の取り扱い グレイスケール• 色深度8ビット• 1チャンネル

赤:255緑:0青:0

赤:255緑:255青:0

赤:0緑:0青:0

明るさ:255

明るさ:235

明るさ:100

明るさ:0

カラー• 色深度8ビット

• 3チャンネル

Page 27: C言語演習(2) - OpenCV

画像の読み込み

画像を読み込み、基本構造体”img”に入れる。

CV_LOAD_IMAGE_UNCHANGEDは元画像の色を変更しないという意味。

img = cvLoadImage(“lena.jpg”,CV_LOAD_IMAGE_UNCHANGED);

Page 28: C言語演習(2) - OpenCV

ウィンドウの作成

読み込んだ画像を表示させるためのウィンドウを作る

名前は”result”

cvNamedWindow("result", 1);

Page 29: C言語演習(2) - OpenCV

読みこんだ画像の表示

”result”に読み込んだ画像を表示させる

cvShowImage("result", img);

Page 30: C言語演習(2) - OpenCV

キー入力待機、メモリ解放

何かキーが押されるまで待機する IplImageとウィンドウを使った場合は、必ず解放する

cvWaitKey(0);

cvReleaseImage(&img);cvDestroyWindow("result");

Page 31: C言語演習(2) - OpenCV

結果

Page 32: C言語演習(2) - OpenCV

四角形を描く

Page 33: C言語演習(2) - OpenCV

CvSize

画像の大きさをあつかうための構造体

typedef struct CvSize{int width; /* 矩形の幅 */int height; /* 矩形の高さ */}CvSize;

CvSize img_size = {640, 480};

Page 34: C言語演習(2) - OpenCV

CvPoint

座標をあつかうための構造体

typedef struct CvPoint{int x; /* x 座標 */int y; /* y 座標 */}CvPoint;

CvPoint pt1 = {50, 50};

原点 x

y

Page 35: C言語演習(2) - OpenCV

画像領域の確保

画像をあつかうためのメモリを確保する

IplImageを使うときは、このcvCreateImageやcvLoadImageなどで、必ず初期化しなければならない

img = cvCreateImage(img_size, IPL_DEPTH_8U,3);

Page 36: C言語演習(2) - OpenCV

真っ黒な画像をつくる

imgの全てのピクセルの値を、ゼロにする。

真っ黒な画像になる

cvSetZero(img);

Page 37: C言語演習(2) - OpenCV

四角形を描く

img上の座標”pt1”から、座標”pt2”まで、赤色で(CV_RGB)、太さ4ピクセルの四角形を描く

cvRectangle(img, pt1, pt2, CV_RGB(255, 0, 0),4, CV_AA, 0);

Page 38: C言語演習(2) - OpenCV

結果

Page 39: C言語演習(2) - OpenCV

エッジ検出

Page 40: C言語演習(2) - OpenCV

エッジ検出とは 画像の明るさが急激に変化した部分を検出する方法

画像の1次微分とも言う

Page 41: C言語演習(2) - OpenCV

Sobelオペレータある点とその周辺9ピクセルに、右の数を掛けて、その和を求める

明るさの変化がない点では、和は0になる

変化が大きい点では、和も大きな値になる

-1 0 1

-2 0 2

-1 0 1

Page 42: C言語演習(2) - OpenCV

計算例周りの明るさが一定だと、計算結果は0に近づく

この場合、50*1+50*2+50*1-50*1+50*2+50*1=0

50 50 50

50 50 50

50 50 50

Page 43: C言語演習(2) - OpenCV

計算例周りの明るさの変化が激しいと、計算結果は大きくなる

この場合、255*1+255*2+255*1-0*1+0*2+0*1=1020

255500

255500

255500

Page 44: C言語演習(2) - OpenCV

エッジ色の変わり目でのみ、値が極端に大きくなる

Page 45: C言語演習(2) - OpenCV

cvSobel

Sobelオペレータを用いて、一次微分画像を計算する

cvSobel(src_img, tmp_img, 1, 0, 3);

Page 46: C言語演習(2) - OpenCV

cvConvertScaleAbs

計算結果の値の範囲を、8ビット(0~255)に変換する

cvConvertScaleAbs(tmp_img, dst_img, 1, 0);

Page 47: C言語演習(2) - OpenCV

結果

Page 48: C言語演習(2) - OpenCV

テンプレートマッチング

Page 49: C言語演習(2) - OpenCV

テンプレートマッチングとは 画像の中から、テンプレートと同じ場所を探す処理

元画像 テンプレート 結果

Page 50: C言語演習(2) - OpenCV

結果保存用領域の準備

結果を保存するための領域を準備する

size = cvSize( src_img->width - tmp_img->width + 1, src_img->height - tmp_img->height + 1);

dst_img = cvCreateImage(size, IPL_DEPTH_32F, 1);

Page 51: C言語演習(2) - OpenCV

マッチングの方法画像の全領域を、テンプレートをスライドさせながら、順番に計算する

テンプレート

結果の個数は、

(元画像の横幅-テンプレートの横幅+1)*(元画像の縦幅-テンプレートの縦幅+1)

Page 52: C言語演習(2) - OpenCV

マッチングを計算

マッチング計算のアルゴリズムにはいくつか種類がある

今回はCV_TM_CCOEFF_NORMEDを使用

cvMatchTemplate (src_img, tmp_img, dst_img,CV_TM_CCOEFF_NORMED);

Page 53: C言語演習(2) - OpenCV

結果の取り出し

min_val, min_locには、最小値の値と座標、max_val, max_locには最大値の値と座標が入る

今回のアルゴリズムは、最もマッチングしている点が最大値をとるので、max_locを使う

cvMinMaxLoc (dst_img, &min_val, &max_val, &min_loc, &max_loc,NULL);

Page 54: C言語演習(2) - OpenCV

結果の描画

max_valには、最もマッチングした点の座標が入っている。この点はテンプレート画像の左上にあたる

よって、max_locから、max_locにテンプレート画像の幅と高さを足した点までの大きさの四角を描けばよい

cvRectangle(src_img, max_loc, cvPoint(max_loc.x + tmp_img->width, max_loc.y + tmp_img->height), CV_RGB(255, 0, 0), 3,CV_AA, 0);

Page 55: C言語演習(2) - OpenCV

結果

テンプレート画像

Page 56: C言語演習(2) - OpenCV

課題について

Page 57: C言語演習(2) - OpenCV

リファレンス 日本語リファレンスのサイトを参考にしながら、課題を行ってください

http://opencv.jp/opencv/document/

便利なので、必ずブックマークしておくこと

Page 58: C言語演習(2) - OpenCV

OpenCV プログラミングブック

初心者向け 生協にも売っている(¥3,570)

先のサイトと同じ作者

Page 59: C言語演習(2) - OpenCV

ssh

lunaの部分にマシン名を入れるパスワードは自分のパスワードでOK

$ ssh ‒X luna

username@luna’s passward: パスワードを入力

Page 60: C言語演習(2) - OpenCV

makefileコンパイルはメイクファイルを使うと便利

Page 61: C言語演習(2) - OpenCV

Makefileの作成

“TARGET=“には、作ったプログラムのファイル名(**.cの”**”の部分)をスペースで区切って列挙

“Makefile”という名前で、プログラムと同じディレクトリに保存する

CXXFLAGS+=`pkg-config opencv --cflags`LDFLAGS+=`pkg-config opencv --libs`

TARGET= filename1 filename2

all:  $(TARGET)

clean:rm -f *.o *̃ $(TARGET)

Page 62: C言語演習(2) - OpenCV

Makefileの作成

あとはターミナルに”make”と入れればコンパイルできる

時間のエラー(クロックのひずみを検出…)は無視してもよい

$ make