About BBS

変形と置換

作成者: 上田悦子, 最終変更者: 怡土順一, 最終変更リビジョン: 342, 最終変更日時: 2007-10-14 23:39:34 +0900 (日, 14 10月 2007)

■ 変形

OpenCVのCXCOREリファレンス マニュアルのTransforms and Permutationsに分類される関数のうち,Transformsには,画像や配列の形状や構造を変えるための関数が用意されている. 特に,データのコピーなしにヘッダ情報を書き換える事でその形状を変化させている.

サンプル


画像形状の変形 cvReshape

データをコピーせずに,3チャンネル画像を各チャンネルデータを展開した1チャンネル画像に変形する

サンプルコード

#include <cv.h> #include <highgui.h> #include <stdio.h> int main (int argc, char **argv) { IplImage *src_img = 0; IplImage img_hdr, *dst_img; CvMat mat_hdr; // (1)画像を読み込む if (argc >= 2) src_img = cvLoadImage (argv[1], CV_LOAD_IMAGE_COLOR); if (src_img == 0) return -1; // (2)画像形状の変更を行う cvReshape (src_img, &mat_hdr, 1, 0); dst_img = cvGetImage (&mat_hdr, &img_hdr); printf ("src_img size:[ %d, %d ] data-pointer:[%p]\n", src_img->width, src_img->height, src_img->imageData); printf ("mat_hdr size:[ %d, %d ] data-pointer:[%p]\n", mat_hdr.width, mat_hdr.height, mat_hdr.data.ptr); // (3)結果を表示する cvNamedWindow ("src", CV_WINDOW_AUTOSIZE); cvNamedWindow ("dst", CV_WINDOW_AUTOSIZE); cvShowImage ("src", src_img); cvShowImage ("dst", dst_img); cvWaitKey (0); cvDestroyWindow ("src"); cvDestroyWindow ("dst"); cvReleaseImage (&src_img); return 1; }

// (1)画像を読み込む
コマンド引数で指定されたファイル名の画像(入力画像)をオープンし,関数 cvLoadImage()で読み込む.2番目の引数にCV_LOAD_IMAGE_COLORを指定することで, デプス8ビット,3チャンネルのカラー画像として読み込む.

// (2)画像形状の変更を行う
関数cvReshape()の3番目の引数で,チャンネル数を1に設定.4番根の引数に0を指定 することで,配列の行数(画像の高さに相当)を変えずに配列のサイズを変える. これは,配列の列数(画像の幅)を3倍する事を意味している.
cvReshape()はCvMat型のヘッダを返すため,関数cvGetImage()で,IplImage構造体のヘッダ に変換している.
この後のprintf文で出力される情報を確認すると,データへのポインタは同じである事がわかる.

// (3)結果を表示する
形状を変換した画像を表示し,何かキーが押されるまで待つ.

実行結果例


■ 置換

OpenCVのCXCOREリファレンス マニュアルのTransforms and Permutationsに分類される関数のうち, Permutationsには,データの置換による配列(画像)のマッピングや反転などを行なう基本的な関数が 用意されている.

サンプル


タイリング cvRepeat

画像のタイリングを行なう

サンプルコード

#include <cv.h> #include <highgui.h> #include <stdio.h> int main (int argc, char **argv) { IplImage *src_img = 0; IplImage *dst_img; // (1)画像を読み込む if (argc >= 2) src_img = cvLoadImage (argv[1], CV_LOAD_IMAGE_COLOR); if (src_img == 0) return -1; // (2)出力画像領域を作成し,入力画像をタイリングする dst_img = cvCreateImage (cvSize (384, 512), IPL_DEPTH_8U, 3); cvRepeat (src_img, dst_img); // (3)結果を表示する cvNamedWindow ("src", CV_WINDOW_AUTOSIZE); cvNamedWindow ("dst", CV_WINDOW_AUTOSIZE); cvShowImage ("src", src_img); cvShowImage ("dst", dst_img); cvWaitKey (0); cvDestroyWindow ("src"); cvDestroyWindow ("dst"); cvReleaseImage (&src_img); cvReleaseImage (&dst_img); return 1; }

