HOG特徴量(Histograms of Oriented Gradients)


 HOGは,画像の局所領域から輝度勾配・輝度強度を取り出す特徴量です.物体の大まかな形状を表現可能です.一般に歩行者や人工物など,物体を検出するために使われています.HOGでは,輝度勾配ヒストグラム(物体の見えから得られる角度毎のヒストグラムのこと.画素ごとに得られます.)の対応する要素に,輝度強度を累積します.さらに,正規化処理によりヒストグラムの形状を整えるので,明るさの変化に対応可能であると言われております.ステップは以下に示します.

Step.0
局所領域をブロック・セルに分割(画像をブロックに分割します.さらにブロックを分割した領域がセルになります.)

Step.1
ブロックを移動.セルの中における輝度勾配ヒストグラムを計算する.

Step.2
ブロックごとに正規化する.

Step.3
全てのヒストグラムを統合して特徴量とする.

Step.1 と Step.2が繰り返し

参考文献

C++,OpenCVによる実装例


・HOGは一般的に学習器(SVM,AdaBoostなど)と組み合わせて使います.識別器を生成して認識します.

/*                      HOG特徴量                           */
// image:画像の配列
// width:画像の幅
// height:画像の高さ
// histogram_dimension:ヒストグラムの要素数
// cell_column:セルの列数(横方向に画像を何分割するか)
// cell_row:セルの行数(縦方向の画像を何分割するか)
// block_column:1ブロックの列数
// block_row:1ブロックの行数
// feature_vector:HOG特徴ベクトルの配列
// feature_vector_dimension:HOG特徴ベクトルの次元数
//histogram_dimension*block_column*block_row*(cell_row - block_row) * (cell_column - block_column)
void HOG(IplImage *image, int width, int height, int histogram_dimension, int cell_column, 
int cell_row, int   block_column, int block_row, float *feature_vector, int feature_vector_dimension)
{
   int x,y;     //繰り返し変数
   int bin;     //ビンの位置
   int cell_width = width / cell_column;  //セルサイズ(幅)
   int cell_height = height / cell_row;   //セルサイズ(高さ)
   int block_dimension = histogram_dimension * block_column * block_row; //ブロックの次元数
   float fu,fv;    
   float magnitude;     //輝度強度
   float direction;     //輝度勾配
   float norm;          //ノルム
   float epsilon = 1.0; //分母が0にならないように
   float *histogram;    //特徴ヒストグラム
   float *cell_feature_vector;  //セルのヒストグラム
   float *block_feature_vector; //ブロックのヒストグラム

   // ヒストグラムを計算する(対応する輝度勾配ヒストグラムのビンに強度を累積)
   histogram = new float [histogram_dimension];
   cell_feature_vector = new float [histogram_dimension * cell_row * cell_column];
   for (int i = 0; i < cell_row; i++) {
      for (int j = 0; j < cell_column; j++) {
         // セルごとにヒストグラムを計算する.
         memset(histogram, 0, histogram_dimension * sizeof(float));
         for (int v = 0; v < cell_height; v++) {
            y = i * cell_height + v;
            for (int u = 0; u < cell_width; u++) {
               x = j * cell_width + u;
               // 勾配強度・勾配方向を求める.
               if ((x > 0) && (x < width) && (y > 0) && (y < height)) {
                  fu = image->imageData[(image->width * y + (x + 1)) * 3] - image->imageData[(image->width * y + (x - 1)) * 3];
                  fv = image->imageData[(image->width * (y + 1) + x) * 3] - image->imageData[(image->width * (y - 1) + x) * 3];
                  magnitude = sqrt(fu * fu + fv * fv);   //輝度強度
                  direction = atan(fv / fu) + PI / 2.0;  //輝度勾配
                  // ヒストグラムに投票
                  bin = (int)floor( (direction * (180.0 / PI)) * ((float)(histogram_dimension - 1) / 180.0) );
                  histogram[bin] += magnitude;
               }
            }
         }
         for (int d = 0; d < histogram_dimension; d++) {
            cell_feature_vector[(d * cell_row + i) * cell_column + j] = histogram[d];
         }
      }  
   }
   delete [] histogram;   //不要なヒストグラムを解放
   // ブロックごとに正規化する
   block_feature_vector = new float [block_dimension];
   for (int i = 0; i < cell_row - block_row + 1; i++) {            //縦のセル数
      for (int j = 0; j < cell_column - block_column + 1; j++) {  //横のセル数
         for (int k = 0; k < block_row; k++) {               //ブロック数
            for (int l = 0; l < block_column; l++) {        //ブロック数
               for (int d = 0; d < histogram_dimension; d++) {
                  block_feature_vector[(d * block_row + k) * block_column + l] 
                = cell_feature_vector[(d * cell_row + (i + k)) * cell_column + (j + l)];
               }
            }
         }
         norm = 0.0;  //ノルムの初期化
         for (int d = 0; d < block_dimension; d++) {
            norm += block_feature_vector[d] * block_feature_vector[d];  //合計値を計算
         }
         for (int d = 0; d < block_dimension; d++) {
            //正規化処理
            feature_vector[(d * (cell_row - block_row + 1) + i) * (cell_column - block_column + 1) + j] 
           = block_feature_vector[d] / sqrt(norm + epsilon * epsilon);
         }
      }   
   }
   //ヒストグラムを解放
   delete [] cell_feature_vector;
   delete [] block_feature_vector;
}

・不備がある可能性があります.あらかじめご了承ください.





最終更新:2011年03月04日 19:13