C++优化曲线方法

数据平滑处理

包括去差值、线性平滑

去差值

五点去差值法是一种常用的数据平滑处理方法,它的基本思想是选取周围五个点,去掉最大值和最小值,然后求剩余三个点的平均值,使得相邻点变得平滑。先找到这五个元素中的最大值和最小值,然后将它们从这五个元素中移除,最后计算剩余三个元素的平均值。

#include <algorithm>
#include <vector>

void fivePointDifference(std::vector<double>& data) {
    std::vector<double> result(data.size());
    for (int i = 2; i < data.size() - 2; i++) {
        std::vector<double> temp(data.begin() + i - 2, data.begin() + i + 3);
        std::sort(temp.begin(), temp.end());
        result[i] = (temp[1] + temp[2] + temp[3]) / 3.0;
    }
    data = result;
}

这个函数现在会处理data中的每一个元素,包括前两个和最后两个元素。对于每一个元素,它都会取出该元素及其周围最多四个元素,并将它们存储在临时向量temp中。然后,它会对temp进行排序,并计算中间元素的平均值。如果temp中只有三个或四个元素(即当我们处理数组的前两个和最后两个元素时),我们就计算这些元素(除了最大值)的平均值。

#include <algorithm>
#include <vector>

void fivePointDifference(std::vector<double>& data) {
    std::vector<double> result(data.size());
    for (int i = 0; i < data.size(); i++) {
        std::vector<double> temp;
        for (int j = std::max(0, i - 2); j <= std::min(static_cast<int>(data.size()) - 1, i + 2); j++) {
            temp.push_back(data[j]);
        }
        std::sort(temp.begin(), temp.end());
        if (temp.size() == 5) {
            result[i] = (temp[1] + temp[2] + temp[3]) / 3.0;
        } else {
            result[i] = temp[0];
            for (int j = 1; j < temp.size() - 1; j++) {
                result[i] += temp[j];
            }
            result[i] /= temp.size() - 1;
        }
    }
    data = result;
}

十点去差值法同理,选择周围十个点,去掉最大值和最小值,然后求剩余八个点的平均值。

#include <algorithm>
#include <vector>

void tenPointDifference(std::vector<double>& data) {
    std::vector<double> result(data.size());
    for (int i = 0; i < data.size(); i++) {
        std::vector<double> temp;
        for (int j = std::max(0, i - 5); j <= std::min(static_cast<int>(data.size()) - 1, i + 5); j++) {
            temp.push_back(data[j]);
        }
        std::sort(temp.begin(), temp.end());
        if (temp.size() == 11) {
            result[i] = 0;
            for (int j = 1; j < temp.size() - 1; j++) {
                result[i] += temp[j];
            }
            result[i] /= 8.0;
        } else {
            result[i] = temp[0];
            for (int j = 1; j < temp.size() - 1; j++) {
                result[i] += temp[j];
            }
            result[i] /= temp.size() - 2;
        }
    }
    data = result;
}

这是100点去差值法,根据你的实际情况来应用不同的数据处理场景。

#include <algorithm>
#include <vector>

void hundredPointDifference(std::vector<double>& data) {
    std::vector<double> result(data.size());
    for (int i = 49; i < data.size() - 49; i++) {
        std::vector<double> temp(data.begin() + i - 49, data.begin() + i + 50);
        std::sort(temp.begin(), temp.end());
        double sum = 0;
        for (int j = 1; j < temp.size() - 1; j++) {
            sum += temp[j];
        }
        result[i] = sum / 98.0;
    }
    for (int i = 0; i < 49; i++) {
        result[i] = data[i];
        result[data.size() - 1 - i] = data[data.size() - 1 - i];
    }
    
    data = result;
}

线性平滑

线性五点平滑是一种常用的数据平滑处理方法,它的基本思想是对每个数据点及其周围四个点进行加权平均,使得相邻点变得平滑。然后遍历数组中的每个元素,并对每个元素及其周围的四个元素进行处理。你可以先找到这五个元素中的最大值和最小值,然后将它们从这五个元素中移除,最后计算剩余三个元素的加权平均值。

#include <vector>

