matlab的findpeaks找峰值函数C++实现

网上搜了一圈没有找到想要的C++复现findpeaks函数,由于项目需要,我只要使用findpeaks里的'MinPeakProminence'和'MinPeakWidth',因此本代码的输入参数只包括最小峰值高度'minHeight',最小峰值突出度'MinPeakProminence'和最小峰宽'MinPeakWidth'。

 findpeaks.h文件:

#include <vector>
#include <iostream>
#include <opencv2/opencv.hpp>

using  namespace std;
struct Peak {
    int index;
    double value;
    int width; // 峰值宽度
    double prominence; // 峰值突出度
};

// 函数声明
void findPeaks(const cv::Mat& data, std::vector<Peak>& peaks, double minHeight, int minWidth, double minProminence);

findpeaks.cpp文件:

#include <iostream>
#include <vector>
#include"findpeaks.h"


// 找峰值的函数定义
void findPeaks(const cv::Mat& data, std::vector<Peak>& peaks, double minHeight, int minWidth, double minProminence) {
    peaks.clear();  // 清空峰值数组

    for (int i = 1; i < data.cols - 1; ++i) {
        // 判断是否为峰值,即比相邻的两个点大,并且大于设定的最小高度
        if (data.at<double>(0, i) > minHeight &&
            data.at<double>(0, i) > data.at<double>(0, i - 1) &&
            data.at<double>(0, i) > data.at<double>(0, i + 1)) {
            // 寻找峰值的宽度,即峰值到其两侧的极小值点的距离
            int left = i-1;
            while (left >= 0 && data.at<double>(0, left) < data.at<double>(0, left + 1)) {
                --left;
            }

            int right = i+1;
            while (right < data.cols && data.at<double>(0, right) < data.at<double>(0, right - 1)) {
                ++right;
            }

            // 计算峰值的宽度和突出度
            int width = right - left -2;
            double prominence = data.at<double>(0, i) - std::max(data.at<double>(0, left+1), data.at<double>(0, right-1));

            // 判断峰值的宽度和突出度是否满足设定的条件
            if (width >= minWidth && prominence > minProminence) {
                peaks.push_back({ i, data.at<double>(0, i), width, prominence });
            }
        }
    }
}

根据自己的数据可以自行更改输入数据类型,我这里是Mat类型。函数输出峰值点的索引index和数值value,和matlab不太一样的是:matlab里‘MinPeakWidth’指的是半宽,这里我的函数指的是全宽。可以利用一个if语句自行改成半宽。测试代码如下:

#include <iostream>
#include <opencv2/opencv.hpp>
#include"findpeaks.h"
using namespace std;

int main3() {
    // 创建一个 Mat 对象,代表一维数据
    cv::Mat data = (cv::Mat_<double>(1, 11) << 1.0, 3.0, 2.0, 5.0, 2.0, 7.0, 2.0, 2.0, 8.0, 2.0, 1.0);

    // 存储峰值的结构体
    std::vector<Peak> peakInfo;

    // 设定最小峰值高度、最小峰值宽度和最小峰值突出度
    double minHeight = 2.0;
    int minWidth = 3;
    double minProminence = 5.0;

    // 调用找峰值的函数
    findPeaks(data, peakInfo, minHeight, minWidth, minProminence);

    // 输出峰值的索引和值
    std::cout << "Peak Indices and Values: ";
    for (const Peak& peak : peakInfo) {
        std::cout << "(" << peak.index << ", " << peak.value << ") ";
    }

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值