OPENCV svm检测算法

本文通过两个实例演示如何使用OpenCV和C++实现支持向量机(SVM)训练及可视化,包括创建随机测试点、训练SVM模型、预测并显示支持向量等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/ml/ml.hpp"
#include <iostream>
using namespace cv;
using namespace std;
void drawCross(Mat &img, Point center, Scalar color)
{
	int col = center.x > 2 ? center.x : 2;
	int row = center.y> 2 ? center.y : 2;
	line(img, Point(col -2, row - 2), Point(col + 2, row + 2), color);  
	line(img, Point(col + 2, row - 2), Point(col - 2, row + 2), color);  
}

int newSvmTest(int rows, int cols, int testCount)
{
	if(testCount > rows * cols)
		return 0;

	Mat img = Mat::zeros(rows, cols, CV_8UC3);
	Mat testPoint = Mat::zeros(rows, cols, CV_8UC1);
	Mat data = Mat::zeros(testCount, 2, CV_32FC1);
	Mat res = Mat::zeros(testCount, 1, CV_32SC1);

	//Create random test points
	for (int i= 0; i< testCount; i++) 
	{ 
		int row = rand() % rows;
		int col = rand() % cols;

		if(testPoint.at<unsigned char>(row, col) == 0)
		{
			testPoint.at<unsigned char>(row, col) = 1;
			data.at<float>(i, 0) = float (col) / cols; 
			data.at<float>(i, 1) = float (row) / rows; 
		}
		else
		{
			i--;
			continue;
		}

		if (row > ( 50 * cos(col * CV_PI/ 100) + 200) )
		{ 
			drawCross(img, Point(col, row), CV_RGB(255, 0, 0));
			res.at<unsigned int>(i, 0) = 1; 
		} 
		else 
		{ 
			if (col > 200) 
			{ 
				drawCross(img, Point(col, row), CV_RGB(0, 255, 0));
				res.at<unsigned int>(i, 0) = 2; 
			} 
			else 
			{ 
				drawCross(img, Point(col, row), CV_RGB(0, 0, 255));
				res.at<unsigned int>(i, 0) = 3; 
			} 
		} 

	}

	//Show test points
	imshow("dst", img);
	waitKey(0);

	/////////////START SVM TRAINNING//////////////////
	CvSVM svm ;
	CvSVMParams param; 
	CvTermCriteria criteria;

	criteria= cvTermCriteria(CV_TERMCRIT_EPS, 1000, FLT_EPSILON); 
	param= CvSVMParams (CvSVM::C_SVC, CvSVM::RBF, 10.0, 8.0, 1.0, 10.0, 0.5, 0.1, NULL, criteria); 

	svm.train(data, res, Mat(), Mat(), param);

	for (int i= 0; i< rows; i++) 
	{ 
		for (int j= 0; j< cols; j++) 
		{ 
			Mat m = Mat::zeros(1, 2, CV_32FC1);
			m.at<float>(0,0) = float (j) / cols;
			m.at<float>(0,1) = float (i) / rows;

			float ret = 0.0; 
			ret = svm.predict(m); 
			Scalar rcolor; 

			switch ((int) ret) 
			{ 
			case 1: rcolor= CV_RGB(100, 0, 0); break; 
			case 2: rcolor= CV_RGB(0, 100, 0); break; 
			case 3: rcolor= CV_RGB(0, 0, 100); break; 
			} 

			line(img, Point(j,i), Point(j,i), rcolor);
		} 
	}

	imshow("dst", img);
	waitKey(0);

	//Show support vectors
	int sv_num= svm.get_support_vector_count(); 
	for (int i= 0; i< sv_num; i++) 
	{ 
		const float* support = svm.get_support_vector(i); 
		circle(img, Point((int) (support[0]*rows), (int) (support[1]*cols)), 5, CV_RGB(200, 200, 200)); 
		//这里为什么要乘上cols,还有rows那里为什么要乘上rows...这里没有看懂啊
	}

	imshow("dst", img);
	waitKey(0);

	return 0;
}
int another_svm()
{
	int width = 512,height = 512;
	//data for visualization Set up the training data The training data of this exercise is formed by a set of labeled 2D-points that belong to one of two different classes; one of the classes consists of one point and the other of three points.
	Mat image = Mat::zeros(height,width,CV_8UC3);
	//data for label;
	float labels[4] = { 1.0,-1.0,-1.0,-1.0};
	Mat labelsMat(4,1,CV_32FC1,labels);

	float trainingData[4][2] = {{501,10},{255,10},{501,255},{10,501}};
	Mat trainingDataMat(4,2,CV_32FC1,trainingData);

	//set up for svm
	CvSVMParams params;
	params.svm_type = CvSVM::C_SVC; //The important feature of the type of SVM CvSVM::C_SVC deals with imperfect separation of classes (i.e. when the training data is non-linearly separable). This feature is not important here since the data is linearly separable and we chose this SVM type only for being the most commonly used.
	params.kernel_type = CvSVM::LINEAR;
	params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER,100,1e-6);

	CvSVM svm;
	svm.train(trainingDataMat,labelsMat,Mat(),Mat(),params);

	Vec3b green(0,255,0),blue(255,0,0);
	for(int i =0 ;i < image.rows; i++)
	{
		for(int j = 0 ; j< image.cols;j ++)
		{
			Mat sampleMat = (Mat_<float>(1,2)<<j,i);
			float response = svm.predict(sampleMat);
			if(response == 1)
			{
				image.at<Vec3b>(i,j) = green; //不知道为什么,i,j的位置是不是这样的...
			}
			else
			{
				image.at<Vec3b>(i,j) = blue;
			}
		}
	}
	// Show support vectors
	int  thickness = 2;
	int lineType = 8;
/*
We use here a couple of methods to obtain information about the support vectors. The method
CvSVM::get_support_vector_count outputs the total number of support vectors used in the problem and with
the method CvSVM::get_support_vector we obtain each of the support vectors using an index. We have used
this methods here to find the training examples that are support vectors and highlight them.
*/
	int c = svm.get_support_vector_count();

	for (int i = 0; i < c; ++i)
	{
		const float *v = svm.get_support_vector(i);
		circle( image, Point( (int) v[0]*image.rows, (int) v[1]*image.cols), 6, Scalar(128, 128, 128), thickness, lineType);
	}
	namedWindow("result",1);
	imshow("result",image);
	waitKey(0);
	return 0;
}
int main(int argc, char** argv)
{
	return another_svm();
	//return newSvmTest(400, 600, 100);
}


总是感觉指导上是错的,在newSvmTest中有疑问的地方是 画图的时候 center的x,y坐标相应的乘以了rows,cols是为什么?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值