VS2017+OpenCV4.5.5 Adaboost-点分类

自适应提升(Adaptive Boosting,Adaboost)算法是一种迭代算法,其核心思想是针对同一个训练集训练不同的分类器(弱分类器),然后把这些弱分类器集合起来,构成一个更强的最终分类器(强分类器)。
主要步骤:

  1. 先通过对N个训练样本的学习得到第一个弱分类器
  2. 将分错的样本和其他的新数据一起构成一个新的N个的训练样本,通过对这个样本的学习得到第二个弱分类器
  3. 将1和2都分错了的样本加上其他的新样本构成另一个新的N个的训练样本,通过对这个样本的学习得到第三个弱分类器
  4. 最终经过提升的强分类器;即某个数据被分为哪一类要由各分类器权值决定。

由Adaboost算法的描述过程可知,该算法在实现过程中根据训练集的大小初始化样本权值,使其满足均匀分布,在后续操作中通过公式来改变和规范化算法迭代后样本的权值。样本被错误分类导致权值增大,反之权值相应减小,这表示被错分的训练样本集包括一个更高的权重。这就会使在下轮时训练样本集更注重于难以识别的样本,针对被错分样本的进一步学习来得到下一个弱分类器,直到样本被正确分类。在达到规定的迭代次数或者预期的误差率时,则强分类器构建完成。

OpenCV中使用决策树来得到弱分类器的。

测试用例:使用AdaBoost算法判断新的坐标(55,25)是属于红点还是绿点;

#include<iostream>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/core/core.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/ml/ml.hpp>

using namespace std;
using namespace cv;
using namespace cv::ml;

struct TrainData_s
{
    
    
	int x;
	int y;
	int label;
};
cv::Scalar color[4] = {
    
     {
    
    0,0,255}, {
    
    0, 255, 0}, {
    
    255,0,0}, {
    
    255,0,255} };

static bool readTestData(const char *path, Mat &trainDataMat, Mat &labelsMat, Mat &showImage) {
    
    

	// read maplist for warping
	FILE *fp_list_sec = fopen(path, "r+");
	if (!fp_list_sec) {
    
    
		printf("Error in open fp_list_sec from %s\n", path);
		return false;
	}

	int traindata_num = 0;
	int n = fscanf(fp_list_sec, "%d\n", &traindata_num);
	if (1 != n) {
    
    
		fclose(fp_list_sec);
		return false;
	}
	n = 3;
	trainDataMat = cv::Mat(traindata_num, n-1, CV_32FC1);
	labelsMat = cv::Mat(traindata_num,1, CV_32SC1);
	int index = 0;
	int x = 0;
	int y = 0;
	int label = 0;

	while (3 == n) {
    
    
		n = fscanf(fp_list_sec, "%d %d %d\n",&x, &y, &label);
		if (3 == n) {
    
    
			trainDataMat.ptr<float>(index)[0] = x;
			trainDataMat.ptr<float>(index)[1] = y;
			labelsMat.ptr<signed int>(index)[0] = label;
			index++;
			cv::circle(showImage, cv::Point(x, y), 0, color[label], 1, 8, 0);
		}
	}
	fclose(fp_list_sec);
	if (index != traindata_num) {
    
    
		printf("Attention: point number not equal to predefined num in file [%s]\n", path);
	}
	return true;
}

int main(int argc, char *argv[])
{
    
    
	//训练样本
	std::string data_path = "D:\\work\\vs2017project\\data\\test_data_adaboost.txt";
	cv::Mat trainDataMat, labelsMat;
	int rows = 80;
	int cols = 120;
	cv::Mat showImage(rows, cols, CV_8UC3, cv::Scalar(255, 255, 255));
	readTestData(data_path.data(), trainDataMat, labelsMat, showImage);
	//建立模型
	Ptr<Boost> boost = Boost::create();
	boost->setBoostType(Boost::GENTLE);
	boost->setWeakCount(100);
	boost->setWeightTrimRate(0.95);
	boost->setMaxDepth(2);
	boost->setUseSurrogates(false);
	boost->setPriors(Mat());
	//创建TrainData并进行训练
	Ptr<TrainData> tData = TrainData::create(trainDataMat, ROW_SAMPLE, labelsMat);
	boost->train(tData);
	float myData[2] = {
    
    55, 25};//测试样本
	Mat myDataMat(1, 2, CV_32FC1, myData);
	//利用训练好的分类器进行测试样本预测
	cv::Mat rMat;
	int r = (int)boost->predict(myDataMat, rMat, false);
	std::cout << "result: " << r << endl;
	cv::circle(showImage, cv::Point(myData[0], myData[1]), 1, color[r], -1);
	return 0;
}

预测结果:红色点
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/zfjBIT/article/details/129218760