HOG特征提取算法----Numpy实现

HOG算法基本思想:一副图像中,局部目标的表象和形状能够被梯度分布很好地描述,即梯度的统计信息主要集中与目标的边缘,HOG算法要提取的就是这些梯度信息。

HOG算法流程:

1.图像预处理:将图像灰度化,并标准化gamma空间,减小颜色和光照的影响。

2.提取每个像素的水平方向梯度grad_x和垂直方向梯度grad_y,用如图所示的梯度算子对图像做卷积即可。

 计算每个像素点的梯度大小和梯度方向:

grad(x,y)=sqrt(grad_x^{2}+grad_y^{2})

\theta=arctan(grad_y/grad_x)

3.将图像分成许多个小cell,将0~180度的角度平均分为9个方向,统计cell中每个像素的梯度在这些方向上的幅值,形成梯度分布直方图。

4.因为梯度值受像素值影响较大,对梯度分布做归一化。用窗口评议的方法,每次选区4个cell,对4个cell中的梯度做归一化,每个窗口得到4*9=36个特征值。最终所有窗口的特征值整合即为图像的HOG特征。

 

Numpy代码:

# -*- coding: utf-8 -*-
"""
Created on Tue Apr 16 16:43:04 2019

@author: yexiaohan
"""

import numpy as np
import cv2
import matplotlib.pyplot as plt
from PIL import Image

def rgb2gray(rgb):
    return np.matmul(rgb, np.array([0.299, 0.587, 0.114]))



def div(img,cell_x,cell_y,cell_w):
    cell=np.zeros(shape=(cell_x, cell_y, cell_w, cell_w))
    img_x=np.split(img,cell_x,axis=0)
    for i in range(cell_x):
        img_y=np.split(img_x[i],cell_y,axis=1)
        for j in range(cell_y):
            cell[i][j]=img_y[j]
    return cell
    
def get_bins(grad_cell,ang_cell):
    bins=np.zeros(shape=(grad_cell.shape[0],grad_cell.shape[1],9))
    for i in range(grad_cell.shape[0]):
        for j in range(grad_cell.shape[1]):
            binn=np.zeros(9)
            grad_list=grad_cell[i,j].flatten()
            ang_list=ang_cell[i,j].flatten()
            left=np.int8(ang_list/20.0)
            right=left+1
            right[right>=8]=0
            left_rit=(ang_list-20*left)/20.0
            right_rit=1.0-left_rit
            binn[left]+=left_rit*grad_list
            binn[right]+=right_rit*grad_list
            bins[i,j]=binn
    return bins
    
    
def hog(img,cell_x,cell_y,cell_w):
    img=rgb2gray(img)
    gx=cv2.Sobel(img,ddepth=cv2.CV_64F,dx=1,dy=0,ksize=3)
    gy=cv2.Sobel(img,ddepth=cv2.CV_64F,dx=0,dy=1,ksize=3)
    grad=np.sqrt(gx*gx+gy*gy)
    ang=np.arctan2(gx,gy)
    ang[ang<0]=np.pi+ang[ang<0]
    ang*=(180.0/np.pi)
    ang[ang>=180]-=180
    grad_cell=div(grad,cell_x,cell_y,cell_w)
    ang_cell=div(ang,cell_x,cell_y,cell_w)
    bins=get_bins(grad_cell,ang_cell)
    feature=[]
    for i in range(cell_x-1):
        for j in range(cell_y-1):
            tmp=[]
            tmp.append(bins[i,j])
            tmp.append(bins[i+1,j])
            tmp.append(bins[i,j+1])
            tmp.append(bins[i+1,j+1])
            tmp-=np.mean(tmp)
            feature.append(tmp.flatten())
    #plt.imshow(grad,cmap=plt.cm.gray)
    #plt.show()
    return np.array(feature).flatten()


img=Image.open('img.jpg')
img=np.array(img)
img=cv2.resize(img,(512, 512),interpolation=cv2.INTER_CUBIC)
cell_w=8
cell_x=int(img.shape[0]/cell_w)
cell_y=int(img.shape[1]/cell_w)
feature=hog(img,cell_x,cell_y,cell_w)
print(feature.shape)

HOG+SVM:

将HOG特征作为SVM的输入训练SVM分类器代替将原始像素点输入SVM会取得比较好的效果,经典的应用如行人检测。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值