模式识别 - libsvm的函数调用方法 详解

libsvm的函数调用方法 详解

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

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

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

可以预测数据的概率, 则需要模型是概率模型, 返回的是一个类别数组(2分类, 则为2个值的数组), 即各个标签的概率值;

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

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

代码:

/*! @file
********************************************************************************
<PRE>
模块名 : 分类器
文件名 : SvmClassifier.cpp
相关文件 : SvmClassifier.h
文件实现功能 : SVM分类器类实现
作者 : C.L.Wang
Email: [email protected]
版本 : 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;
}

模式识别 - libsvm的函数调用方法 详解,布布扣,bubuko.com

时间: 2024-10-19 22:47:03

模式识别 - libsvm的函数调用方法 详解的相关文章

Android——onCreate( )方法详解(转)

android开发之onCreate( )方法详解 onCreate( )方法是android应用程序中最常见的方法之一,那么,我们在使用onCreate()方法的时候应该注意哪些问题呢? 先看看Google Android Developers官网上的解释: onCreate(Bundle) is where you initialize your activity. Most importantly, here you will usually call setContentView(int

C++调用JAVA方法详解

C++调用JAVA方法详解          博客分类: 本文主要参考http://tech.ccidnet.com/art/1081/20050413/237901_1.html 上的文章. C++调用JAVA主要用到了SUN公司的JNI技术, JNI是Java Native Interface的 缩写.从Java 1.1开始,Java Native Interface (JNI)标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互.相关资料见http://java.su

JavaScript原生对象属性和方法详解——Array对象 转载

length 设置或返回 数组中元素的数目. 注意:设置 length 属性可改变数组的大小.如果设置的值比其当前值小,数组将被截断,其尾部的元素将丢失.如果设置的值比它的当前值大,数组将增大,新的元素被添加到数组的尾部,它们的值为 undefined.所以length不一定代表数组的元素个数. var arr = new Array(3) arr[0] = "John" arr[1] = "Andy" arr[2] = "Wendy" cons

Python数据类型及其方法详解

Python数据类型及其方法详解 我们在学习编程语言的时候,都会遇到数据类型,这种看着很基础也不显眼的东西,却是很重要,本文介绍了python的数据类型,并就每种数据类型的方法作出了详细的描述,可供知识回顾. 一.整型和长整型 整型:数据是不包含小数部分的数值型数据,比如我们所说的1.2.3.4.122,其type为"int" 长整型:也是一种数字型数据,但是一般数字很大,其type为"long" 在python2中区分整型和长整型,在32位的机器上,取值范围是-2

【转】深入学习JavaScript: apply call方法 详解(转)

Js apply方法详解 原文:http://blog.csdn.net/myhahaxiao/article/details/6952321 我在一开始看到JavaScript的函数apply和call时,非常的模糊,看也看不懂,最近在网上看到一些文章对apply方法和call的一些示例,总算是看的有点眉目了,在这里我做如下笔记,希望和大家分享..  如有什么不对的或者说法不明确的地方希望读者多多提一些意见,以便共同提高.. 主要我是要解决一下几个问题: 1.        apply和cal

hbase-0.94安装方法详解

先决条件: 1)java环境,需要安装java1.6以上版本 2)hadoop环境,由于HBase架构是基于其他文件存储系统的,因此在分布式模式下安装Hadoop是必须的,但是,如果运行在单价模式下,此条件可以省略.Hadoop-1.2.1的安装方法参考 hadoop-1.2.1安装方法详解 注意:安装时要注意Hadoop和HBase之间的版本关系,如果不匹配,很可能会影响HBase系统的稳定性. 本帖教程采用的hadoop是hadoop-1.2.1,hbase采用的是hbase-0.94 hb

oc中字典的实现方法详解

一:字典的基本概念 Foundation中的字典(NSDictionary,NSMutableDictionary)是由键-值对组成的数据集合.正如,我们在字典里查找单词的定义一样. 通过key(键),查找的对应的value(值),key通常是字符串对象,也可以是其他任意类型对象.在一个字典对象中,key的值必须是唯一的. 此外,字典对象的键和值不可以为空(nil),如果需要在字典中加入一个空值,可以加入NSNull对象 二:不可变字典-NSDictionary 1:初始化(以一个元素和多个元素

57. 数对之差的最大值:4种方法详解与总结[maximum difference of array]

[本文链接] http://www.cnblogs.com/hellogiser/p/maximum-difference-of-array.html [题目] 在数组中,数字减去它右边的数字得到一个数对之差.求所有数对之差的最大值.例如在数组{2, 4, 1, 16, 7, 5, 11, 9}中,数对之差的最大值是11,是16减去5的结果. [分析] 看到这个题目,很多人的第一反应是找到这个数组的最大值和最小值,然后觉得最大值减去最小值就是最终的结果.这种思路忽略了题目中很重要的一点:数对之差

Java中的main()方法详解

在Java中,main()方法是Java应用程序的入口方法,也就是说,程序在运行的时候,第一个执行的方法就是main()方法,这个方法和其他的方法有很大的不同,比如方法的名字必须是main,方法必须是public static void 类型的,方法必须接收一个字符串数组的参数等等. 在看Java中的main()方法之前,先看一个最简单的Java应用程序HelloWorld,我将通过这个例子说明Java类中main()方法的奥秘,程序的代码如下: 1 /** 2 * Java中的main()方法