HOG特徵和應用

概述

✔️ HOG(Histogram of Oriented Gradient)特徵在物件識別與模式匹配中是一種常見的特徵提取演算法,是基於本地畫素塊進行特徵直方圖提取的一種演算法,物件區域性的變形與光照影響有很好的穩定性。

HOG應用-行人檢測

✔️ 用HOG特徵來來識別人像,透過HOG特徵提取+SVM訓練,可以得到很好的效果,Opencv也集成了HOG進行的行人檢測演算法。

OpenCV函式

hog = cv2。HOGDescriptor()

:建立HOG特徵描述;

hog。setSVMDetector(cv。HOGDescriptor_getDefaultPeopleDetector())

:建立HOG+SVM行人檢測器;

多尺度檢測API:

rects, weights = hog。detectMultiScale(img, foundLocations,

hitThreshold = 0,

winStride, padding,

scale = 1。05,

finalThreshold = 2。0,

useMeanshiftGrouping = false)

輸入

Img ——> 表示輸入影象;

foundLocations ——> 表示發現物件矩形框;

hitThreshold ——> 表示SVM距離度量(特徵與SVM分類超平面之間距離),預設0表示;

winStride ——> 表示視窗步長;

padding ——> 表示填充;

scale ——> 表示尺度空間;

finalThreshold ——> 最終閾值,預設為2。0;

useMeanshiftGrouping ——> 不建議使用,速度太慢;

PS:其中視窗步長與Scale對結果影響最大,特別是Scale,小的尺度變化有利於檢出低解析度物件,同時也會導致FP發生,高的可以避免FP但是會產生FN(物件漏檢)。

行人檢測程式碼示例

import

cv2

as

cv

src

=

cv

imread

“people。png”

cv

imshow

“input”

src

# hog特徵描述

hog

=

cv

HOGDescriptor

()

# 建立SVM檢測器

hog

setSVMDetector

cv

HOGDescriptor_getDefaultPeopleDetector

())

# 檢測行人

rects

weights

=

hog

detectMultiScale

src

winStride

=

4

4

),

padding

=

8

8

),

scale

=

1。25

useMeanshiftGrouping

=

False

for

x

y

w

h

in

rects

cv

rectangle

src

x

y

),

x

+

w

y

+

h

),

0

255

0

),

2

cv

imshow

“hog-people”

src

cv

waitKey

0

cv

destroyAllWindows

()

OpenCV影象處理-HOG特徵和應用

原圖

OpenCV影象處理-HOG特徵和應用

結果圖

HOG特徵描述子提取

提取過程

1. Gamma矯正

✔️ 為了提高檢測器對關照等干擾因素的魯棒性,需要對影象進行Gamma矯正,完成對整個影象的歸一化,調整對比度,降低噪聲影響;

G(x, y)=F(x, y)^{1 / r}

一般 r=1/2

2. 灰度化

3. 計算影象XY梯度和方向

使用sobel可以出水平和垂直方向的梯度:

gx = cv2。Sobel(img, cv2。CV_32F, 1, 0, ksize=1)

gy = cv2。Sobel(img, cv2。CV_32F, 0, 1, ksize=1)

利用公式求取梯度幅值和方向:

\begin{aligned} g &=\sqrt{g_{x}^{2}+g_{y}^{2}} \\ \theta &=\arctan \frac{g_{y}}{g_{x}} \end{aligned}

# Opencv中使用:

mag, angle = cv2。cartToPolar(gx, gy, angleInDegrees=True)

4. 8x8網格方向梯度權重直方圖統計

✔️ 流程:首先將影象劃分成若干個塊(Block),每個塊又由若干個細胞單元(cell)組成,細胞單元由更小的單位畫素(Pixel)組成,然後在每個細胞單元中對內部的所有畫素的梯度方向進行統計。

預設HOG的描述子視窗為64x128, 視窗移動步長為 8x8

每個視窗的cell為8x8,每個block由4個cell組成,block移動步長為一個cell,因此可以得到7x15個block

OpenCV影象處理-HOG特徵和應用

HOG

直方圖把180度分為9個bin,每個區間為20度,如果畫素落在某個區間,就把該畫素的直方圖累計到對應區間的直方圖上

OpenCV影象處理-HOG特徵和應用

直方圖統計

每個block有4個cell,每個cell有9個向量值,即每個block有36個向量,所以整個視窗有7x15x36=3780個特徵描述子。

5. 塊描述子和特徵向量歸一化

✔️ 每個block可以得到4個9維的向量,需要再次進行一次歸一化,這樣可以進一步提高泛化能力,同傳使用L2-nrom進行歸一化(還有L1-norm, L1-sqrt,etc。)

v=\frac{v}{\sqrt{\|v\|_{2}^{2}+\varepsilon^{2}}}

整體流程圖

OpenCV影象處理-HOG特徵和應用

HOG提取流程

HOG+SVM 檢測示例

✔️ 這裡,我們使用前面所瞭解到HOG知識,結合SVM,進行一個簡單的水錶檢測案例。

使用描述子特徵生成樣本資料

透過SVM進行分類學習與訓練

load模型,進行預測結果

資料生成

# 把目標圖放在64x128的灰色圖片中間,方便計算描述子

def

get_hog_descriptor

image

):

hog

=

cv

HOGDescriptor

()

h

w

=

image

shape

