【Python/OpenCV】HoG特徴+SVM識別器の作成

この記事では、Python版OpenCVでHoG特徴+SVM識別器(分類器・xmlファイル)を作成する方法をソースコード付きで解説します。

HoG特徴+SVM識別器の作成

HoG SVMは、物体検出に使われる識別器の1つです。
その名の通り、HoG特徴量とSVM(サポートベクタマシン)を組み合わせて識別器を作成します。

人検出などでは明暗差よりも輪郭情報を捉えたほうが検出精度が良いとされています。
そのため、人検出はHaar-like特徴よりもHoG特徴をよく使います。

画像処理ライブラリOpenCVにも実装されているので、今回はそちらを利用して識別器を作成してみます。

関連記事
HoG SVMの詳細 HoG SVMによる人間検出の原理
HoG特徴の原理 HoG特徴量の原理・計算式
SVMの原理 サポートベクターマシンの原理・計算式
参考文献1 OpenCVでSVMとHOG特徴量を使って人を検出するのを試みてみる
参考文献2 HOG特徴量を用いたポケモンのアイコン画像判別

cv2.HOGDescriptor

cv2.HOGDescriptorでは、グレースケール画像のHog特徴を計算できます。

hog = cv2.HOGDescriptor(win_size, block_size, block_stride, cell_size, nbins)
hog.compute(img)
パラメータ 説明
win_size 検出窓サイズ
block_size ブロックサイズ
block_stride ブロックの移動量(セルサイズの倍数にする)
cell_size セルサイズ
nbins 1セル毎のビン数
img グレースケール画像(8bit)

ソースコード(Python3+OpenCV3)

サンプルプログラムのソースコードです。

識別器の作成

#-*- coding:utf-8 -*-
import cv2
import numpy as np

# Hog特徴の計算とラベリング
def calc_hog(hog, pos_n, neg_n, win_size, cnt=1):
    train = []
    label = []
    # 正解画像・不正解画像のHog特徴を計算してラベル付け
    for i in range(cnt, pos_n):
        img = cv2.imread('pos/' + str(i) + '.jpg', 0)
        img = cv2.resize(img, (win_size))
        train.append(hog.compute(img)) # 特徴量の格納
        label.append(1)                # 正解データのラベルは1

    for i in range(cnt, neg_n):
        img = cv2.imread('neg/' + str(i) + '.jpg', 0)
        img = cv2.resize(img,(win_size))
        train.append(hog.compute(img)) # 特徴量の格納
        label.append(0)                # 正解データのラベルは0
    
    return np.array(train), np.array(label, dtype=int)


def main():
    # Hog特徴のパラメータ
    win_size = (120, 60)
    block_size = (16, 16)
    block_stride = (4, 4)
    cell_size = (4, 4)
    bins = 9
    pos_n = 3 # 正解画像の枚数
    neg_n = 3 # 不正解画像の枚数

    # Hog特徴の計算とラベリング
    hog = cv2.HOGDescriptor(win_size, block_size, block_stride, cell_size, bins)
    train, label = calc_hog(hog, pos_n, neg_n, win_size)

    # Hog特徴からSVM識別器の作成
    svm = cv2.ml.SVM_create()
    svm.setKernel(cv2.ml.SVM_LINEAR)
    svm.setType(cv2.ml.SVM_C_SVC)
    svm.setC(0.5)
    svm.train(train, cv2.ml.ROW_SAMPLE, label)
    svm.save('train.xml')

if __name__ == "__main__":
    main()

作成した識別器の読み込み

#-*- coding:utf-8 -*-
import cv2
import numpy as np

def main():
    svm = cv2.ml.SVM_create()
    svm.load("train.xml")
    print(svm)

if name == “main“:
main()

実行結果

サンプルプログラムの実行結果です。

関連記事
PythonでOpenCV入門 サンプル集
【Python】画像処理プログラミング入門
【画像処理入門】アルゴリズム&プログラミング
関連記事

コメント

  1. k より:

    識別機を作成した後の使い方を教えて頂けないでしょうか。
    宜しくお願い致します。

    • 管理人 より:

      ※k様

      コメントありがとうございます。
      作成した識別器の扱い方ですが、私も現在調査中でうまく行っていません。
      申し訳ないのですが、分かり次第、追記したいと思います。
      もしk様が使い方がわかれば教えてくださると嬉しいです。

      • k より:

        返信ありがとうございます。
        このサイトにはいつもお世話になっております。
        機械学習を研究に使用しておりまして、現在勉強中です。
        分かりましたらお知らせお知らせ致します。
        ご丁寧にありがとうございました。