十五天掌握OpenCV——支持向量机

魏老师学生——Cecil:学习OpenCV-机器视觉之旅

SVM—线性数据分割

  1. 决定边界:使用f(x)=ax1+bx2+c 将数据分割到两个区域。
  2. 线性分割:使用一条直线将数据分成两组的方法。
  3. SVM:找到一条直线,并使这条直线到各组数据的最短距离最大。
  4. 支持向量:靠近决定边界的那部分数据。
  5. 支持平面:经过支持向量的直线。
  6. ωTx+b0 : ω是权重向量;x是特征向量;b0是截距。
  7. 权重向量影响决定边界走向,截距点影响决定边界的位置。
  8. 决定边界:两个超平面的中间线。表达式ωTx+b0=0.
  9. distance support vector = 1/ ||ω||:支持向量到决定边界的最短距离。边缘长度是其两倍。
  10. 需要使边缘长度最大,创建一个函数使其最小:1

非线性数据分割

  1. 在低维空间不能线性分割的数据在高维空间有可能线性分割。
  2. 通常将d维数据映射到D维数据检测是否可以线性分割。从而通过对低维输入空间的计算获得高维空间的点积。
  3. 最大边缘最小错误分类的评判标准:2
  4. ξi:训练样本到所属类的超平面的距离。3
  5. C的取值:取决于训练数据。太大了边缘减小,错误也变少(数据噪声小使用);太小了边缘变大,错误升高(数据噪声大使用)。

使用SVM进行手写数据OCR

  1. KNN中直接使用像素的灰度值作为特征向量。SVM中使用方向梯度直方图HOG作为特征向量。
  2. 计算HOG前使用图片的二阶矩进行抗扭斜 deskew 处理。
#coding=utf-8
import cv2
import numpy as np
from matplotlib import pyplot as plt

def deskew(img):
    m=cv2.moments(img)
    if abs(m['mu02'])<1e-2:
        return img.copy()
    skew=m['mu11']/m['mu02']
    M=np.float32([[1,skew,-0.5*SZ*skew],[0,1,0]])
    img=cv2.warpAffiner(img,M,(SZ,SZ),flags=affine_flags)
    return img
  1. 计算图像的HOG描述符。先计算图像X方向Y方向的Sobel导数,再计算每个像素的梯度方向与大小。
  2. 把梯度转换为16位整数。分图像为4个小方块,计算每个小方块的朝向直方图 16个bin,使用梯度大小做权重。使得每个小方块都得到含有16个成员的向量。
  3. 4个小方块的4个向量组成图像的特征向量,包含64个成员。
def hog(img):
    gx=cv2.Sobel(img,cv2.CV_32F,1,0)
    gy=cv2.Sobel(img,cv2.CV_32F,0,1)
    mag,ang=cv2.cartToPolar(gx,gy)
    bins=np.int32(bin_n*ang/(2*np.pi))
    bin_cells=bins[:10,:10],bins[10:,:10],bins[:10,10:],bins[10:,10:]
    mag_cells=mag[:10,:10],mag[10:,:10],mag[:10,10:],mag[10:,10:]
    hists=[np.bincount(b.ravel(),m.ravel(),bin_n) for b,m in zip(bin_cells,mag_cells)]
    hist=np.hstack(hists)
    return hist

代码演示

将大图割成小图,使用一半数据集为训练数据,一半为测试数据。

#coding=utf-8
import cv2
import numpy as np
from matplotlib import pyplot as plt

SZ=20
bin_n=16

svm_params=dict(kernel_type=cv2.SVM_LINEAR,
                svm_type=cv2.SVM_C_SVC,
                C=2.67,gamma=5.383)

affine_flags=cv2.WARP_INVERSE_MAP|cv2.INTER_LINEAR

def deskew(img):
    m=cv2.moments(img)
    if abs(m['mu02'])<1e-2:
        return img.copy()
    skew=m['mu11']/m['mu02']
    M=np.float32([[1,skew,-0.5*SZ*skew],[0,1,0]])
    img=cv2.warpAffiner(img,M,(SZ,SZ),flags=affine_flags)
    return img

def hog(img):
    gx=cv2.Sobel(img,cv2.CV_32F,1,0)
    gy=cv2.Sobel(img,cv2.CV_32F,0,1)
    mag,ang=cv2.cartToPolar(gx,gy)
    bins=np.int32(bin_n*ang/(2*np.pi))
    bin_cells=bins[:10,:10],bins[10:,:10],bins[:10,10:],bins[10:,10:]
    mag_cells=mag[:10,:10],mag[10:,:10],mag[:10,10:],mag[10:,10:]
    hists=[np.bincount(b.ravel(),m.ravel(),bin_n) for b,m in zip(bin_cells,mag_cells)]
    hist=np.hstack(hists)
    return hist

img=cv2.imread('./image2/classification.jpg',0)

cells=[np.hsplit(row,100) for row in np.vsplit(img,50)]

train_cells=[i[:50] for i in cells]
test_cells=[i[50:] for i in cells]
#训练
deskewed=[map(deskew,row) for row in train_cells]
hogdata=[map(hog,row) for row in deskewed]
trainData=np.float32(hogdata).reshape(-1,64)
responses=np.float32(np.repeat(np.arange(10),250)[:,np.newaxis])

svm=cv2.SVM()
svm.train(trainData,responses,params=svm_params)
svm.save('svm_data.dat')

#测试
deskewed=[map(deskew,row) for row in test_cells]
hogdata=[map(hog,row) for row in deskewed]
testData=np.float32(hogdata).reshape(-1,bin_n*4)
result=svm.predict_all(testData)

#检测准确度
mask=result==responses
correct=np.count_nonzero(mask)
print(correct*100.0/result.size)

准确率可达到94%。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值