OpenCV17:使用Hog + SVM做小狮子识别

在【OpenCV16:Hog特征】中已经详细描述了Hog特征,这次加上SVM做一个小小的识别。

实现步骤如下:1、准备数据集    2、对样本进行Hog特征的训练    3、预测

1、准备数据集

一个好的样本,远胜过一个复杂的神经网络。

我们将数据集分为两个文件夹neg(1931张图,大小64*128)和pos(820张,大小64*128)。

pos文件夹里存放的是正样本,所有图片都包含小狮子。

neg文件夹里存放的是负样本,所有图片都不能包含小狮子。

pos文件夹的部分图片
neg文件夹的部分图片

 

正样本尽可能多样化:如环境、角度、干扰等。

2、对样本进行Hog特征的训练  3、预测

定义的Hog特征在【OpenCV16:Hog特征】中有介绍,使用的推荐大小。

首先,要训练SVM 是监督学习,学习的是图中的Hog特征,所以要使用计算好的Hog特征对正负样本进行标签的设置。代码如下:

# 5、设置正负样本标签
for i in range(PosNum):
    fileName = 'pos\\' + str(i+1) + '.jpg'
    img = cv2.imread(fileName)
    hist = hog.compute(img, (8,8))    # 计算hog特征
    # 将正样本中的 Hog特征装到featureArray中
    for j in range(featureNum):    # Hog特征维度,在下面的全部代码中有定义
        featureArray[i,j] = hist[j]    # featureArray中的每一行代表一个3780维的 Hog特征
    labelArray[i,0] = 1     # 正样本标签设置为 1
# 处理负样本
for i in range(NegNum):
    fileName = 'neg\\' + str(i+1) + '.jpg'
    img = cv2.imread(fileName)
    hist = hog.compute(img, (8,8))    # 计算hog特征
    for j in range(featureNum):
        featureArray[i+PosNum, j] = hist[j]
    labelArray[i+PosNum, 0] = -1    # 正样本标签设置为 -1

然后设置SVM的属性,并加以训练:

# 设置svm的属性
svm.setType(cv2.ml.SVM_C_SVC)
svm.setKernel(cv2.ml.SVM_LINEAR)
svm.setC(0.01)
# 6、训练
ret = svm.train(featureArray, cv2.ml.ROW_SAMPLE, labelArray)

在检测时,需要创建一个myHog,其核心是myDetect。所以要得到这个myDetect,myDetect是一个数组,数据由resultArray和经过SVM训练得到的rho组成。得到detect后调用detectMutiScale()方法预测,这个方法可以返回目标的宽高信息,从而实现绘制。全部代码如下:

# 整个过程分为7步:1、Hog参数设置    2、创建Hog    3、svm参数设置与创建    4、计算Hog    5、label    6、训练    7、预测
import cv2
import numpy as np
import matplotlib.pyplot as plt

# 1、设置 Hog参数,定义3780维的Hog特征
PosNum = 820    # 正样本的数量
NegNum = 1931
winSize = (64,128)    # win的大小
blockSize = (16,16)    # block的大小
blockStep = (8,8)
cellSize = (8,8)
binNum = 9

# 2、创建Hog
hog = cv2.HOGDescriptor(winSize,blockSize,blockStep,cellSize,binNum)
# 3、创建svm
svm = cv2.ml.SVM_create()

# 4、计算Hog
featureNum = int(((128-16)/8+1) * ((64-16)/8+1) * 4 * 9)    # 3780维的特征数,计算的是bin的数量,数字为推荐尺寸
featureArray = np.zeros(((PosNum + NegNum),featureNum),np.float32)   # 装载特征的数组 全样本数行 * 特征维数(3780)列
labelArray = np.zeros(((PosNum + NegNum), 1), np.int32)   # 装载标签的数组,   注意!!!!如果labelArray报错,那么你应该写成了np.float32

# svm 是监督学习,学习的是图中的Hog特征
# 5、设置正负样本标签
for i in range(PosNum):
    fileName = 'pos\\' + str(i+1) + '.jpg'
    img = cv2.imread(fileName)
    hist = hog.compute(img, (8,8))    # 计算hog特征
    # 将正样本中的 Hog特征装到featureArray中
    for j in range(featureNum):
        featureArray[i,j] = hist[j]    # featureArray中的每一行代表一个3780维的 Hog特征
    labelArray[i,0] = 1     # 正样本标签设置为 1
# 处理负样本
for i in range(NegNum):
    fileName = 'neg\\' + str(i+1) + '.jpg'
    img = cv2.imread(fileName)
    hist = hog.compute(img, (8,8))    # 计算hog特征
    for j in range(featureNum):
        featureArray[i+PosNum, j] = hist[j]
    labelArray[i+PosNum, 0] = -1    # 正样本标签设置为 -1

# 设置svm的属性
svm.setType(cv2.ml.SVM_C_SVC)
svm.setKernel(cv2.ml.SVM_LINEAR)
svm.setC(0.01)
# 6、训练
ret = svm.train(featureArray, cv2.ml.ROW_SAMPLE, labelArray)
print(ret)

# 7、预测
alpha = np.zeros((1), np.float32)   # 一维数组
rho = svm.getDecisionFunction(0,alpha)    # 在SVM的判决中需要用到 rho
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    
print(resultArray)

# 创建 myDetect是为了创建 Hog,detect是其核心
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)    # 把当前myDtector属性传入Hog
imgSrc = cv2.imread('OpenCV\\Test2.jpg', 1)    # 读取检测图
# (8,8)win步长   (32,32)win尺寸   1.05缩放系数    2最小像素范围
objs = myHog.detectMultiScale(imgSrc, 0, (8,8), (32,32), 1.05, 2)    # 三维信息
# 起始坐标,和宽度高度放在了objs的最后一维
x = int(objs[0][0][0])
y = int(objs[0][0][1])
w = int(objs[0][0][2])
h = int(objs[0][0][3])

# 绘制展示
cv2.rectangle(imgSrc,(x,y),(x+w,y+h),(255,0,0),2)
cv2.imshow('dst',imgSrc)
cv2.waitKey(0)
cv2.destroyAllWindows()

 

 

评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值