OpenCV画像特徴抽出学習5、HOG特徴検出アルゴリズム

1. HOG 勾配ヒストグラムの概要

 

配向勾配ヒストグラム (HOG) 機能は、密なグリッド内の配向勾配の正規化された局所ヒストグラムの計算に基づいています。この方法の基本的な考え方は、たとえ対応する勾配やエッジの位置が分からなくても、局所的なオブジェクトの外観と形状は、局所的な勾配やエッジの方向の分布によって適切に記述できるということです。実際の動作では、画像を小さなセル(セル)に分割し、セルごとに1次元の勾配方向(またはエッジ方向)のヒストグラムを蓄積して計算します。

照明と影に対する不変性を高めるには、ヒストグラムのコントラスト正規化が必要です。これは、セルをより大きなブロックにグループ化し、ブロック内のすべてのセルを正規化することで実現できます。正規化されたブロック記述子は HOG 記述子と呼ばれます。検出ウィンドウ内のすべてのブロックの HOG 記述子が結合されて最終的な特徴ベクトルが形成され、その後、SVM 分類器を使用した歩行者検出に使用されます。検出ウィンドウは重複するブロックに分割され、これらのブロックに対して HOG 記述子が計算され、形成された特徴ベクトルがターゲット/非ターゲットの二値分類のために線形 SVM に入力されます。検出ウィンドウは、すべての位置とスケールで画像全体をスキャンし、出力ピラミッドに対して非最大抑制を実行してオブジェクトを検出します。

================================================= =======================

2. 方向勾配ヒストグラム (HOG) 特徴アルゴリズムの一般的なプロセス:

1) HOG 特徴抽出手法は、画像、つまり検出対象またはスキャンされた形式をグレースケール化し、画像を R、G、B 色の 3 次元画像とみなします。 、RGB コンポーネントはグレースケール画像に変換されます。変換の数式は次のとおりです。

                                    グレー =0.33\cdot R+0.59\cdot G+0.11\cdot B

2) ガンマ補正方法を使用して入力画像の色空間を標準化 (正規化) します。目的は、画像のコントラストを調整し、画像内の局所的な影や照明の変化の影響を軽減し、同時に画像の色空間を抑制することです。ノイズの干渉。画像の照明が不均一な場合は、ガンマ補正を使用して画像全体の明るさを増減できます。実際には、ガンマは平方根と対数という 2 つの異なる方法で標準化できます。ここでは平方根法を使用します。式は次のとおりです (γ=0.5 の場合)。                                    

                                              Y\left ( x,y \right )= I\left ( x,y \right )^{\gamma }

3) 画像の各ピクセルの勾配 dx と dy (勾配のサイズと勾配の方向を含む) を計算します。主に輪郭情報を取得すると同時に、光の干渉をさらに弱め、X 方向を計算します。画像の勾配 dx と Y 方向の勾配 dy は、勾配計算の倍率と角度に従って、勾配を計算するときに、最初にガウスぼかしを適用し、ソーベル演算子または他の一次微分演算子を使用して勾配値 dx、dy を計算できます。 、グラデーションのサイズと方向:

 、

ソーベルの水平演算子と垂直演算子:

                             垂直方向=\begin{bmatrix} -1,&-2,&-1& \\ 0,&0,&0& \\1,&2,&1 \end{bmatrix} 

                            水平方向 =\begin{bmatrix} -1,&0,&1& \\ -2,&0,&2& \\-1,&0,&1 \end{bmatrix}

まず、sobel 演算子と水平方向勾配演算子を使用して元の画像に畳み込み演算を実行し、x 方向 (水平方向、右方向を正の方向とする) の勾配成分 gradscalx を取得します。次に、水平方向勾配を使用します。元の画像に畳み込みを実行する演算子。y 方向 (垂直方向、上を正の方向) に段階的に勾配成分を取得する積演算。次に、次の式を使用して、ピクセルのグラデーションのサイズと方向を計算します。

                               G_{x}\left ( x,y \right )=H\left ( x+1,y \right )-H\left ( x-1,y \right )

                               G_{y}\left ( x,y \right )=H\left ( x,y+1 \right )-H\left ( x,y-1 \right )

