用SVM对自己的数据分类

参考http://blog.csdn.net/carson2005/article/details/6547250  数据和标签格式还是和上一篇Adaboost一样的

用的LINEAR线性的核类型

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/ml/ml.hpp>
#include "opencv2/imgproc/imgproc.hpp"  
#include <iostream>  
#include<algorithm>
#include<opencv2/opencv.hpp>
#include "time.h" 
using namespace std;
using namespace cv;
int main()
{
//开始计时
clock_t start, finish;
double duration;
start = clock();
// 样本
CvMLData cvmlprimer;
cvmlprimer.read_csv("featurewet.csv");
cv::Mat cvml = cv::Mat(cvmlprimer.get_values(), true);
CvMLData resprimer;
resprimer.read_csv("labelwet.csv");
cv::Mat res = cv::Mat(resprimer.get_values(), true);

//打乱顺序结果在stonevec[]和kuangvec[]两个数组里 图像标号
const int uselesssample = 358, usefulsample = 192, allsample = usefulsample + uselesssample, featurecol = 1000;
//打乱顺序 前uselesssample个为废石  后usefulsample个为矿
int stonevec[uselesssample], kuangvec[usefulsample];
for (int i = 0; i < uselesssample; i++)
stonevec[i] = i;
for (int i = 0; i <usefulsample; i++)
kuangvec[i] = uselesssample + i;
random_shuffle(stonevec, stonevec + uselesssample);
random_shuffle(kuangvec, kuangvec + usefulsample);
/saperate into trainset randomly
const float rate = 0.8;
int trainnum = int(uselesssample*rate) + int(usefulsample*rate), testnum = allsample - trainnum;
Mat traindata = Mat::zeros(trainnum, featurecol, cvml.type()), testdata = Mat::zeros(testnum, featurecol, cvml.type()), trainlabel = Mat::zeros(trainnum, 1, res.type()), testlabel = Mat::zeros(testnum, 1, res.type());
for (int i = 0; i <int(uselesssample*rate); i++)
{
float* newrow = traindata.ptr<float>(i);
int currentrow = stonevec[i];
float* primerow = cvml.ptr<float>(currentrow);
for (int j = 0; j < featurecol; j++)
newrow[j] = primerow[j];
float* newlabelrow = trainlabel.ptr<float>(i);
float* primerlabelrow = res.ptr<float>(currentrow);
newlabelrow[0] = primerlabelrow[0];
}
for (int i = int(uselesssample*rate); i <trainnum; i++)
{
float* newrow = traindata.ptr<float>(i);
int ii = i - int(uselesssample*rate);
int currentrow = kuangvec[ii];
float* primerow = cvml.ptr<float>(currentrow);
for (int j = 0; j < featurecol; j++)
newrow[j] = primerow[j];
float* newlabelrow = trainlabel.ptr<float>(i);
float* primerlabelrow = res.ptr<float>(currentrow);
newlabelrow[0] = primerlabelrow[0];
}
//saperate into testset 
for (int i = 0; i <uselesssample - int(uselesssample*rate); i++)
{
float* newrow = testdata.ptr<float>(i);
int iii = i + int(uselesssample*rate);
int currentrow = stonevec[iii];
float* primerow = cvml.ptr<float>(currentrow);
for (int j = 0; j < featurecol; j++)
newrow[j] = primerow[j];
float* newlabelrow = testlabel.ptr<float>(i);
float* primerlabelrow = res.ptr<float>(currentrow);
newlabelrow[0] = primerlabelrow[0];
}
for (int i = uselesssample - int(uselesssample*rate); i <testnum; i++)
{
int ii = int(usefulsample*rate) + i - (uselesssample - int(uselesssample*rate));
float* newrow = testdata.ptr<float>(i);
int currentrow = kuangvec[ii];
float* primerow = cvml.ptr<float>(currentrow);
for (int j = 0; j < featurecol; j++)
newrow[j] = primerow[j];
float* newlabelrow = testlabel.ptr<float>(i);
float* primerlabelrow = res.ptr<float>(currentrow);
newlabelrow[0] = primerlabelrow[0];
}
/train
cout << "Ready for Training ... " << endl;
// 设置SVM参数
CvSVMParams params;
params.svm_type = CvSVM::C_SVC;
//params.kernel_type = CvSVM::RBF;
//params.kernel_type = CvSVM::SIGMOID;
params.kernel_type = CvSVM::LINEAR;
//params.C= 0.1;  
params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 100, 1e-6);
// 对SVM进行训练
CvSVM SVM;
SVM.train(traindata, trainlabel, Mat(), Mat(), params);
cout << "training done!!!prepare for test..." << endl;
test
const int numfortest = testdata.rows;
Mat currentsample;
currentsample.create(1, featurecol, testdata.type());
float* outputlabels = new float[numfortest];   //动态数组可以避免必须写明确维度的麻烦  记得delete
for (int i = 0; i < numfortest; i++)
{
float* currentrow = testdata.ptr<float>(i);
for (int j = 0; j < featurecol; j++)
currentsample.at<float>(0, j) = currentrow[j];
float currentoutputs = SVM.predict(currentsample);//必须一个一个样本的进行测试
outputlabels[i] = currentoutputs;
//cout << currentoutputs << endl;
}
cout << "test done!!!prepare for calculating the accurency..." << endl << endl;
/calculate whole error 
int correct = 0;
float accurency;
for (int i = 0; i < testlabel.rows; ++i)
{
float* p = testlabel.ptr<float>(i);
cout << "true label= " << p[0] << " output label= " << outputlabels[i] << endl;
if (p[0] == outputlabels[i])
++correct;
}
cout << endl;
accurency = (float)correct / testlabel.rows;
cout << "whole accurency= " << accurency << endl;
/calculate the positive sample error and negative sample error
int alluseless = 0, uselesserror = 0, alluseful = 0, usefulerror = 0;
float stoneerror = 0, kuangerror = 0;
//stone error
for (int i = 0; i < testlabel.rows; ++i)
{
float* p = testlabel.ptr<float>(i);
if (p[0] == (float)1)
{
++alluseless;
if (p[0] != outputlabels[i])
++uselesserror;
}
}
cout << alluseless << "  " << uselesserror << endl;
stoneerror = (float)uselesserror / alluseless;
cout << " stone error= " << stoneerror << endl;
//kuang  error
for (int i = 0; i <testlabel.rows; ++i)
{
float* p = testlabel.ptr<float>(i);
if (p[0] == (float)2)
{
++alluseful;
if (p[0] != outputlabels[i])
++usefulerror;
}
}
cout << alluseful << "  " << usefulerror << endl;
kuangerror = (float)usefulerror / alluseful;
cout << " kuang error= " << kuangerror << endl;