void linearFivePointSmoothing(std::vector<double>& data) {
    std::vector<double> result(data.size());
    for (int i = 2; i < data.size() - 2; i++) {
        result[i] = (data[i - 2] + data[i - 1]*2 + data[i]*3 + data[i + 1]*2 + data[i + 2]) / 9.0;
    }
    result[0] = data[0];
    result[1] = (data[0] + data[1]*2 + data[2]*3) / 6.0;
    result[data.size() - 2] = (data[data.size() - 3]*3 + data[data.size() - 2]*2 + data[data.size() - 1]) / 6.0;
    result[data.size() - 1] = data[data.size() - 1];
    
    data = result;
}

十点平滑同理,每个数据点及其周围九个点进行加权平均,使得相邻点变得平滑,遍历数组中的每个元素,并对每个元素及其周围的九个元素进行处理。具体来说,找到这十个元素中的最大值和最小值,然后将它们从这十个元素中移除,最后计算剩余八个元素的加权平均值。

#include <vector>

void linearTenPointSmoothing(std::vector<double>& data) {
    std::vector<double> result(data.size());
    for (int i = 4; i < data.size() - 4; i++) {
        result[i] = (data[i - 4] + data[i - 3]*2 + data[i - 2]*3 + data[i - 1]*4 + data[i]*5 + data[i + 1]*4 + data[i + 2]*3 + data[i + 3]*2 + data[i + 4]) / 25.0;
    }
    result[0] = data[0];
    result[1] = (data[0] + data[1]*2 + data[2]*3 + data[3]*4) / 10.0;
    result[2] = (data[0] + data[1]*2 + data[2]*3 + data[3]*4 + data[4]*5) / 15.0;
    result[3] = (data[0] + data[1]*2 + data[2]*3 + data[3]*4 + data[4]*5 + data[5]*4) / 19.0;
    result[data.size() - 4] = (data[data.size() - 6]*4 + data[data.size() - 5]*5 + data[data.size() - 4]*4 + data[data.size() - 3]*3 + data[data.size() - 2]*2 + data[data.size() - 1]) / 19.0;
    result[data.size() - 3] = (data[data.size() - 5]*5 + data[data.size() - 4]*4 + data[data.size() - 3]*3 + data[data.size() - 2]*2 + data[data.size() - 1]) / 15.0;
    result[data.size() - 2] = (data[data.size() - 4]*4 + data[data.size() - 3]*3 + data[data.size() - 2]*2 + data[data.size() - 1]) / 10.0;
    result[data.size() - 1] = data[data.size() - 1];
    
    data = result;
}

一百点平滑,遍历数组中的每个元素,并对每个元素及其周围的九十九个元素进行处理。具体来说,先找到这一百个元素中的最大值和最小值,然后将它们从这一百个元素中移除,最后计算剩余九十八个元素的加权平均值。

#include <vector>

void linearHundredPointSmoothing(std::vector<double>& data) {
    std::vector<double> result(data.size());
    for (int i = 49; i < data.size() - 49; i++) {
        double sum = 0;
        for (int j = i - 49; j <= i + 49; j++) {
            sum += data[j];
        }
        result[i] = sum / 99.0;
    }
    for (int i = 0; i < 49; i++) {
        result[i] = data[i];
        result[data.size() - 1 - i] = data[data.size() - 1 - i];
    }
    data = result;
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在OpenCV中,可以使用最小二乘法进行曲线拟合。最小二乘法是一种数学优化方法,通过最小化实际观测值与拟合曲线之间的残差平方和来求解拟合曲线的参数。在拟合曲线时,可以使用多项式函数来逼近实际的曲线形状。 具体而言,在OpenCV中,可以通过使用函数`cv::polyfit`来进行多项式拟合。该函数可以根据给定的数据点和多项式的次数,求解出拟合曲线的系数。然后,可以使用这些系数来生成拟合曲线。 例如,使用以下引用中给出的资料,可以参考博客园上的文章《opencv 曲线拟合 - 无左无右》和CSDN上的文章《最小二乘法多项式曲线拟合原理与实现》,了解更多关于OpenCV中曲线拟合的实现原理和方法。 引用: [《opencv 曲线拟合 - 无左无右 - 博客园》](https://blog.csdn.net/jairuschan/article/details/7517773/) 引用: [《最小二乘法多项式曲线拟合原理与实现》](https://www.cnblogs.com/yanghailin/p/15724647.html) 通过引用的资料,你可以了解到在OpenCV中使用最小二乘法进行曲线拟合的具体步骤和代码实现。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [opencv 曲线拟合](https://blog.csdn.net/yang332233/article/details/122120160)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [C++ opencv曲线拟合](https://blog.csdn.net/qq_40622955/article/details/120432313)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值