入力画像の画素点 (x, y) の水平方向の勾配、垂直方向の勾配、画素値をそれぞれ表し、画素点 (x, y) c における勾配の大きさと勾配の方向はそれぞれ次のとおりです。

                               G_{x,y}= \sqrt{G_{x}\left ( x,y \right )^{2}+G_{y}\left ( x,y \right )^{2}}

                               \alpha \left ( x,y \right )=tan^{-1}\left ( \frac{G_{x}\left ( x,y \right )}{G_{y}\left ( x,y \そうそう )

画像を 8x8 の小さなグリッドに分割し、各小さなグリッド内の画像の勾配方向ヒストグラムを作成します。各 8x8=64 ピクセルがセルであり、各セルを角度 (BIN) に従って 9 つのヒストグラム ブロックに分割します。セルを勾配方向でヒストグラムに重み付けして投影し、固定角度範囲にマッピングすると、セルの勾配方向ヒストグラムが得られ、これはセル内の対応する 9 次元特徴ベクトルです。たとえば、20° -40° と 200° ~ 220° は 1 つのヒストグラム ビンに分類されます。

                        

4)画像を小さなグリッドセルに分割し、グリッド単位ごとに勾配方向ヒストグラムを作成し、セルの勾配方向を 360 度の 9 方向ブロックに分割します。一般に、ブロック(Block)は複数のグリッドセルで構成され、セルは複数のピクセルで構成されます。歩行者検出のパラメータ設定が、2×2 セル/ブロック、8×8 ピクセル/セル、9 ヒストグラム チャネル (9 ビン)、セルのホッグ記述子ベクトルの長さが 9、およびセルの長さが 9 であると仮定します。ブロックの特徴ベクトルは 2×2×9=36 となるので、検出窓の HOG ベクトル長=105×4×9=3780 となります。

5)各セルの勾配ヒストグラム内の異なる勾配の数をカウントすることによって、各セルの記述子を形成することができ、各セルの勾配ヒストグラムを計算するとき、三線形補間を使用して計算速度を向上させることができる。各セル内の点は 3 次元ベクトルであると考えられます。\left ( x,y,\theta \right )                                                                                   

下の図からわかるように、元の画像サイズは 720×475 で、これを 64×128 ピクセルのサイズの画像にトリミングし、8×8 サイズの 128 個のグリッド セルに分割できます。グリッドセルは勾配ヒストグラムを計算します。サイズ 8×8 ピクセルのグリッド セルは、コンパクト/圧縮された表現を提供します。

画像では、各ピクセルには x 方向の勾配の大きさと勾配方向の方向の 3 つの要素が含まれます。つまり、8×8 ピクセルの画像には 8×8×3 = 192 個のピクセル値があり、3 つのチャネルが最大です。大きさの 1 を合計すると 8*8*2=128 になります。後で、これらの 128 の数値が 9 つのビンのヒストグラムを持つ 9 つの数値の配列としてどのように表現されるかを見ていきます。コンパクトな表現ができるだけでなく、イメージの表現にヒストグラムを使用すると、ノイズ対策も強化されます。グラデーションにはノイズが含まれる場合がありますが、ヒストグラムで表現されると、ノイズの影響をそれほど受けなくなります。

 

上の画像のサイズは 64×128 ピクセルで、8×8 ピクセル サイズの 128 個のグリッド セルに分割されており、画像全体の合計は 64/8 ×128/8 = 8*16=128 個のグリッドになります。

勾配の大きさと勾配の方向の 2 つのテーブルに従って、勾配の方向に従ってビンの位置を選択し、二次値に従ってビンのサイズを決定します。青い円内のピクセルは、勾配方向 80、対応する振幅 2 に対応します。対応するヒストグラムの 5 番目のビンに 2 を追加します。対応する勾配方向は 10、対応する振幅は 4 です。これは、角度 10 が次のとおりであるためです。 0 ~ 20 度の中間 (ちょうど半分) にあるため、振幅は比例効果サイズに従って 2 つに分割され、0 と 20 の 2 つのビンに配置されます。

角度が 160 度より大きい場合、角度は 160 度から 180 度の間となり、0 度と 180 度が等しくなるように角度が折り返されます。したがって、以下の例では、角度 165 度のピクセルが 0 度のビンと 160 度のビンに比例して寄与します。

0 ~ 180 のビンに多くの値が分布していることがわかります。これは、実際には、このグリッドの多くの勾配方向が上向きまたは下向きであることを意味します。各 8*8 セル内のすべてのピクセルを 9 ビンに追加して、9 ビン ヒストグラムを作成します。上記のグリッドに対応するヒストグラムは次のとおりです。

 

