网上搜了一圈没有找到想要的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;
}