Head Pose Estimation:SVR训练

本文基于别人博客的整理,原文:

https://mp.weixin.qq.com/s/rY29GWzKOY0n73lD2M9dug

一、简介

1、导入feature和label txt数据↔OpenCV Mat类型

2、数据乱序处理

3、准备训练集和测试集

4、SVR训练

二、详介

1、导入feature和label txt数据↔OpenCV Mat类型

(1)txt文件数据格式如图所示:数据与数据之间以空格隔开,每一行以\r\n结尾

(2)具体代码如下:

void ReadTxtFileToMat(const std::string strFilePath, cv::Mat& mat)
{
    std::ifstream infile;
    infile.open(strFilePath, std::ios::in);
    if (!infile.is_open())
    {
        std::cerr << "Open " << strFilePath << " failed!" << std::endl;
        return;
    }

    for (int i = 0; i < mat.rows; i++)
    {
        for (int j = 0; j < mat.cols; j++)
        {
            infile >> mat.at<float>(i, j);
        }
    }

    infile.close();
}
void ReadMatToTxtFile(const cv::Mat& mat, std::string strFilePath)
{
	std::ofstream outfile;
	outfile.open(strFilePath, std::ios::out);

	for (int i = 0; i < mat.rows; i++) {
		for (int j = 0; j < mat.cols; j++) {
			outfile << mat.at<float>(i, j) << " ";
		}
		outfile << "\n";
	}
	outfile.close();
}

2、数据乱序处理

(1)代码如下:生成一个有序vector类型seeds,调用OpenCV randShuffle函数将其打乱,最后根据乱序的seeds去原数据取值

void ShuffleData(const cv::Mat& matFeature, const cv::Mat& matLabel, cv::Mat& matFeatureShuffled, cv::Mat& matLabelShuffled)
{
    if (matFeature.rows != matLabel.rows)
    {
        std::cerr << "WARNING: The feature length unequals the label length!" << std::endl;
        return;
    }

    std::vector<int> seeds;
    for (int i = 0; i < matFeature.rows; i++)
    {
        seeds.push_back(i);
    }
    cv::randShuffle(seeds);

    for (int i = 0; i < matFeature.rows; i++)
    {
        matFeatureShuffled.push_back(matFeature.row(seeds[i]));
        matLabelShuffled.push_back(matLabel.row(seeds[i]));
    }
}

3、准备训练集和测试集

(1)这个很简单,直接上代码:

void SplitData(cv::Mat& matData, cv::Mat& matDataTrain, cv::Mat& matDataTest, float fRate)
{
    int train_num = int(fRate * matData.rows);

    for (int i = 0; i < train_num; i++)
    {
        matDataTrain.push_back(matData.row(i));
    }

    for (int i = train_num; i < matData.rows; i++)
    {
        matDataTest.push_back(matData.row(i));
    }
}

4、SVR训练

float C[11] = { 0.01, 0.05, 0.1, 0.3, 0.5, 0.8, 1, 2, 5, 10, 50 };
float Nu[8] = { 0.01, 0.02, 0.05, 0.08, 0.1, 0.3, 0.5, 0.8 };

// 训练模型:pitch
std::cout << "Pitch: 训练模型初始化...\n";
cv::Ptr<cv::ml::SVM> svr_model_pitch = cv::ml::SVM::create();
svr_model_pitch->setKernel(cv::ml::SVM::LINEAR);
svr_model_pitch->setC(C[i]);
svr_model_pitch->setNu(Nu[j]);
svr_model_pitch->setType(cv::ml::SVM::NU_SVR);
svr_model_pitch->setTermCriteria(cv::TermCriteria(cv::TermCriteria::MAX_ITER + cv::TermCriteria::EPS, 10000, 1e-5));
std::cout << "Pitch: 开始训练...\n";
// 分别对pitch, yaw, roll进行训练,所以是label_train.col(0)
svr_model_pitch->train(data_train, cv::ml::ROW_SAMPLE, label_train.col(0));
std::cout << "Pitch: 训练结束...\n";

// 保存模型
std::cout << "保存模型: start...\n";
// 路径格式
sprintf_s(pitch_xml, "%s_C%1.2f_Nu%1.2f.xml", xml[0], C[i], Nu[j]);
svr_model_pitch->save(pitch_xml);
std::cout << "保存模型: end...\n";

// 测试模型
std::cout << "测试模型:start...\n";
cv::Mat predict_pitch;
svr_model_pitch->predict(data_test, predict_pitch);
std::cout << "测试模型:end...\n";

std::cout << "保存预测数据到txt文档:start...\n";
// 路径格式
sprintf_s(predict_pitch_txt, "%s_C%1.2f_Nu%1.2f.txt", predict[1], C[i], Nu[j]);
ReadMatToTxtFile(predict_pitch, predict_pitch_txt);
std::cout << "保存预测数据到txt文档:end...\n\n";

猜你喜欢

转载自blog.csdn.net/sinat_29634715/article/details/85835803