zoukankan      html  css  js  c++  java
  • 模式识别

    libsvm该函数的调用方法 详细说明


    本文地址: http://blog.csdn.net/caroline_wendy/article/details/26261173


    须要载入(load)SVM的模型, 然后将结点转换为SVM的格式, 即索引(index)+数据(value)的形式;

    释放SVM的model有专用的函数: svm_free_and_destroy_model, 否则easy内存泄露;

    能够预測数据的概率, 则须要模型是概率模型, 返回的是一个类别数组(2分类, 则为2个值的数组), 即各个标签的概率值;

    注意: 标签即概率值较大的部分, 所以在训练时, 应注意正负样本的顺序

    正样本在前, 下标0, 为正样本的概率, 下标1, 为负样本的概率; 反之亦然.


    代码:

    /*! @file
    ********************************************************************************
    <PRE>
    模块名 : 分类器
    文件名称 : SvmClassifier.cpp
    相关文件 : SvmClassifier.h
    文件实现功能 : SVM分类器类实现
    作者 : C.L.Wang
    Email: morndragon@126.com
    版本号 : 1.0
    --------------------------------------------------------------------------------
    多线程安全性 : 是
    异常时安全性 : 是
    --------------------------------------------------------------------------------
    备注 : 无
    --------------------------------------------------------------------------------
    改动记录 :  
    日 期              版本号   改动人         改动内容 
    2014/03/27  1.0    C.L.Wang        Create
    </PRE>
    ********************************************************************************
    
    * 版权全部(c) C.L.Wang, 保留全部权利
    
    *******************************************************************************/
    
    #include "stdafx.h"
    
    #include "SvmClassifier.h"
    
    #include <opencv.hpp>
    
    using namespace std;
    using namespace cv;
    using namespace vd;
    
    const std::string SvmClassifier::NORM_NAME = "normalization.xml"; //归一化模型
    const std::string SvmClassifier::SVM_MODEL_NAME = "hvd.model"; //Svm模型
    bool SvmClassifier::m_mutex = true; //相互排斥锁
    
    /*! @function
    ********************************************************************************
    <PRE>
    函数名 : SvmClassifier
    功能 : 參数构造函数
    參数 : 
    const Mat& _videoFeature, 视频特征; 
    const string& _modelPath, 模型路径;
    返回值 : 无
    抛出异常 : 无
    --------------------------------------------------------------------------------
    复杂度 : 无
    备注 : 无
    典型使用方法 : SvmClassifier iSF(_videoFeature, _modelPath);
    --------------------------------------------------------------------------------
    作者 : C.L.Wang
    </PRE>
    *******************************************************************************/ 
    SvmClassifier::SvmClassifier (
    	const cv::Mat& _videoFeature, /*特征*/
    	const std::string& _modelPath /*模型路径*/
    	) :
    	Classifier(_videoFeature, _modelPath),
    	m_model(nullptr),
    	m_node(nullptr)
    {
    	return;
    }
    
    /*! @function
    ********************************************************************************
    <PRE>
    函数名 : ~SvmClassifier
    功能 : 析构函数
    參数 : void
    返回值 : 无
    抛出异常 : 无
    --------------------------------------------------------------------------------
    复杂度 : 无
    备注 : 无
    典型使用方法 : iSC.~SvmClassifier();
    --------------------------------------------------------------------------------
    作者 : C.L.Wang
    </PRE>
    *******************************************************************************/ 
    SvmClassifier::~SvmClassifier (void)
    {
    	if (m_model != nullptr) {
    		svm_free_and_destroy_model(&m_model);
    	}
    
    	if (m_node != nullptr) {
    		delete[] m_node;
    		m_node = nullptr;
    	}
    
    	return;
    }
    
    /*! @function
    ********************************************************************************
    <PRE>
    函数名 : calculateResult
    功能 : 计算分类结果
    參数 : void
    返回值 : const double, 分类结果
    抛出异常 : 无
    --------------------------------------------------------------------------------
    复杂度 : 无
    备注 : 无
    典型使用方法 : result = iSC.calculateResult();
    --------------------------------------------------------------------------------
    作者 : C.L.Wang
    </PRE>
    *******************************************************************************/ 
    const double SvmClassifier::calculateResult (void)
    {
    	double result(0.0);
    
    	while(1) {
    		if (m_mutex == true) 
    		{
    			m_mutex = false;
    			_initModel();
    
    			result = _predictValue();
    
    			if (m_model != nullptr) {
    				svm_free_and_destroy_model(&m_model);
    			}
    
    			if (m_node != nullptr) {
    				delete[] m_node;
    				m_node = nullptr;
    			}
    			m_mutex = true;
    			break;
    		}
    	}
    
    	return result;
    }
    
    /*! @function
    ********************************************************************************
    <PRE>
    函数名 : _predictValue
    功能 : 预測值
    參数 : void
    返回值 : const double, 预測值;
    抛出异常 : 无
    --------------------------------------------------------------------------------
    复杂度 : 无
    备注 : 无
    典型使用方法 : result = _predictValue();
    --------------------------------------------------------------------------------
    作者 : C.L.Wang
    </PRE>
    *******************************************************************************/ 
    const double SvmClassifier::_predictValue (void) const
    {
    	double label (0.0);
    	double prop (0.0);
    	const int nr_class (2);
    	double* prob_estimates = (double *) malloc(nr_class*sizeof(double));
    
    	label = svm_predict_probability(m_model, m_node, prob_estimates);
    	prop = prob_estimates[0]; //返回预測概率值
    
    	delete[] prob_estimates;
    
    	return prop;
    }
    
    /*! @function
    ********************************************************************************
    <PRE>
    函数名 : _initModel
    功能 : 初始化模型
    參数 : void
    返回值 : void
    抛出异常 : 无
    --------------------------------------------------------------------------------
    复杂度 : 无
    备注 : 无
    典型使用方法 : _initModel();
    --------------------------------------------------------------------------------
    作者 : C.L.Wang
    </PRE>
    *******************************************************************************/ 
    void SvmClassifier::_initModel (void)
    {
    	/*完整路径*/
    	
    	std::string modelName (m_modelPath); //模型名称
    	std::string normName (m_modelPath); //归一化名称
    
    	const std::string slash("/");
    
    	modelName.append(slash);
    	modelName.append(SVM_MODEL_NAME);
    
    	normName.append(slash);
    	normName.append(NORM_NAME);
    
    	std::ifstream ifs;
    	ifs.open(modelName, ios::in);
    	if (ifs.fail()) {
    		__printLog(std::cerr, "Failed to open the model file!");
    	}
    	ifs.close();
    
    	ifs.open(normName, ios::in);
    	if (ifs.fail()) {
    		__printLog(std::cerr, "Failed to open the model file!");
    	}
    	ifs.close();
    
    	if (m_model != nullptr) {
    		svm_free_and_destroy_model(&m_model);
    	}
    	m_model = svm_load_model(modelName.c_str());
    
    	__transSvmNode(normName);
    
    	return;
    }
    
    /*! @function
    ********************************************************************************
    <PRE>
    函数名 : __transSvmNode
    功能 : 转换Svm结点
    參数 : const string& normName, 归一化模型路径
    返回值 : void
    抛出异常 : 无
    --------------------------------------------------------------------------------
    复杂度 : 无
    备注 : 无
    典型使用方法 : __transSvmNode(normName);
    --------------------------------------------------------------------------------
    作者 : C.L.Wang
    </PRE>
    *******************************************************************************/ 
    void SvmClassifier::__transSvmNode (const std::string& _normName)
    {
    	cv::FileStorage fs(_normName, FileStorage::READ);
    	cv::Mat maxNorm;
    	fs["normalization"] >> maxNorm;
    	fs.release(); 
    
    	/*归一化视频特征*/
    
    	cv::Mat normFeature = 
    		cv::Mat::zeros(1, maxNorm.cols-2, CV_64FC1);
    
    	for (int j=2; j<m_videoFeature.cols; ++j) {
    		for(int i=0; i<m_videoFeature.rows; ++i) {
    			normFeature.at<double>(0, j-2) += m_videoFeature.at<double>(i, j);
    		}
    	}
    
    	for (int j=0; j<normFeature.cols; ++j)
    	{
    		normFeature.at<double>(0, j) /= m_videoFeature.rows;
    		if (maxNorm.at<double>(0, j+2) > 0.0001)
    			normFeature.at<double>(0, j) /= maxNorm.at<double>(0, j+2);
    	}
    	normFeature.at<double>(0,0) = 0.0;
    
    	if (m_node != nullptr) {
    		delete[] m_node;
    		m_node = nullptr;
    	}
    
    	m_node = new svm_node[normFeature.cols];
    	for (int j=1; j < normFeature.cols; ++j) {
    		m_node[j-1].index = j;
    		m_node[j-1].value = normFeature.at<double>(0, j);
    	}
    
    	m_node[normFeature.cols-1].index = -1;
    	m_node[normFeature.cols-1].value = 0;
    
    	return;
    }




    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    POJ-1189 钉子和小球(动态规划)
    POJ-1191-棋盘分割(动态规划)
    Java实现 LeetCode 730 统计不同回文子字符串(动态规划)
    Java实现 LeetCode 730 统计不同回文子字符串(动态规划)
    Java实现 LeetCode 729 我的日程安排表 I(二叉树)
    Java实现 LeetCode 729 我的日程安排表 I(二叉树)
    Java实现 LeetCode 729 我的日程安排表 I(二叉树)
    Java实现 LeetCode 728 自除数(暴力)
    Java实现 LeetCode 728 自除数(暴力)
    Java实现 LeetCode 728 自除数(暴力)
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4822214.html
Copyright © 2011-2022 走看看