opencv::ml系列,支持向量机基础1

opencv::ml::svm,线性分类器示例

代码如下,该代码采用线性内核,根据示例的四个训练样本集训练分类器,并以此为基础将图像坐标各点作为待测试点

bool svmBasicExample() {

	Ptr<SVM> svm = SVM::create();//
	svm->setType(SVM::C_SVC);//类型,
	svm->setKernel(SVM::LINEAR);//核函数类型,注意其他核函数需要对应地进行参数设置
	//svm->setC(0.5);
	//svm->setGamma(1);//Exp,RBF核参数

	//算法终止条件,设置迭代终止条件
	svm->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 100, 1e-6));//一般包括误差条件和迭代次数

	//训练样本特征
	float trainingData[4][2]{//4个2维样本
		{501,10},{255,10},{501,255},{10,501}
	};
	Mat trainingDataMat(4, 2, CV_32FC1, trainingData);//样本数据必须存储为CV_32FC1类型,opencv3版本特点
	//标签
	int labels[4] = { 1.0,-1.0,-1.0,-1.0 };//opencv3的label从float调整为了int,否则会导致分类结果为无穷大
	Mat labelMat(4, 1, CV_32SC1, labels);
	//标签数据必须存储为CV_32SC1类型,opencv3从int转换
	Ptr<TrainData> tData = TrainData::create(trainingDataMat, ROW_SAMPLE, labelMat);

	//训练/保存/加载
	svm->train(tData);//训练

	//二维样本可显示
	constexpr int width = 512, height = 512;//constexpr,编译阶段可求值表达式
	cv::Mat imgShow = cv::Mat::zeros(height, width, CV_8UC3);
	const cv::Vec3b Green(0, 255, 0), Blue(255, 0, 0);
	for (int i = 0; i < imgShow.rows; ++i)    // 遍历的每个点作为测试点
	{
		for (int j = 0; j < imgShow.cols; ++j)
		{
			cv::Mat SampleMat = (cv::Mat_<float>(1, 2) << j, i);
			auto Response = svm->predict(SampleMat); 
			//需要注意,如果label没有转化为int类型,会导致预测结果类型问题
			if (Response == 1)
			{
				imgShow.at<cv::Vec3b>(i, j) = Green;
			}
			else if (Response == -1)
			{
				imgShow.at<cv::Vec3b>(i, j) = Blue;
			}
			//SVM默认将类别分为+1和-1
		}
	}
	// 标记训练点
	int Thinckness = -1;
	cv::circle(imgShow, cv::Point(501, 10), 5, cv::Scalar(0, 0, 0), Thinckness);
	cv::circle(imgShow, cv::Point(255, 10), 5, cv::Scalar(255, 255, 255), Thinckness);
	cv::circle(imgShow, cv::Point(501, 255), 5, cv::Scalar(255, 255, 255), Thinckness);
	cv::circle(imgShow, cv::Point(10, 501), 5, cv::Scalar(255, 255, 255), Thinckness);

	Thinckness = 2;
	//标记采用的支持向量
	Mat supportVectors = svm->getUncompressedSupportVectors();//获取未压缩支持向量
	for (int i = 0; i<supportVectors.rows; i++) {//注意是<rows
		auto vecTmp = supportVectors.ptr<float>(i);//读取supportVectors Mat中第i个数据坐标,数据类型为float(?),因为样本label给的是32FC1,也就是32bit的float,channel1,所以支持向量也是float格式
		cv::circle(imgShow, Point(static_cast<int>(vecTmp[0]), static_cast<int>(vecTmp[1])), 6, Scalar(128, 128, 128), Thinckness);
	}
	cv::imshow("svmExample", imgShow);
	cv::waitKey();

	return true;
}

部分函数补充说明:

setType参数:

 enum Types {
        C_SVC=100,//C_SVC,允许部分离群点,使用惩罚系数C进行约束;
        NU_SVC=101,//C_SVC的替代,nu在0-1之间nu_svc比c_svc更难于优化,且运行时间无法与c_svc相比;
        ONE_CLASS=102//分布估计,单类样本最小超球面拟合
        EPS_SVR=103,//支持向量回归
        NU_SVR=104//使用nu替代p
};

setKernel参数:

enum KernelTypes {
        CUSTOM=-1,//若存在自定义核,则返回自定义核
        LINEAR=0,//线性分类或回归
        POLY=1,//多项式核
        RBF=2,//RBF核,径向基函数高斯核,多数情况下最优
        SIGMOID=3,//sigmoid核,
        CHI2=4,//Chi2核,类似RBF核,
        INTER=5//直方图交叉核
    };

	svm->setGamma(1);//默认1,POLY/RBF/SIGMOID/CHI2
	svm->setC(1);//设置惩罚因子C,C_SVC/SVR,默认0
	svm->setDegree(0);//POLY核参数,默认0
	svm->setCoef0(1);//sigmoid/poly
	svm->setNu(0.5);//nu_SVC/nu_SVR/one_class
	svm->setP(0);//EPS_SVR

迭代终止条件
class CV_EXPORTS TermCriteria
{
public:
enum Type,终止条件类型,COUNT计次/EPS迭代算法所要求的精度或参数的变化
{
COUNT=1,
MAX_ITER=COUNT, //同上
EPS=2 //!< the desired accuracy or change in parameters at which the iterative algorithm stops
};

//默认构造函数
TermCriteria();//TermCriteria(0,0,0)
/**
@param type The type of termination criteria, one of TermCriteria::Type
@param maxCount The maximum number of iterations or elements to compute.
@param epsilon The desired accuracy or change in parameters at which the iterative algorithm stops.
*/
TermCriteria(int type, int maxCount, double epsilon);
int type; //!< the type of termination criteria: COUNT, EPS or COUNT + EPS
int maxCount; //!< the maximum number of iterations/elements
double epsilon; //!< the desired accuracy

};

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值