// (1)画像を読み込む
コマンド引数で指定されたファイル名の画像(入力画像)をオープンし,関数 cvLoadImage()で読み込む.2番目の引数にCV_LOAD_IMAGE_COLORを指定することで, デプス8ビット,3チャンネルのカラー画像として読み込む.

// (2)出力画像領域を作成し,入力画像をタイリングする
関数cvCreateImage()によって,幅384,高さ512の画像領域を生成する. 生成した画像に対して,関数cvRepeat()を用いて入力画像をタイリングする.

// (3)結果を表示する
処理された画像を実際に表示し,何かキーが押されるまで待つ.

実行結果例

入力画像(256x192)が出力画像(384x512)より小さい場合

入力画像(512x384)が出力画像(384x512)より幅が大きい場合


画像の反転 cvFlip(1)

画像の垂直・水平・両軸反転を行う

サンプルコード

#include <cv.h> #include <highgui.h> int main (int argc, char **argv) { IplImage *src_img = 0; IplImage *dst_img_1, *dst_img_2, *dst_img_3; // (1)画像を読み込み,同じサイズの出力画像を用意する if (argc >= 2) src_img = cvLoadImage (argv[1], CV_LOAD_IMAGE_COLOR); if (src_img == 0) return -1; dst_img_1 = cvCloneImage (src_img); dst_img_2 = cvCloneImage (src_img); dst_img_3 = cvCloneImage (src_img); // (2)画像の水平軸反転・垂直軸反転・両軸反転を行う cvFlip (src_img, dst_img_1, 0); cvFlip (src_img, dst_img_2, 1); cvFlip (src_img, dst_img_3, -1); // (3)結果を表示する cvNamedWindow ("src", CV_WINDOW_AUTOSIZE); cvNamedWindow ("dst_1", CV_WINDOW_AUTOSIZE); cvNamedWindow ("dst_2", CV_WINDOW_AUTOSIZE); cvNamedWindow ("dst_3", CV_WINDOW_AUTOSIZE); cvShowImage ("src", src_img); cvShowImage ("dst_1", dst_img_1); cvShowImage ("dst_2", dst_img_2); cvShowImage ("dst_3", dst_img_3); cvWaitKey (0); cvDestroyWindow ("src"); cvDestroyWindow ("dst_1"); cvDestroyWindow ("dst_2"); cvDestroyWindow ("dst_3"); cvReleaseImage (&src_img); cvReleaseImage (&dst_img_1); cvReleaseImage (&dst_img_2); cvReleaseImage (&dst_img_3); return 1; }

// (1)画像を読み込み,同じサイズの出力画像を用意する
コマンド引数で指定されたファイル名の画像(入力画像)をオープンし,関数cvLoadImage()で読み込む. また,反転後の画像を保存するために3つの画像領域を生成する.

// (2)画像の水平軸反転・垂直軸反転・両軸反転を行う
関数cvFlip()によって,画像の反転を行なう. 3番目の引数に0を指定し水平軸反転を,1(>0)を指定し垂直軸反転を, -1(<0)を指定し両軸反転を行う.

// (3)結果を表示する
処理された画像を実際に表示し,何かキーが押されるまで待つ.

実行結果例

入力画像 水平軸反転 垂直軸反転 両軸反転


ROIを利用した画像の部分反転 cvFlip(2)

ROIを利用して画像の一部分に対して垂直・水平・両軸反転を行う

サンプルコード

#include <cv.h> #include <highgui.h> int main (int argc, char **argv) { int w, h; IplImage *src_img = 0; IplImage *dst_img; // (1)画像を読み込み,入力画像をコピーした出力画像を用意する if (argc >= 2) src_img = cvLoadImage (argv[1], CV_LOAD_IMAGE_COLOR); if (src_img == 0) return -1; dst_img = cvCloneImage (src_img); // (2)出力画像にROIをセットし各部に対して水平軸反転・垂直軸反転・両軸反転をインプレースモードで行う w = dst_img->width / 2; h = dst_img->height / 2; cvSetImageROI (dst_img, cvRect (w, 0, w, h)); cvFlip (dst_img, NULL, 0); cvSetImageROI (dst_img, cvRect (0, h, w, h)); cvFlip (dst_img, NULL, 1); cvSetImageROI (dst_img, cvRect (w, h, w, h)); cvFlip (dst_img, NULL, -1); cvResetImageROI (dst_img); // (3)結果を表示する cvLine (src_img, cvPoint (0, h), cvPoint (src_img->width - 1, h), CV_RGB (255, 0, 255), 2, 8, 0); cvLine (src_img, cvPoint (w, 0), cvPoint (w, src_img->height - 1), CV_RGB (255, 0, 255), 2, 8, 0); cvNamedWindow ("src", CV_WINDOW_AUTOSIZE); cvNamedWindow ("dst", CV_WINDOW_AUTOSIZE); cvShowImage ("src", src_img); cvShowImage ("dst", dst_img); cvWaitKey (0); return 1; }

