#include #include #include #include #include #include #include using namespace std; // 定义一个结构体来保存每一行的值 struct TargetData { int id; double x, y, width, height; }; // 读取日志文件并提取目标数据 vector readLogFile(const string& filepath) { vector data; ifstream file(filepath); string line; // 正则表达式来匹配Target ID后的五个值 regex targetRegex("Target ID: (-?\\d+),\\s*(-?\\d+),\\s*(-?\\d+),\\s*(-?\\d+),\\s*(-?\\d+)"); while (getline(file, line)) { smatch matches; if (regex_search(line, matches, targetRegex)) { TargetData target; target.id = stoi(matches[1].str()); target.x = stod(matches[2].str()); target.y = stod(matches[3].str()); target.width = stod(matches[4].str()); target.height = stod(matches[5].str()); data.push_back(target); } } return data; } // 清洗数据,去掉横坐标小于100或大于600的数据,以及极端值 void cleanData(vector& data, double n) { // 计算平均值 double sum = 0; for (const auto& target : data) { sum += target.width; } double mean = sum / data.size(); // 计算标准差 double variance = 0; for (const auto& target : data) { variance += pow(target.width - mean, 2); } double stddev = sqrt(variance / data.size()); // 根据误差系数范围n清洗数据 vector cleanedData; for (const auto& target : data) { // 添加条件,去掉横坐标小于100或大于600的数据 if (target.x >= 100 && target.x <= 600 && abs(target.width - mean) <= n * stddev) { cleanedData.push_back(target); } } data = cleanedData; } // 用最小二乘法来计算线性回归的参数 (width = a * y + b) void fitLinearModel(const vector& data, double& a, double& b) { int n = data.size(); double sum_y = 0, sum_width = 0, sum_yy = 0, sum_yw = 0; // 计算所需的累加和 for (const auto& target : data) { sum_y += target.y; sum_width += target.width; sum_yy += target.y * target.y; sum_yw += target.y * target.width; } // 计算线性回归的系数 a 和 b double denominator = n * sum_yy - sum_y * sum_y; if (denominator == 0) { a = 0; b = 0; return; } a = (n * sum_yw - sum_y * sum_width) / denominator; b = (sum_yy * sum_width - sum_y * sum_yw) / denominator; } // 输出拟合结果 void printFitEquation(double a, double b) { cout << "拟合结果: width = " << a << " * y + " << b << endl; } // 打印data中的所有数据 void printData(const vector& data) { for (const auto& target : data) { cout << "ID: " << target.id << ", x: " << target.x << ", y: " << target.y << ", width: " << target.width << ", height: " << target.height << endl; } } int main(int argc, char* argv[]) { if (argc < 3) { cout << "使用方法: " << argv[0] << " <日志文件路径> <误差系数范围>" << endl; return 1; } string logFilePath = argv[1]; double n = stod(argv[2]); // 误差系数范围 // 读取日志文件中的目标数据 vector data = readLogFile(logFilePath); // 数据清洗 cleanData(data, n); // 打印清洗后的数据 cout << "\n清洗后的数据:" << endl; printData(data); // 使用最小二乘法拟合数据 double a, b; fitLinearModel(data, a, b); // 输出拟合的函数公式 printFitEquation(a, b); return 0; }