OpenCV:使⽤python-cv2+Hog特征+SVM实现狮⼦识别
⽂章⽬录
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)
#训练
# 预测
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)
Hog特征
看下⾯这个例⼦:
这⾥有⼀个图像img(整个⽩⾊区域), win窗⼝(蓝⾊区域)为图像中Hog特征计算的最⼤模板,官⽅模板⼤⼩为64*128。block(红⾊区域部分)为win窗⼝中的⼩模板,⼤⼩⼀般为16*16。block中⼜有很多的⼩模板cell(绿⾊区域),⼤⼩⼀般为8*8。
cell bin: 通过计算像素的梯度得到梯度的⼤⼩和⽅向, ⽅向为0-360度, 如果以40度进⾏划分,将会得到9块,将这9块设置为9个单元,每⼀个单元就是⼀个bin。
hot特征维度: win窗⼝中block模板的个数 * cell模板个数 * bin的个数
hog特征: 像素都有⼀个梯度,win窗⼝中所有的像素梯度构成了hog特征
如何计算梯度:
我们使⽤俩个模板:⽔平梯度模板[1 0 -1], 竖直梯度模板[[1],[0],[-1]],即相邻像素之差。
求得幅值为:f = sqrt(x^2 + y^2),⾓度angle = arctan(a / b)
bin的划分:如果以40度进⾏划分,将会得到9个bin,则bin1的区域为(0-20度)和180-200度,即关于180度对称的夹⾓
如果某个梯度的⾓度正好在bin⾓度范围的正中⼼, 如d = 10,则将其规划到bin1区域。否则将该梯度分解到相邻的俩个bin单元中:d1 = d * d(夹⾓), d2 = d * (1 - d(夹⾓))
计算整体的hog特征
1.⾸先计算每个cell下所有bin的值,每⼀个bin的计算⽅式为所有划分到该bin下的幅值之和sum(d)
2.得到图像特征的维度,以上⾯的为例,该图像的特征维度为win窗⼝中block模板的个数 * cell模板个数 * bin的个数 = 105* 4 * 9 = 3780
3.通过使⽤svm⽀持向量机对特征进⾏分类,得到⼀个3780维的分类结果,⽤hog * svm得到⼀个值 f,让 f 与我们的判决门限进⾏⽐较,如果⼤于判决门限则认为是⽬标。
Hog特征+SVM实现狮⼦识别
这⾥使⽤正样本(PosNum) 820张图⽚,负样本(NegNum)1931张图⽚进⾏训练模型,最终完成训练,最后采⽤带有⼩狮⼦的图⽚进⾏测试
训练步骤如下:
1.设置参数
2.创建Hog:我们使⽤cv2.HOGDescriptor(winSize,blockSize,blockStride,cellSize,Bin)函数来创建
3.创建svm,我们使⽤cv2.ml.SVM_create()函数来创建,并设置属性
4.计算Hog,准备标签label
5.训练
6.预测
7.绘图
import cv2
rectangle函数opencvimport 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)
img = cv2.imread(filename)
# 计算图像的hog特征, shape (3780,1)
hist = hogpute(img,(8,8))# 第⼆个参数: winStride Window stride # 将该hog特征值存到featureArray⾥⾯
featureArray[i]= shape(-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 = hogpute(img,(8,8))# 第⼆个参数: winStride Window stride # 将该hog特征值存到featureArray⾥⾯
featureArray[i]= shape(-1)
labelArray[i]=-1
# 5.训练
# 6.检测
alpha = np.zeros((1), np.float32)
rho = DecisionFunction(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.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]]))
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论