[:

2

rate

=

64

/

w

image

=

cv

resize

image

64

np

int

rate

*

h

)))

gray

=

cv

cvtColor

image

cv

COLOR_BGR2GRAY

bg

=

np

zeros

((

128

64

),

dtype

=

np

uint8

bg

[:,:]

=

127

h

w

=

gray

shape

dy

=

128

-

h

//

2

bg

dy

h

+

dy

,:]

=

gray

descriptors

=

hog

compute

bg

winStride

=

8

8

),

padding

=

0

0

))

return

descriptors

def

get_data

train_data

labels

path

lableType

):

for

file_name

in

os

listdir

path

):

img_dir

=

os

path

join

path

file_name

img

=

cv

imread

img_dir

hog_desc

=

get_hog_descriptor

img

one_fv

=

np

zeros

([

len

hog_desc

)],

dtype

=

np

float32

for

i

in

range

len

hog_desc

)):

one_fv

i

=

hog_desc

i

][

0

train_data

append

one_fv

labels

append

lableType

return

train_data

labels

def

get_dataset

pdir

ndir

):

train_data

=

[]

labels

=

[]

# 獲取正樣本

train_data

labels

=

get_data

train_data

labels

pdir

lableType

=

1

# 獲取負樣本

train_data

labels

=

get_data

train_data

labels

ndir

lableType

=-

1

return

np

array

train_data

dtype

=

np

float32

),

np

array

labels

dtype

=

np

int32

if

__name__

==

‘__main__’

# train_data的shape為(n, 3780), labels(n,)

# n為樣本數

train_data

labels

=

get_dataset

“pdir/”

“ndir/”

構建SVM訓練器

✔️ Opencv中SVM有線性分類器和非線性的徑向分類器。

這裡使用線性分類器:

svm。train(trainData, cv。ml。ROW_SAMPLE, responses)

Sample ——> 表示訓練樣本資料/HOG特徵資料

Layout ——> 有兩種組織方式ROW_SAMPLE與COL_SAMPLE

Responses ——> 每個輸入樣本的標籤

訓練程式碼

def

svm_train

pdir

ndir

):

# 建立SVM

svm

=

cv

ml

SVM_create

()

# 設定相應的SVM引數

svm

setKernel

cv

ml

SVM_LINEAR

svm

setType

cv

ml

SVM_C_SVC

svm

setC

2。67

svm

setGamma

5。383

# 獲取正負樣本和labels

trainData

responses

=

get_dataset

pdir

ndir

# reshape (n,)——>(n,1)

responses

=

np

reshape

responses

-

1

1

])

# 訓練

svm

train

trainData

cv

ml

ROW_SAMPLE

responses

svm

save

‘svm_data。dat’

預測目標

import cv2 as cv

import numpy as np

image = cv。imread(“test_01。jpg”)

# 原圖太大,降低原圖解析度

test_img = cv。resize(image, (0, 0), fx=0。2, fy=0。2)

# 灰度

gray = cv。cvtColor(test_img, cv。COLOR_BGR2GRAY)

# 獲取大小

h, w = test_img。shape[:2]

# 載入訓練好的模型

svm = cv。ml。SVM_load(‘。。/code_104/svm_data。dat’)

# 為了篩選框,記錄框座標總和以及框的個數,為了最後求出所有候選框的均值框

sum_x = 0

sum_y = 0

count = 0

# 建立hog特徵描述子函式

hog = cv。HOGDescriptor()

# 為了加快計算,視窗滑動的步長為4,一個cell是8個畫素

for row in range(64, h-64, 4):

for col in range(32, w-32, 4):

win_roi = gray[row-64:row+64,col-32:col+32]

hog_desc = hog。compute(win_roi, winStride=(8, 8), padding=(0, 0))

one_fv = np。zeros([len(hog_desc)], dtype=np。float32)

for i in range(len(hog_desc)):

one_fv[i] = hog_desc[i][0]

one_fv = one_fv。reshape(-1, len(hog_desc))

# 預測

result = svm。predict(one_fv)[1]

# 統計正樣本

if result[0][0] > 0:

sum_x += (col-32)

sum_y += (row-64)

count += 1

# 畫出所有框

cv。rectangle(test_img, (col-32, row-64), (col+32, row+64), (0, 233, 255), 1, 8, 0)

# 求取均值框

x = sum_x // count

y = sum_y // count

# 畫出均值框

cv。rectangle(test_img, (x, y), (x+64, y+128), (0, 0, 255), 2, 8, 0)

OpenCV影象處理-HOG特徵和應用

原圖

OpenCV影象處理-HOG特徵和應用

結果圖(紅色框為最終均值框,黃色為檢測到的所有框)

如上圖,類似於目標檢測中NMS的作用,這裡使用均值的方法獲得最終的框。

小結

✔️ 對於簡單的識別,HOG和SVM的識別效果還是很不錯的,為了提高效果,可以增加正負樣本進行,再次進行訓練。

✔️ SVM不需要GPU,所以在針對一些簡單的識別任務,可以採用這個方法,但是複雜問題,還是建議使用神經網路,效果會更好!

——————————————————————可愛の分割線——————————————————————

更多Opencv教程可以 Follow github的opencv教程,

中文&English

歡迎Star

❤️❤️❤️

參考

- Histogram of Oriented Gradients

- 方向梯度直方圖(HOG)