// (1)(1)画像を読み込み,入力画像をコピーした出力画像を用意する
コマンド引数で指定されたファイル名の画像(入力画像)をオープンし,関数cvLoadImage()で読み込む. また,処理用の画像として入力画像のコピーを生成する.

// (2)出力画像にROIをセットし各部に対して水平軸反転・垂直軸反転・両軸反転をインプレースモードで行う
画像を4分割し,最初に右上の領域をROIとしてセットする. 続いて関数cvFlip()の2番目の引数にNULLを指定し,3番目の引数に0を指定することで, セットしたROI領域に対してインプレースモードで部分的な水平軸反転を行う.
続いて同様の方法でに,左下領域,右下領域に対してそれぞれ垂直軸反転(第3引数に1を指定), 両軸反転(第3引数に-1を指定)を行う.
最後にcvResetImageROI()で,ROIを解放する.

// (3)結果を表示する
入力画像の4分割の領域を表示するために,入力画像src_img上にcvLine()で水平・垂直線分を描画する. 処理された画像を実際に表示し,何かキーが押されるまで待つ.

実行結果例

入力画像(分割領域を表示)と部分反転を行なった出力画像

OpenCV-1.0 リファレンス マニュアル
OpenCV-1.1pre リファレンス マニュアル
OpenCVサンプルコード


画素値の直接操作
部分画像のシャッフル
画像の連結
画像のコピー
画像形状の変形
タイリング
画像の反転
逆行列(擬似逆行列)の計算
色空間の写像
離散フーリエ変換
階層構造を持つ輪郭の座標取得
図形の描画
ポリゴンの描画
凸ポリゴンの描画
テキストの描画
IplImage構造体情報の保存
マップのシーケンスを保存
IplImage構造体情報の読み込み
マップのシーケンスを読み込む
K-means法によるクラスタリング
クラスタリングによる減色処理
エッジの検出
コーナーの検出
並進移動のためのピクセルサンプリング
回転移動のためのピクセルサンプリング
画像のサイズ変更
画像のアフィン変換(1)
画像のアフィン変換(2)
画像の透視投影変換
全方位画像の透視投影変換
モルフォロジー変換
平滑化
ユーザ定義フィルタ
境界線の作成
画像の二値化
画像の二値化(大津の手法)
画像ピラミッドの作成
画像ピラミッドを用いた画像の領域分割
平均値シフト法による画像のセグメント化
Watershedアルゴリズムによる画像の領域分割
輪郭の検出と描画
画像のモーメントを計算
ハフ変換による直線検出
ハフ変換による円検出
距離変換とその可視化
不要オブジェクトの除去
ヒストグラムの描画
ヒストグラム間の距離
二次元のヒストグラム
バックプロジェクションパッチ
ヒストグラムの均一化
テンプレートマッチング
形状のマッチング
点列を包含する矩形
輪郭領域の面積と輪郭の長さ
二つの矩形を包含する矩形
楕円のフィッティング
点列を包含する図形
動的背景更新による物体検出
snakeによる輪郭追跡(静止画)
オプティカルフロー1
オプティカルフロー2
オプティカルフロー3
Condensation
顔の検出
カメラキャリブレーション
歪み補正
マップを利用した歪み補正
サポートベクターマシン
画像の各ピクセル値を特徴ベクトルとしたSVMの学習
画像の各ピクセル値を特徴ベクトルとしたSVMによる物体検出
マウスイベントの取得
トラックバーの利用
カメラからの画像キャプチャ
動画としてファイルへ書き出す
ラベリング