delete[] outputlabels;
//结束计时  
finish = clock();
duration = (double)(finish - start) / CLOCKS_PER_SEC;
cout << "训练过程结束,共耗时:" << duration << "秒" << endl;
return 0;
}

可以是可以  可是准确率太低了  调参是门技术

参考http://blog.csdn.net/computerme/article/details/38677599自动寻优参数:

RBF核函数 自动寻参数最优哎。。。。。。。。。调参是门技术









另一个SVM程序:

#include<opencv2\opencv.hpp>
#include<opencv2\imgproc\imgproc.hpp>
#include<opencv2\highgui\highgui.hpp>
#include<fstream>
using namespace cv;
using namespace std;
#define cvQueryHistValue_1D( hist, idx0 )    ((float)cvGetReal1D( (hist)->bins, (idx0)))

Mat mypredone(IplImage* srcipl,vector<Mat> bgrimgs)
{
	//找轮廓
	Mat img(srcipl, 0);
	split(img, bgrimgs);
	Mat bimg(img.size(), CV_8UC1, cv::Scalar(0));
	bgrimgs[0].copyTo(bimg);
	threshold(bimg, bimg, 12, 255, CV_THRESH_BINARY/*|CV_THRESH_OTSU*/);
	Mat element(4, 4, CV_8U, cv::Scalar(1));
	morphologyEx(bimg, bimg, cv::MORPH_OPEN, element);
	for (int i = 0; i < 20; i++)
	{
		uchar* data = bimg.ptr<uchar>(i);
		for (int j = 0; j < bimg.size().width; j++)
			data[j] = 0;
	}
	//for (int i = bimg.size().height - 19; i < bimg.size().height; i++)
	//{
	//	uchar* data = bimg.ptr<uchar>(i);
	//	for (int j = 0; j < bimg.size().width; j++)
	//		data[j] = 0;
	//}
	return bimg;
}

