HOG

OG(Histogram of Oriented Gridients)即标的目标梯度直方图,是一种图象特点提取的编制。其最早由法国研究员Dalal等人在CVPR-2005上提出,经过过程图象局部梯度标的目标的漫衍描述图象中的物体边沿。

算法首要分爲以下幾個步驟:

  • 預處理
  • 計算梯度
  • 計算梯度标的目标直方图
  • 重疊直方圖歸一化
  • 獲取HOG特点向量

預處理

在這一步中,可以對圖像進行裁剪與縮放和調整圖像亮度,以便後續對圖像處理。

例如:

  • 冪次變換
  • 對數變換

計算梯度

通過Sobel算子計算程度與豎直梯度,並計算合梯度的幅值與标的目标:

$$ g=\sqrt{g^2_{x}+g^2_{y}} $$

$$ \theta=\arctan\frac{g_y}{g_x} $$

由于梯度标的目标取绝对值,所以$\theta\in[0, \pi]$,标的目标相反的两个梯度会被以为是同一个。

計算梯度标的目标直方图

将图象划分为$n\times m$的cell,对每个cell计较标的目标梯度强度直方图。在这一步中,我们需要对梯度标的目标进行离散化,例如可以将数据分为9个深度为20的箱,从而构成一个长度为9向量。

重疊直方圖歸一化

将$x\times x$的cell划分为一个block,采取滑动窗口的策略,对block内每个cell拼接而成的向量进行归一化操纵。

獲取HOG特点向量

在上一步中,对每个block,我们都获得了一个长度为$bin_{depth}\times x^2$的向量,总计$(n-1)\times(m-1)$个。将这些向量拼接起来,就获得了我们需要求的HOG特点向量


參考:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import cv2
import os
import numpy as np
from skimage import io
import matplotlib.pyplot as plt
from skimage.feature import hog
from sklearn.svm import SVC
from sklearn.metrics import precision_score,recall_score

TRAIN_COUNT = 500
TEST_COUNT = 100

def get_features(object_detect, count, test=False):
    if test:
        img_path = f"data/test_set/{object_detect}s/{object_detect}.%d.jpg"
        start = 4001
    else:
        img_path = f"data/training_set/{object_detect}s/{object_detect}.%d.jpg"
        start = 1


    if object_detect == "cat":
        labels = np.array([0 for _ in range(count)]).reshape(-1, 1)
    else:
        labels = np.array([1 for _ in range(count)]).reshape(-1, 1)


    features = list()
    for i in range(start, start+count):
        print(img_path % i)
        # 读取图片
        gray = cv2.imread(img_path % i, cv2.IMREAD_GRAYSCALE)
        # 尺寸缩放
        gray = cv2.resize(gray, (128, 128))
        # 中值滤波
        gray = cv2.medianBlur(gray, 3)
        # HOG特点提取
        hog_image = hog(gray, orientations=9, pixels_per_cell=(8, 8), cells_per_block=(8, 8))
        features.append(hog_image.flatten())
    features = np.array(features)
    return features, labels


def get_predict_img(img_path):
    gray = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)
    # 尺寸缩放
    gray = cv2.resize(gray, (128, 128))
    # 中值滤波
    gray = cv2.medianBlur(gray, 3)
    normalised_blocks, hog_image = hog(gray, orientations=9, pixels_per_cell=( 8, 8), cells_per_block=(8, 8), visualise=True)
    return hog_image.reshape(1, -1)

cat, cat_labels  = get_features(object_detect="cat", count=TRAIN_COUNT)
dog, dog_labels = get_features(object_detect="dog", count=TRAIN_COUNT)
img = np.vstack([cat, dog])
labels = np.vstack([cat_labels, dog_labels])
res = np.hstack([img, labels])

clf = SVC(probability=True)
data = res[:, :-1]
labels = res[:, -1]
clf.fit(data, labels)


# ----------- 展望单张图片 ---------------------------------
# test_img = get_predict_img("training_set/cats/cat.38.jpg")
# pred = clf.predict(test_img)
# print(pred)
# ----------- 展望单张图片 ---------------------------------

test_cat, test_cat_labels = get_features(object_detect="cat", count=TEST_COUNT, test=True)
test_dog, test_dog_labels = get_features(object_detect="dog", count=TEST_COUNT, test=True)

test_img = np.vstack([test_cat, test_dog])
test_labels = np.vstack([test_cat_labels, test_dog_labels])

pred = clf.predict(test_img)

precision = precision_score(pred,test_labels)
recall = recall_score(pred,test_labels)
print("實際類別:",test_labels.flatten())
print("預測類別:",pred.flatten())
print(f"精准率:{precision}, 召回率:{recall}")
利用 Hugo 構建
主題 StackJimmy 設計
xxfseo.com