赞
踩
网上搜了一圈没有找到想要的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;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。