基于SVM的运动手势识别模型

1、通过捕捉手在空中的运动手势,通过卷积进行图像特征提取和PCA特征降维最后通过SVM进行分类。具体代码如下,通过

sklearn、numpy等相关库实现。
#!usr/bin/python3
# -*- coding:utf-8 -*-
# author:SingWeek

import cv2
import numpy as np
import os
from sklearn.model_selection import train_test_split
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix
from sklearn.decomposition import PCA
from sklearn.svm import SVC
from sklearn.externals import joblib

class SVM(object):
    def __init__(self,svmfile="svm.model",pcafile="pca.model"):
        """
        初始化参数
        :param svmfile: SVM模型保存的名称"svm.model"
        :param pcafile: PCA模型保存的名称,"pca.model"
        """
        self.svmfile=svmfile
        self.pcafile=pcafile

    def Load_Svm(self):
        self.clf=joblib.load(self.svmfile)#加载模型

    def Load_Pca(self):
        self.pca=joblib.load(self.pcafile)#加载模型

    def Train_Pca(self,X_Train,n_components = 100):
        """
        PCA 模型训练
        :param X_Train:训练数据
        :param n_components: 特征数,PCA算法中所要保留的主成分个数n,也即保留下来的特征个数n
        :return: None
        """
        self.pca = PCA(svd_solver='auto', n_components=n_components, whiten=True).fit(X_Train)  # 训练一个pca模型
        joblib.dump(self.pca, self.pcafile)  # 保存模型

    def Train(self,X_train, Y_train):
        """
        SVM模型训练
        :param X_train:训练数据
        :param Y_train: 训练标签
        :return: None
        """
        X_train=self.Pca_X(X_train)#数据转换
        param_grid = {'C': [1e3, 5e3, 1e4, 5e4, 1e5],  # C是对错误的惩罚
                      'gamma': [0.0001, 0.0005, 0.001, 0.005, 0.01, 0.1], }  # gamma核函数里多少个特征点会被使用}#对参数尝试不同的值
        self.clf = GridSearchCV(SVC(kernel='rbf'), param_grid)
        self.clf.fit(X_train, Y_train)
        joblib.dump(self.clf, self.svmfile)  # 保存模型

    def Split_Data(self,X,Y,test_ratio=0.3):
        """
        训练数据切分
        :param X:数据
        :param Y:数据标签
        :param test_ratio:测试集占比
        :return:X_train, X_test, Y_train, Y_test:训练数据,测试数据,训练数据标签,测试数据标签
        """
        X_train, X_test, Y_train, Y_test = train_test_split(X,Y, test_size=test_ratio)  # 选取test_ratio的测试集
        return X_train, X_test, Y_train, Y_test

    def Print_Score(self,X_Test,Y_Test):
        """
        模型评分
        :param X_Test: 测试数据
        :param Y_Test: 测试数据标签
        :return: 矩阵评分
        """
        target_names = ['0', '1', '2', '3', '4', '5', '6']
        n_classes = 7
        X_Test=self.Pca_X(X_Test)
        Y_pred=self.clf.predict(X_Test)
        print(classification_report(Y_Test, Y_pred, target_names=target_names))#测试报告
        matrix=confusion_matrix(Y_Test, Y_pred, labels=range(n_classes))
        print(matrix)#矩阵评分
        return matrix

    def Pca_X(self,X_Test):
        """
        PCA 降维处理
        :param X_Test: 输入降维的数据
        :return: 降维处理后的数据
        """
        return self.pca.transform(X_Test)

    def Conv_Pooling(self,frame):
        """
        图像特征提取
        :param frame:卷积池化的图像
        :return:卷积池化后的图像20*20
        """
        # fil = np.array([[1, 1, 1], [1, -2, 1], [-1, -1, -1]])
        fil1 = np.array([[-1, -1, -1], [-1, 8, -1], [-1, -1, -1]])
        # fil2 = np.array([[1, 1, 1], [1, -8, 1], [1, 1, 1]])
        fil3 = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]])
        frame = cv2.filter2D(frame, -1, fil1)  # 卷积,高通滤波
        frame = cv2.resize(frame, (140, 140))  # 相当于池化
        frame = cv2.resize(frame, (80, 80))  # 相当于池化
        frame = cv2.filter2D(frame, -1, fil3)  # 卷积,边缘特征提取
        frame = cv2.resize(frame, (40, 40))
        frame = cv2.resize(frame, (20, 20))
        return frame

    def Prect(self,img):
        """
        对图像进行分类预测
        :param img: 输入待分类的图像
        :return:识别结果,0,1,2,3,4,5,6
        """
        X_Test=self.Conv_Pooling(img).reshape(400)
        X_Test=np.array([X_Test],dtype='float32')
        X_Test=self.Pca_X(X_Test)
        return self.clf.predict(X_Test)[0]

    def Load_Data(self,file):
        """
        从文件夹中读取图像,并进行特征提取转换
        :param file:训练数据总的文件名
        :return: 转换后的一维图像特征
        """
        listsx = []
        listsy = []
        for i in os.listdir(file):#目录分层,类别
            classfile = file + i + '/'
            for j in os.listdir(classfile):#定位到具体一个数据读取
                filename = classfile + j
                img = cv2.imread(filename, cv2.IMREAD_GRAYSCALE)
                Conv_out = self.Conv_Pooling(img)#卷积特征提取,缩放降维
                Conv_out = Conv_out.reshape(400)#二维转一维
                listsx.append(Conv_out)
                listsy.append(int(i))
        listsx = np.array(listsx, dtype='float32')
        return listsx, listsy

2、在通过3/7划分训练集和测试集,相关打印参数如下:

3、自己收集数据集手势数据集包含0,1,2,3,4,5,6数量分别为468,954,281,282,346,448,885 第6类是负样本:https://download.csdn.net/download/zx520113/12116992

4、参考:https://www.cnblogs.com/albert-yzp/p/9525162.html

5、总结:在实际应用中,手在空中运动的速度不同,后造成重影,会影响1与2,2与3,3与4之间的识别,0比划快了也会影响和1的识别,更多的将在后续中完善改进,增加数据集,把控好不同类别之间的特征关系。

6、简单的测试训练代码,需要根据自己的文件路径去修改。

# !usr/bin/python3
# -*- coding:utf-8 -*-
# author:SingWeek

from package import *
svm=SVM()#模型定义
x,y=svm.Load_Data("./TrainData/")#数据加载
x_train,x_test,y_train,y_test=svm.Split_Data(x,y,0.3)#数据切分
svm.Train_Pca(x)#训练
svm.Train(x_train,y_train)#训练
# svm.Load_Svm()
# svm.Load_Pca()
svm.Print_Score(x_test,y_test)#评分
#预测
img=cv2.imread("E:\\Write\\2\\879.jpg",cv2.IMREAD_GRAYSCALE)
img=svm.Conv_Pooling(img)
result=svm.Prect(img)
print(result)

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值