2021-07-25 C++ opencv knn

1/原文连接 矩阵匹配
knn 行列数组操作

#include "opencv2\opencv.hpp"
#include <iostream>
using namespace std;
using namespace cv;
using namespace cv::ml;

int main()
{
Mat img = imread("digitals.png");
Mat gray;
cvtColor(img, gray, CV_BGR2GRAY);
int b = 20;
int m = gray.rows / b;   //原图为1000*2000
int n = gray.cols / b;   //裁剪为5000个20*20的小图块
Mat data, labels;   //特征矩阵
for (int i = 0; i < n; i++)
{
	int offsetCol = i*b; //列上的偏移量
	for (int j = 0; j < m; j++)
	{
		int offsetRow = j*b;  //行上的偏移量
							  //截取20*20的小块
		Mat tmp;
		gray(Range(offsetRow, offsetRow + b), Range(offsetCol, offsetCol + b)).copyTo(tmp);
		data.push_back(tmp.reshape(0, 1));  //序列化后放入特征矩阵
		labels.push_back((int)j / 5);  //对应的标注
	}

}
data.convertTo(data, CV_32F); //uchar型转换为cv_32f
int samplesNum = data.rows;
int trainNum = 3000;
Mat trainData, trainLabels;
trainData = data(Range(0, trainNum), Range::all());   //前3000个样本为训练数据
trainLabels = labels(Range(0, trainNum), Range::all());

//使用KNN算法
int K = 5;
Ptr<TrainData> tData = TrainData::create(trainData, ROW_SAMPLE, trainLabels);
Ptr<KNearest> model = KNearest::create();
model->setDefaultK(K);
model->setIsClassifier(true);
model->train(tData);

//svm分类
Ptr<SVM> svm = SVM::create();//SVM分类器
svm->setType(SVM::C_SVC);
svm->setC(0.01);
svm->setKernel(SVM::LINEAR);
svm->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 3000, 1e-6));
std::cout << "Starting training..." << endl;
svm->train(trainData, ROW_SAMPLE, trainLabels);
//训练分类器 	
std::cout << "Finishing training..." << endl;
//将训练好的SVM模型保存为xml文件 	
svm->SVM::save("SVM_HOG.xml");



//Ann分类
Ptr<ANN_MLP> ann = ANN_MLP::create();
Mat layerSizes = (Mat_<int>(1, 5) << 400, 128, 128, 128, 10);
ann->setLayerSizes(layerSizes);
ann->setTrainMethod(ANN_MLP::BACKPROP, 0.001, 0.1);
ann->setActivationFunction(ANN_MLP::SIGMOID_SYM, 1.0, 1.0);
ann->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER | TermCriteria::EPS, 10000, 0.0001));

Ptr<TrainData> trainDatas = TrainData::create(trainData, ROW_SAMPLE, trainLabels);
ann->train(trainDatas);
//保存训练结果
ann->save("MLPModel.xml");







//预测分类
double train_hr = 0, test_hr = 0;
Mat response;
// compute prediction error on train and test data
for (int i = 0; i < samplesNum; i++)
{
	Mat sample = data.row(i);
	float r = model->predict(sample);   //对所有行进行预测
										//预测结果与原结果相比,相等为1,不等为0
	r = std::abs(r - labels.at<int>(i)) <= FLT_EPSILON ? 1.f : 0.f;

	if (i < trainNum)
		train_hr += r;  //累积正确数
	else
		test_hr += r;
}

test_hr /= samplesNum - trainNum;
train_hr = trainNum > 0 ? train_hr / trainNum : 1.;

printf("accuracy: train = %.1f%%, test = %.1f%%\n",
	train_hr*100., test_hr*100.);







//svm分类
double svmtrain_hr = 0, svmtest_hr = 0;
//Mat svmresponse;
// compute prediction error on train and test data
for (int i = 0; i < samplesNum; i++)
{
	Mat sample = data.row(i);
	float r =svm->predict(sample);   //对所有行进行预测
										//预测结果与原结果相比,相等为1,不等为0
	r = std::abs(r - labels.at<int>(i)) <= FLT_EPSILON ? 1.f : 0.f;

	if (i < trainNum)
		svmtrain_hr += r;  //累积正确数
	else
		svmtest_hr += r;
}

svmtest_hr /= samplesNum - trainNum;
train_hr = trainNum > 0 ? svmtrain_hr / trainNum : 1.;

printf("accuracy: train = %.1f%%, test = %.1f%%\n",
	svmtrain_hr*100., svmtest_hr*100.);


//ann分类
//预测分类
double anntrain_hr = 0, anntest_hr = 0;
//Mat response;
// compute prediction error on train and test data
for (int i = 0; i < samplesNum; i++)
{
	Mat sample = data.row(i);
	float r = model->predict(sample);   //对所有行进行预测
										//预测结果与原结果相比,相等为1,不等为0
	r = std::abs(r - labels.at<int>(i)) <= FLT_EPSILON ? 1.f : 0.f;

	if (i < trainNum)
		anntrain_hr += r;  //累积正确数
	else
		anntest_hr += r;
}

anntest_hr /= samplesNum - trainNum;
anntrain_hr = trainNum > 0 ? anntrain_hr / trainNum : 1.;

printf("accuracy: train = %.1f%%, test = %.1f%%\n",
	anntrain_hr*100., anntest_hr*100.);

waitKey(0);
getchar();
return 0;

}

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
OpenCV是一个开源的计算机视觉库,提供了许多用于处理图像和视频的函数和算法。其中之一就是K最近邻(KNN)分类算法。 KNN是一种监督学习算法,用于分类任务。它的基本思想是根据已知的训练样本,通过计算样本之间的距离来确定一个测试样本的类别。 下面是一个使用OpenCV实现KNN分类算法的示例代码: ```c #include <opencv2/opencv.hpp> #include <iostream> int main() { // 加载训练样本 cv::Mat trainData = (cv::Mat_<float>(4, 2) << 2, 4, 4, 2, 4, 4, 6, 2); cv::Mat trainLabels = (cv::Mat_<int>(4, 1) << 0, 0, 1, 1); // 创建KNN分类器对象 cv::Ptr<cv::ml::KNearest> knn = cv::ml::KNearest::create(); // 训练,传入训练数据和对应的标签 knn->train(trainData, cv::ml::ROW_SAMPLE, trainLabels); // 创建测试样本 cv::Mat testData = (cv::Mat_<float>(1, 2) << 6, 6); // 预测测试样本的类别 cv::Mat results, neighborResponses, dists; float response = knn->findNearest(testData, 3, results, neighborResponses, dists); // 打印预测结果 std::cout << "Predicted class: " << response << std::endl; return 0; } ``` 以上代码中,首先加载了4个训练样本,每个样本有2个特征。然后创建了一个KNN分类器对象,进行训练。接着创建了一个测试样本,使用KNN分类器进行预测,预测结果存储在response变量中。最后将预测结果打印出来。 需要注意的是,以上代码只是一个简单的示例,实际使用KNN分类器时,可能需要更多的训练样本和特征,并进行参数调优等操作。希望以上回答对您有所帮助。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值