記事ディレクトリ
SVM
ベクターマシンのサポート:サンプル分類を実現するために最適なハイパープレーンを探します
以下では、SVMを使用して、身長と体重に基づいて男性と女性の学生を分類する問題を実装します。
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 准备数据
rand1 = np.array([[155,48],[159,50],[164,53],[168,56],[172,60]])
rand2 = np.array([[152,53],[156,55],[160,56],[172,64],[176,65]])
# 0为女生 1为男生
label = np.array([[0],[0],[0],[0],[0],[1],[1],[1],[1],[1]])
data = np.vstack((rand1,rand2)) # 合并两组数据
data = np.array(data, dtype = 'float32')
svm = cv2.ml.SVM_create() # 创建svm学习模型
svm.setType(cv2.ml.SVM_C_SVC) # 类型为svm分类
svm.setKernel(cv2.ml.SVM_LINEAR) # 设置svm的内核为线性分类器
svm.setC(0.01)
#训练
svm.train(data,cv2.ml.ROW_SAMPLE,label)
# 预测
pt_data = np.array([[167,55],[162,57]])
pt_data = np.array(pt_data, dtype = 'float32')
#pt_label = [[0],[1]]
predict = svm.predict(pt_data)
predict[1]
array([[0.],
[1.]], dtype=float32)
豚の特徴
次の例を見てください。
これが画像img(白い領域全体)であり、win
ウィンドウ(青い領域)は画像内のHog機能によって計算された最大のテンプレートです64*128
。公式のテンプレートサイズはです。block
(赤い領域)はwin
ウィンドウ内の小さなテンプレートで、サイズは通常16*16
です。block
真ん中に小さなテンプレートcell
(緑色の領域)がたくさんあり、サイズは一般的に8*8
です。
セルビン:。。。9個の細胞に設定しますが、40度で割る場合、あなたが9つのブロックを取得する方向が0から360度で、画素の勾配を算出することにより、これらの9つのブロックの勾配の大きさと方向を取得し、各セルは、1つです置き場。
ホットフィーチャーの寸法: win窗口中block模板的个数 * cell模板个数 * bin的个数
ホグ機能:ピクセルには勾配があり、勝利ウィンドウ内のすべてのピクセル勾配がホグ機能を構成します
勾配の計算方法:
水平勾配テンプレート[1 0 -1]
と垂直勾配テンプレート[[1],[0],[-1]]
、つまり隣接するピクセル間の差の2つのテンプレートを使用します。
振幅を見つける:f = sqrt(x^2 + y^2)
、角度angle = arctan(a / b)
ビンの分割:40度で分割すると、9つのビンが得られます.bin1の面積は(0〜20度)と180〜200度で、これは180度の対称角度です
特定の勾配の角度が正確にビンの角度範囲の中心にある場合(d = 10など)、bin1領域に計画されます。それ以外の場合、勾配は2つの隣接するビンユニットに分解されます。d1 = d * d(夹角), d2 = d * (1 - d(夹角))
全体的な豚の特徴を計算する
1.まずcell
、各ビンのすべてのビンの値を計算します。各ビンの計算方法は、すべてのビンを分割した振幅の合計です。sum(d)
2.上記を例として、画像の特徴の寸法を取得します。画像の特徴の寸法は次のとおりです。win窗口中block模板的个数 * cell模板个数 * bin的个数 = 105* 4 * 9 = 3780
3. svmサポートベクターマシンを使用して特徴を分類することにより、3780次元の分類結果が得られ、hog * svmで値fが得られ、fが決定しきい値と比較されます。決定しきい値より大きい場合は、ターゲットと見なされます。
ライオン認識を実現する豚機能+ SVM
ここでは、ポジティブサンプルの820枚(PosNum)とネガティブサンプルの1931枚(NegNum)を使用してモデルをトレーニングし、最後にトレーニングを完了し、最後に小さなライオンの写真をテストに使用します。
ここで使用されるポジティブサンプルとネガティブサンプルのデータセットは、Baiduクラウドリンクにあります:
リンク:https
://pan.baidu.com/s/1jNpN8ecMKhOHLiy1KlEj4w抽出コード:61時間
トレーニング手順は次のとおりです。
1.パラメータを設定します
2.豚の作成:cv2.HOGDescriptor(winSize,blockSize,blockStride,cellSize,Bin)
関数を使用して作成します
3. svmcv2.ml.SVM_create()
を作成し、関数を使用してプロパティを作成および設定します
4.豚を計算し、ラベルを準備します
5.トレーニング
6.予測
7.描画
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 1.设置参数
PosNum = 820
NegNum = 1931
winSize = (64,128)
blockSize = (16,16) # 105
blockStride = (8,8)
cellSize = (8,8)
Bin = 9 # 3780
#2.创建hog
hog = cv2.HOGDescriptor(winSize,blockSize,blockStride,cellSize,Bin)
#3.创建svm
svm = cv2.ml.SVM_create()
#svm属性设置
svm.setType(cv2.ml.SVM_C_SVC)
svm.setKernel(cv2.ml.SVM_LINEAR)
svm.setC(0.01) # 优化
#4.计算hog
featureNum = int(((128 - 16) / 8 + 1) * ((64 - 16) / 8 + 1) * 4 * 9) # 3780
featureArray = np.zeros((PosNum + NegNum, featureNum),np.float32)
labelArray = np.zeros((PosNum + NegNum, 1),np.int32)
# 处理正样本
for i in range(PosNum):
filename = 'pos\\' + str(i + 1) + '.jpg'
img = cv2.imread(filename)
# 计算图像的hog特征, shape (3780,1)
hist = hog.compute(img, (8,8)) # 第二个参数: winStride Window stride
# 将该hog特征值存到featureArray里面
featureArray[i] = hist.reshape(-1)
labelArray[i] = 1
# 处理负样本
for i in range(PosNum, PosNum + NegNum):
filename = 'neg\\' + str(i + 1 - PosNum) + '.jpg'
img = cv2.imread(filename)
# 计算图像的hog特征, shape (3780,1)
hist = hog.compute(img, (8,8)) # 第二个参数: winStride Window stride
# 将该hog特征值存到featureArray里面
featureArray[i] = hist.reshape(-1)
labelArray[i] = -1
# 5.训练
svm.train(featureArray,cv2.ml.ROW_SAMPLE, labelArray)
# 6.检测
alpha = np.zeros((1), np.float32)
rho = svm.getDecisionFunction(0, alpha) # 得到分类阙值
print(rho)
print(alpha)
alphaArray = np.zeros((1,1),np.float32)
supportVArray = np.zeros((1,featureNum), np.float32)
resultArray = np.zeros((1,featureNum), np.float32)
alphaArray[0,0] = alpha
resultArray = -1 * alphaArray * supportVArray
# 7.绘图
myDetect = np.zeros((3781), np.float32)
for i in range(3780):
myDetect[i] = resultArray[0,i]
myDetect[3780] = rho[0]
# 构建hog
myHog = cv2.HOGDescriptor()
myHog.setSVMDetector(myDetect)
# 加载待检测图片
imageSrc = cv2.imread('test.jpg', 1)
cv2.imshow('img', imageSrc)
# 参数:(8,8)win滑动步长,(32,32)win大小,缩放系数 目标大小
objects = myHog.detectMultiScale(imageSrc, 0, (8,8), (32,32), 1.05, 2)
x = int(objects[0][0][0])
y = int(objects[0][0][1])
w = int(objects[0][0][2])
h = int(objects[0][0][3])
cv2.rectangle(imageSrc, (x,y),(x+w,y+h),(255,0,0),2)
cv2.imshow('img', imageSrc)
print(objects)
cv2.waitKey(0)
(0.2555259476741386, array([[1.]]), array([[0]], dtype=int32))
[0.]
(array([[ 0, 0, 64, 128]], dtype=int32), array([[0.25552595]]))