Mat my_contour(IplImage* dst, IplImage bimgipl)
{
	cvZero(dst);
	CvMemStorage *storage = cvCreateMemStorage();
	CvSeq *contour = NULL, *hull = NULL;
	vector<CvPoint> allpoints;
	CvContourScanner scanner = cvStartFindContours(&bimgipl, storage);
	while ((contour = cvFindNextContour(scanner)) != NULL)
	{
		cvDrawContours(dst, contour, cv::Scalar(255), cv::Scalar(255), 0);
		hull = cvConvexHull2(contour, 0, CV_CLOCKWISE, 0);
		CvPoint pt0 = **(CvPoint**)cvGetSeqElem(hull, hull->total - 1);
		allpoints.push_back(pt0);
		for (int i = 0; i < hull->total; ++i)
		{
			CvPoint pt1 = **(CvPoint**)cvGetSeqElem(hull, i);
			allpoints.push_back(pt1);
			cvLine(dst, pt0, pt1, cv::Scalar(255));
			pt0 = pt1;
		}
	}
	//上面是第一次寻找 可能有多个凸包 下面存储每个凸包的凸点到容器中 方便我连线画图再寻找一次 也是最后的
	Mat dstmat(dst, 0);
	std::vector<std::vector<cv::Point>> myown_contours;
	cv::findContours(dstmat, myown_contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
	//cout << myown_contours.size() << endl;
	if (myown_contours.size() > 1)
	{
		for (int i = 0; i < allpoints.size() - 1; i++)
		{
			CvPoint firstdot = allpoints[i];
			CvPoint secdot = allpoints[i + 1];
			cvLine(dst, firstdot, secdot, cv::Scalar(255), 2);
		}
		CvContourScanner scanner2 = cvStartFindContours(dst, storage);
		while ((contour = cvFindNextContour(scanner2)) != NULL)
		{
			cvDrawContours(dst, contour, cv::Scalar(255), cv::Scalar(255), 0);
			hull = cvConvexHull2(contour, 0, CV_CLOCKWISE, 0);
			CvPoint pt0 = **(CvPoint**)cvGetSeqElem(hull, hull->total - 1);
			for (int i = 0; i < hull->total; ++i)
			{
				CvPoint pt1 = **(CvPoint**)cvGetSeqElem(hull, i);
				cvLine(dst, pt0, pt1, cv::Scalar(255));
				pt0 = pt1;
			}
		}
	}
	Mat bimgdst(dst, 0);
	std::vector<std::vector<cv::Point>> contours;
	cv::findContours(bimgdst, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
	Mat contoursimg(bimgdst.size(), CV_8UC1, cv::Scalar(0));
	drawContours(contoursimg, contours, -1, Scalar(255), CV_FILLED);
	return contoursimg;
}

void myfeatures(IplImage* srcipl,IplImage myresultipl,float features[])
{
	cvCvtColor(srcipl, srcipl, CV_BGR2Lab);
	IplImage* limg = cvCreateImage(cvGetSize(srcipl), srcipl->depth, 1);
	IplImage* aimg = cvCreateImage(cvGetSize(srcipl), srcipl->depth, 1);
	IplImage* bbimg = cvCreateImage(cvGetSize(srcipl), srcipl->depth, 1);
	cvSplit(srcipl, limg, aimg, bbimg, 0);
	//cvAnd(limg, &myresultipl, limg);
	cvAnd(aimg, &myresultipl, aimg);
	cvAnd(bbimg, &myresultipl, bbimg);
	//cvShowImage("a", aimg);
	//waitKey(0);
	/A B的直方图
	int histsize = 256;
	float range[] = { 0, histsize };
	float *ranges[] = { range };
	CvHistogram* hista = cvCreateHist(1, &histsize, CV_HIST_ARRAY, ranges, 1);
	cvCalcHist(&aimg, hista, 0, 0);
	cvNormalizeHist(hista, 1.0);
	CvHistogram* histb = cvCreateHist(1, &histsize, CV_HIST_ARRAY, ranges, 1);
	cvCalcHist(&bbimg, histb, 0, 0);
	cvNormalizeHist(histb, 1.0);
	//my features
	//float features[256*2];
	for (int i = 0; i < histsize; i++)
		features[i] = cvQueryHistValue_1D(hista, i);
	for (int i = histsize; i < 2 * histsize; i++)
		features[i] = cvQueryHistValue_1D(histb, i - histsize);
	//show hist img
	/*
	int scale= 2,height=256;
	IplImage* hist_img= cvCreateImage(cvSize(histsize* scale, height), 8, 3);
	cvZero(hist_img);
	float max_value= 0;
	cvGetMinMaxHistValue(histb, 0, &max_value, 0, 0);
	for (int i = 0; i < histsize; i++)
	{
	float bin_val = cvQueryHistValue_1D(histb, i);
	int intensity = cvRound(bin_val* height / max_value);
	cvRectangle(hist_img, cvPoint(i* scale, height - 1),
	cvPoint((i + 1)* scale - 1, height - intensity), cv::Scalar(255, 255, 255));
	}
	cvShowImage("aimg hist", hist_img);
	waitKey(0);
	*/
	/return features;
}

char filename[100];

void main()
{
	TickMeter tm;
	tm.start();

	/*   1 img test
	IplImage* src_ipl = cvLoadImage("1.bmp");
	vector<Mat> bgrimgs;
	Mat bimg = mypredone(src_ipl, bgrimgs);
	///
	IplImage mybimgipl = bimg;
	IplImage *mydst = cvCreateImage(cvGetSize(src_ipl), 8, 1);
	Mat myresult(mydst, 0);
	myresult = my_contour(mydst, mybimgipl);
	IplImage my_resultipl = myresult;
	/上面是找轮廓得到掩模 
	float myfeature[256 * 2];
	myfeatures(src_ipl, my_resultipl, myfeature);
	*/

	Mat featuremat(1657,256*2, CV_32FC1, cv::Scalar(0));
	//float* finalfeatures[1657];
	for (int i = 1; i <= 1657; i++)
	{
		sprintf(filename, "正常图_压缩\\%d.bmp", i);
		
		IplImage* src_ipl = cvLoadImage(filename);
		vector<Mat> bgrimgs;
		Mat bimg = mypredone(src_ipl, bgrimgs);
		///找轮廓得到掩模 
		IplImage mybimgipl = bimg;
		IplImage *mydst = cvCreateImage(cvGetSize(src_ipl), 8, 1);
		Mat myresult(mydst, 0);
		myresult = my_contour(mydst, mybimgipl);
		IplImage my_resultipl = myresult;
		//LAB图像与掩模与操作 得到掩模中的图像 特征
		float myfeature[256 * 2];
		myfeatures(src_ipl, my_resultipl, myfeature);
		//                          
		//finalfeatures[i - 1] = myfeature;   //每个图片的特征向量的指针放在这个数组中
	    //特征保存为mat   featuremat
		float* datarow = featuremat.ptr<float>(i - 1);
		for (int j = 0; j < featuremat.cols; j++)
			datarow[j] = float(myfeature[j]);
	}
	//label:res
	CvMLData resprimer;
	resprimer.read_csv("label.csv");
	cv::Mat label = cv::Mat(resprimer.get_values(), true);
	//saperate train and test data
	float rate = 0.6;
	Mat traindata = Mat::zeros(int(rate * 1657), 256 * 2, featuremat.type());
	//Mat traindata(int(rate * 1657), 256 * 2, CV_32FC1, cv::Scalar(0));
	Mat trainlabel = Mat::zeros(int(rate * 1657),1, label.type());
	//Mat trainlabel(int(rate * 1657), 1, CV_32SC1, cv::Scalar(0));
	//Mat testdata(1657 - int(rate * 1657), 256 * 2, CV_32FC1, cv::Scalar(0));
	Mat testdata = Mat::zeros(1657 - int(rate * 1657), 256 * 2, featuremat.type());
	//Mat testlabel(1657 - int(rate * 1657), 1, CV_32SC1, cv::Scalar(0));
	Mat testlabel = Mat::zeros(1657 - int(rate * 1657), 1, label.type());
	for (int i = 0; i < featuremat.rows; i++)
	{
		float* datarow = featuremat.ptr<float>(i);
		int* labelrow = label.ptr<int>(i);
		
		if (i < traindata.rows)
		{
			int* trainlabelrow = trainlabel.ptr<int>(i);
			trainlabelrow[0] = int(labelrow[0]);
			float* traindatarow = traindata.ptr<float>(i);
			for (int j = 0; j < featuremat.cols; j++)
				traindatarow[j] = datarow[j];
		}
		else
		{
			int newi = i - traindata.rows;
			int* testlabelrow = testlabel.ptr<int>(newi);
			testlabelrow[0] = labelrow[0];
			float* testdatarow = testdata.ptr<float>(newi);
			for (int j = 0; j < featuremat.cols; j++)
				testdatarow[j] = datarow[j];
		}
	}
	
	cout << "Ready for Training ... " << endl;
	CvSVMParams params;
	params.svm_type = CvSVM::C_SVC;
	CvSVM SVM;
	//
	//params.kernel_type = CvSVM::SIGMOID;
	//params.kernel_type = CvSVM::LINEAR;
	//params.C= 0.1;  
	//params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 100, 1e-6);
	//SVM.train(traindata, trainlabel, Mat(), Mat(), params);
	
	params.kernel_type = CvSVM::RBF;
	params.C = 0.1;  //给参数赋初始值  
	params.gamma = 0.01;  //给参数赋初始值  
	params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 100, 1e-6);
	//对不用的参数step设为0  
	CvParamGrid p = CvParamGrid(1, 1, 0.0);
	CvParamGrid nuGrid = CvParamGrid(1, 1, 0.0);
	CvParamGrid coeffGrid = CvParamGrid(1, 1, 0.0);
	CvParamGrid degreeGrid = CvParamGrid(1, 1, 0.0);
	CvMat traindata2 = traindata, trainlabel2 = trainlabel;
	CvMat* traindata3 = cvCreateMat(traindata2.rows, traindata2.cols, traindata2.type);
	cvCopy(&traindata2, traindata3);
	CvMat* trainlabel3 = cvCreateMat(trainlabel2.rows, trainlabel2.cols, trainlabel2.type);
	cvCopy(&trainlabel2, trainlabel3);
	SVM.train_auto(traindata3, trainlabel3, NULL, NULL, params, 10, SVM.get_default_grid(CvSVM::C), SVM.get_default_grid(CvSVM::GAMMA), p, nuGrid, coeffGrid, degreeGrid);
	CvSVMParams params_re = SVM.get_params();
	//SVM.save("auto_training_arguments.xml");
	float C = params_re.C;
	float gamma = params_re.gamma;
	printf("\nBest Parms: P=%f, gamma=%f \n", C, gamma);

	///
	cout << "training done!!!prepare for test..." << endl;
	test
	const int numfortest = testdata.rows;
	Mat currentsample;
	currentsample.create(1, 256*2, testdata.type());
	float* outputlabels = new float[numfortest];   //记得delete
	for (int i = 0; i < numfortest; i++)
	{
		float* currentrow = testdata.ptr<float>(i);
		for (int j = 0; j < 256*2; j++)
			currentsample.at<float>(0, j) = currentrow[j];
		float currentoutputs = SVM.predict(currentsample);//必须一个一个样本的进行测试
		outputlabels[i] = currentoutputs;
		//cout << currentoutputs << endl;
	}
	cout << "test done!!!prepare for calculating the accurency..." << endl << endl;
	/calculate whole error 
	int correct = 0;
	float accurency;
	for (int i = 0; i < testlabel.rows; ++i)
	{
		float* p = testlabel.ptr<float>(i);
		//cout << "true label= " << p[0] << " output label= " << outputlabels[i] << endl;
		if (p[0] == outputlabels[i])
			++correct;
	}
	cout << endl;
	accurency = (float)correct / testlabel.rows;
	cout << "whole accurency= " << accurency << endl;
	/calculate the positive sample error and negative sample error
	int alluseless = 0, uselesserror = 0, alluseful = 0, usefulerror = 0;
	float stoneerror = 0, kuangerror = 0;
	//stone error
	for (int i = 0; i < testlabel.rows; ++i)
	{
		float* p = testlabel.ptr<float>(i);
		if (p[0] == (float)0)
		{
			++alluseless;
			if (p[0] != outputlabels[i])
				++uselesserror;
		}
	}
	cout << "alluseless=" << alluseless << "  " << "uselesserror="<< uselesserror << endl;
	stoneerror = (float)uselesserror / alluseless;
	cout << " stone error= " << stoneerror << endl;
	//kuang  error
	for (int i = 0; i <testlabel.rows; ++i)
	{
		float* p = testlabel.ptr<float>(i);
		if (p[0] == (float)1)
		{
			++alluseful;
			if (p[0] != outputlabels[i])
				++usefulerror;
		}
	}
	cout << " alluseful=" << alluseful << "  " << "usefulerror=" << usefulerror << endl;
	kuangerror = (float)usefulerror / alluseful;
	cout << " kuang error= " << kuangerror << endl;
	
	delete[] outputlabels;
	
	
	tm.stop();
	cout << "count=" << tm.getCounter() << ",process time=" << tm.getTimeMilli() << endl;
}
整体是:

 首先提取轮廓 作为一个掩模 得到原图掩模处的图像 转化为Lab空间 求其a和b图的直方图 统计 作为这幅图的特征 然后用分类器去判别  我用的是svm RBF核 自动寻优参数 994张训练 663张测试 然而准确率只有63,.8%  。。。。。。。。

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

元气少女缘结神

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值