6)数セルごとにブロック(2×2セル/ブロックなど)を形成し、ブロック内の全セルの特徴記述子を直列に接続して、ブロックのHOG特徴記述子を得る。winSize(64,128)、blockSize(16,16)、blockStride(8,8)、cellSize(8,8)、nbins(9) という非常に重要なパラメーターがいくつかあり、ここではいくつかの概略図で表されています。

a) ウィンドウサイズ winSize (64,128)

b) ブロックサイズ blockSize (16,16)

 c) セルサイズ cellSize (8,8)

 Hog フィーチャー寸法の計算

HOGDescriptor* hog = newHOGDescriptor(cvSize(64, 48), cvSize(8, 6), cvSize(8, 6), cvSize(4, 3), 9);

上記の説明によれば、 cvSize(64,128) はウィンドウのサイズを表し、 cvSize(16, 16) はブロックのサイズを表し、 cvSize(8,8) はブロックストライドのサイズを表します。 cvSize(4, 4)セル サイズを表し、9 は各セル内の勾配ヒストグラムの数を表します。

ブロック (block) には A=(blockSize.width/cellSize.width)*(blockSize.height / cellSize.height)=128 グリッド (セル) が含まれていることがわかります。つまり、ブロック (block) には 9A=1125 のグラデーションが含まれています。ヒストグラム。ウィンドウは、B=((windowSize.width-blockSize.width)/(blockStrideSize.width)+1)* ((windowSize.height-blockSize.height)/(blockStrideSize.height)+1)= 105 ブロックで計算できます。 (ブロック) なので、ウィンドウには 9AB=3780 個の勾配ヒストグラムが含まれます。

2x2 の格子状の単位セルが大きなブロック (Block) に結合され、各ブロックの 1/2 が重複領域となります。主なことは、各セルのヒストグラムを大きなヒストグラム ベクトルにマージして、各ブロックが 36 個のベクトル記述子を持つようにすることです。各ブロックの記述子を正規化します。一般的な正規化プロセスは、L2 ノルムまたは L1 ノルムです。式は次のとおりです。

                                         L2 ノルム :f=\frac{v}{\sqrt{\begin{Vmatrix} v\\ \end{Vmatrix}_{2}^{2}+e^{2}}}

                                         L1 ノルム :f=\frac{v}{\begin{Vmatrix} v\\ \end{Vmatrix}_{2}+e}

7) 画像内のすべてのブロックの HOG 特徴記述子を直列に接続して、画像 (検出したいターゲット) の HOG 特徴記述子を取得します。これは、分類に使用できる最終的な特徴ベクトルです。

================================================= =======================

コード:

#include"stdafx.h"
#include <opencv2/opencv.hpp>
#include <iostream>
#include "math.h"
#include <opencv2/features2d.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

using namespace cv;
using namespace std;
//using namespace cv::features2d;

int main(int argc, char** argv) {
	Mat src = imread("F:/photo/h1.jpg");
	if (src.empty()) {
		printf("could not load image...\n");
		return -1;
	}
	namedWindow("input image", WINDOW_AUTOSIZE);
	imshow("input image", src);

	/*Mat dst, dst_gray;
	resize(src, dst, Size(64, 128));
	cvtColor(dst, dst_gray, COLOR_BGR2GRAY);
	HOGDescriptor detector(Size(64, 128), Size(16, 16), Size(8, 8), Size(8, 8), 9);

	vector<float> descriptors;
	vector<Point> locations;
	detector.compute(dst_gray, descriptors, Size(0, 0), Size(0, 0), locations);
	printf("number of HOG descriptors : %d", descriptors.size());
	*/
	HOGDescriptor hog = HOGDescriptor();
	hog.setSVMDetector(hog.getDefaultPeopleDetector());

	vector<Rect> foundLocations;
	hog.detectMultiScale(src, foundLocations, 0, Size(8, 8), Size(32, 32), 1.05, 2);
	Mat result = src.clone();
	for (size_t t = 0; t < foundLocations.size(); t++) {
		rectangle(result, foundLocations[t], Scalar(0, 0, 255), 2, 8, 0);
	}
	namedWindow("HOG SVM Detector Demo", WINDOW_AUTOSIZE);
	imshow("HOG SVM Detector Demo", result);

	waitKey(0);
	return 0;
}

画像処理効果:

歩行者の認識: 

歩行者の認識:

グレースケールの歩行者認識:

  

文章参考:Histogram of Oriented Gradients explained using OpenCV

おすすめ

転載: blog.csdn.net/weixin_44651073/article/details/128099635