#stub

複数枚の画像から,各座標における最頻値を計算する方法. 主に,固定カメラで撮影されたビデオシーケンスから背景画像を計算する方法

CvSparseMat* cvCreateSparseMat(int dimensions, const int* sizes, int type)

疎な多次元行列CvSparseMat型を生成する.画像におけるcvCreateImage,(密な)行列におけるcvCreateMat

引数

返り値

サンプルコード

#geshi(c++,number){{ int dimensionSize[] = {256, 256, 256}; const int NUMBER_OF_DIMENSIONS = 3; IplImage *image = cvLoadImage(inputFileName[0]);

/*---生成---*/ CvSparseMat **histogram = new CvSparseMat* [image->width*image->height]; for(int i = 0;i < image->width*image->height;i++){

   // ピクセルごとにヒストグラム用のCvSparseMatを作成
   // typeがCV_16UC1なので,カウントは2byte=65536回までカウント可能
   histogram[i]	= cvCreateSparseMat(NUMBER_OF_DIMENSIONS, dimensionSize, CV_16UC1);

}

IplImage *background = cvCloneImage(image); cvReleaseImage(&image);

for(int frame = 0;frame < FRAME_LENGTH;frame++){

   image = cvLoadImage(inputFileName[frame]);
   
   /*---データ格納 ---*/
   for(int y = 0;y < image->height;y++){
   for(int x = 0;x < image->width;x++){
       // RGBの値を取得
       CvScalar color = cvGet2D(image, y, x);
       // RGBによる3次元座標を構築してdimensionSizeに格納
       for(int i = 0;i < NUMBER_OF_DIMENSIONS;i++){
           dimensionSize[i] = color.val[i];
       }
       // dimensionSizeで指定した座標(色)が過去何回現れたか取得
       // 1度も現れてない場合は0が返される
       CvScalar count = cvGetND(histogram[y*image->width+x], dimensionSize);
       // カウントアップ
       count.val[0]++;
       // 格納する
       cvSetND(histogram[y*image->width+x], dimensionSize, count); 
   }
   }
   cvReleaseImage(&image);

}

for(int y = 0;y < image->height;y++){ for(int x = 0;x < image->width;x++){

   // 内部のリスト構造のデータを手繰るためのイタレータ
   CvSparseMatIterator mat_iterator;
   // 初期化と同時に先頭ノードを返す関数
   // 各ピクセルごとに先頭ノードを得る
   CvSparseNode *node  = cvInitSparseMatIterator(histogram[y*image->width+x], &mat_iterator);
   CvSparseNode *head  = node;
   
   /*---リストを連結---*/
   for(;node != 0;node->next != NULL){
       // 疎行列内はリストが連結してるとは限らないので,
       // GetNextSparseNodeを使って次ノードを手繰る.
       node->next = cvGetNextSparseNode(&mat_iterator);
   }
   
   /*---ソーティング---*/
   // リスト構造をソーティングする関数を別途定義しておくこと
   // ここではマージソートを想定
   // headノードが指す番地は最頻値になる
   sort(head);
   
   /*---最頻値画像---*/
   // 最頻値を取得
   // 疎行列内の特定の座標の値を取得するdefine文 CV_NODE_VAL
   // unsigned int count = *(unsigned int*)CV_NODE_VAL(histogram[i], node);
   // 疎行列内の座標(この場合は色)を取得するdefine文 CV_NODE_IDX
   const int* index = CV_NODE_IDX(histogram[y*image->width+x], head);
   
   CvScalar color;
   for(int i = 0;i < NUMBER_OF_DIMENSIONS;i++){
       color.val[i] = index[i];
   }
   cvSet2D(background, y, x, color);

} }

/*---解放---*/ for(int i = 0;i < image->width*image->height;i++){

   cvReleaseSparseMat(&histogram[i]);

} delete [] histogram; }}

解説

生成

データ格納

リストを連結

ソーティング

最頻値画像

解放

メモリ使用量

実体ファイル

ジャンル:OpenCV:OpenCV 2.1準拠


*1 uchar*)(node) + (mat)->valoffset
*2 uchar*)(node) + (mat)->idxoffset

トップ   編集 凍結 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2011-01-17 (月) 12:37:32