c++仿写小波分解和去噪代码(只使用基础库)

news2024/12/24 10:59:21

小波分解C++版本

C++代码

参考了一些Github的代码
最终代码可从链接下载。
main函数如果打不开的话,使用

#include <iostream>
#include <vector>
#include <fstream>
#include "wavelet.h"

int main() {
    // 读取原始信号数据
    std::ifstream input("MultiSinWaveWithNoise_1s.txt");
    if (!input.is_open()) {
        std::cerr << "Failed to open input file." << std::endl;
        return 1;
    }

    std::vector<double> original_signal;
    double value;
    while (input >> value) {
        original_signal.push_back(value);
    }
    input.close();

    // 初始化小波对象,使用 db4 小波,从matlab导出
    std::vector<double> Hi_D = { -0.230377813308855,0.714846570552542,-0.630880767929590,-0.027983769416984,0.187034811718881,0.030841381835987,-0.032883011666983,-0.010597401784997 };
    std::vector<double> Hi_R = { -0.010597401784997,-0.032883011666983,0.030841381835987,0.187034811718881,-0.027983769416984,-0.630880767929590,0.714846570552542,-0.230377813308855 };
    std::vector<double> Lo_D = { -0.010597401784997,0.032883011666983,0.030841381835987,-0.187034811718881,-0.027983769416984,0.630880767929590,0.714846570552542,0.230377813308855 };
    std::vector<double> Lo_R = { 0.230377813308855,0.714846570552542,0.630880767929590,-0.027983769416984,-0.187034811718881,0.030841381835987,0.032883011666983,-0.010597401784997 };

    Wavelet<double> wavelet(Lo_D, Hi_D, Lo_R, Hi_R);

    // 进行小波分解
    int levels = 3; //5;
    Decomposition1D<double> decomposition = wavelet.Wavedec(original_signal, levels);

    // 对细节系数进行软阈值去噪,阈值设为1或0.5等,根据实际情况调整

    double threshold_V01 = 1; // 0.5;

    for (size_t i = 0; i < decomposition.NumLevels(); ++i) {
        std::vector<double> detcoef = decomposition.GetDetcoef(i);
        for (size_t j = 0; j < detcoef.size(); ++j) {
            if (std::abs(detcoef[j]) < threshold_V01) {
                detcoef[j] = 0.0;
            }
        }
        decomposition.SetDetcoef(detcoef, i);
    }

    // 重构信号
    std::vector<double> denoised_signal = wavelet.Waverec(decomposition, original_signal.size());

    // 将去噪后的信号保存到文件
    std::ofstream output("denoised_signal.txt");
    if (!output.is_open()) {
        std::cerr << "Failed to open output file." << std::endl;
        return 1;
    }

    for (size_t i = 0; i < denoised_signal.size(); ++i) {
        output << denoised_signal[i] << std::endl;
    }
    output.close();

    std::cout << "Denoised signal saved to denoised_signal.txt" << std::endl;

    return 0;
}

Matlab生成小波系数代码

[Lo_D, Hi_D, Lo_R, Hi_R] = wfilters('db4');

去噪效果

在这里插入图片描述

%%
clear all;
clc;

% denoised_result = load('VS_result\denoised_result01.txt');
% denoised_result = load('VS_result\denoised_result04.txt');

% denoised_result = load('VS_result\denoised_signal01.txt');
denoised_result = load('VS_result\denoised_signal05.txt');

%%
data = load('MultiSinWaveWithNoise_1s.txt');
% data = load('MultiSinWaveWithNoise_10s.txt');

fs=1000;%采样频率是1000Hz
yourEEGData = data;

%生成正弦波信号
t=linspace(0, length(data)/fs-1/fs, length(data));
y1 =15*sin(2*pi* 2.8 *t);%生成频率为2.8Hz,幅值为15的正弦波
y2 =10*sin(2*pi* 10.5 *t);%生成频率为10.5Hz,幅值为10的正弦波
y3 =3*sin(2*pi* 27 *t);%生成频率为27Hz,幅值为3的正弦波
y4 =0.5*sin(2*pi* 43 *t);%生成频率为43Hz,幅值为0.5的正弦波

y_Sin =y1+y2+y3+y4;


%%
figure;
plot(y_Sin);
hold on;
plot(data);
hold on;
plot(denoised_result);
legend({'raw','noise','denoise'});

error_noise = sum(abs(data-y_Sin'));
error_denoise = sum(abs(denoised_result-y_Sin'));

Matlab自带小波去噪代码

%%
clear all;
clc;

%%
data = load('MultiSinWaveWithNoise_1s.txt');
% data = load('MultiSinWaveWithNoise_10s.txt');

fs=1000;%采样频率是1000Hz
yourEEGData = data;

%生成正弦波信号
t=linspace(0, length(data)/fs-1/fs, length(data));
y1 =15*sin(2*pi* 2.8 *t);%生成频率为2.8Hz,幅值为15的正弦波
y2 =10*sin(2*pi* 10.5 *t);%生成频率为10.5Hz,幅值为10的正弦波
y3 =3*sin(2*pi* 27 *t);%生成频率为27Hz,幅值为3的正弦波
y4 =0.5*sin(2*pi* 43 *t);%生成频率为43Hz,幅值为0.5的正弦波

y_Sin =y1+y2+y3+y4;

%%
% 1. 读取脑电信号数据
% 请将您的脑电信号数据加载到MATLAB中,例如,使用load函数。

% 2. 小波分解
% 选择适当的小波函数和分解级别
signal = yourEEGData; % 替换为您的脑电信号数据
waveletName = 'db4'; % 小波类型,可以根据需要更改
level = 5; % 分解级别,可以根据需要更改
[C, L] = wavedec(signal, level, waveletName);

% 3. 去除噪声
% 选择适当的阈值和去噪方法
threshold = 0.5; % 阈值,可以根据需要更改
denoisedCoeff = wthresh(C, 's', threshold);

% 4. 重构信号
denoisedSignal = waverec(denoisedCoeff, L, waveletName);

% 5. 绘制原始信号和去噪后的信号
% figure;
% subplot(2, 1, 1);
% plot(signal);
% title('Raw');
% 
% subplot(2, 1, 2);
% plot(denoisedSignal);
% title('Denoise');

% 6. 分析和评估结果
% 根据需要,您可以进行进一步的分析和评估,以确保去噪效果满意。

% 7. 保存去噪后的信号
% 如果需要,可以将去噪后的信号保存到文件。

% 请根据您的数据和需求调整代码中的参数和细节。

%%
figure;
plot(signal);
hold on;
plot(denoisedSignal);

error_denoise = sum(abs(denoisedSignal - y_Sin'));
error_before = sum(abs(signal - y_Sin'));

在这里插入图片描述

Matlab自带函数去噪效果更好,改写的C++因为计算精度和逻辑有所差异,但改变软阈值的值或者改成硬阈值去噪法也能改善结果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1098169.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

用户生成内容vs专业生成内容:谁主海外社媒营销江山?

随着社交媒体和数字营销的崛起&#xff0c;海外社媒营销已经成为各大品牌推广产品和服务的一种主要方式。然而&#xff0c;在选择最佳策略时&#xff0c;品牌经常会面临一个关键的问题&#xff1a;是使用用户生成内容&#xff08;UGC&#xff09;还是专业生成内容&#xff08;P…

fix: prosemirror adds two extra spaces when paste

bug 项目使用 prosemirror&#xff0c;复制 NodeSelection 时&#xff0c;会在末尾多出两个空格。 NodeSelection prosemirror 的 Selection 是抽象类&#xff0c;它有三个子类 TextSelection 最常见的NodeSelection 指向单一节点的选区。设置了 selectable true 的节点&am…

C++项目实战——基于多设计模式下的同步异步日志系统-⑪-日志器管理类与全局建造者类设计(单例模式)

文章目录 专栏导读日志器建造者类完善单例日志器管理类设计思想单例日志器管理类设计全局建造者类设计日志器类、建造者类整理日志器管理类测试 专栏导读 &#x1f338;作者简介&#xff1a;花想云 &#xff0c;在读本科生一枚&#xff0c;C/C领域新星创作者&#xff0c;新星计…

达梦数据库适配ServiceStack框架

注&#xff1a;达梦的驱动版本请使用2023第四季度及以后版本驱动才可以 ServiceStack介绍 ServiceStack官网&#xff1a; https://github.com/ServiceStack/ServiceStack ServiceStack是一个开源的十分流行的WebService框架&#xff0c;引用其官网的介绍&#xff1a;“Servic…

创建React Native的第一个hello world工程

创建React Native的第一个hello world工程 需要安装好node、npm环境 如果之前没有安装过react-native-cli脚手架的&#xff0c;可以按照下述步骤直接安装。如果已经安装过的&#xff0c;但是在使用这个脚手架初始化工程的时候遇到下述报错的话 cli.init(root, projectname);…

FPGA中的LUT查找表工作原理。

在RAM中填入1110,后续的不同AB组合Y输出对应的值&#xff0c;实现上面逻辑表达式的功能。

windows编译ollvm笔记

准备工作 1.找到Android SDK目录配置好cmake环境变量 E:\AndroidSDK\cmake\3.18.1&#xff08;E:\AndroidSDK为 Android SDK目录地址&#xff09;。 下载llvm-mingw编译环境(gcc编译器的windows版本&#xff0c;即可以在windows平台上使用gcc编译器)&#xff0c;下载地址&…

Linux安装rpm包在线安装mysql5.7

以前安装过mysql 前言&#xff1a;检查以前是否装有mysql rpm -qa|grep -i mysql安装了会显示&#xff1a;   bt-mysql57-5.7.31-1.el7.x86_64 停止mysql服务和删除之前安装的mysql rpm -e bt-mysql57-5.7.31-1.el7.x86_64查找并删除mysql相关目录 find / -name mysql/va…

QT开发工业自动化控制软件的几个常用模块

最近两年一直从事工业自动化制造企业的软件开发&#xff0c;发现跟以前开发网络软件还是有较大的区别&#xff0c;重点就是在一些细的方面&#xff0c;比如架构、模块、通讯之类的。下面举几个例子&#xff1a; 1、数字键盘&#xff08;替代普通键盘的小数字键盘&#xff09; …

Jenkins 内存占用

查看内存占用 # ps aux | grep 9090 root 130854 0.0 0.0 8900 708 pts/1 S 16:23 0:00 grep --colorauto 9090 root 4010748 0.2 30.7 5826500 2502884 ? Ssl Oct13 8:55 /usr/bin/java -Djava.awt.headlesstrue -jar /usr/share/java/jenkins…

数据在内存中的存储(2)

文章目录 3. 浮点型在内存中的存储3.1 一个例子3.2 浮点数存储规则 3. 浮点型在内存中的存储 常见的浮点数&#xff1a; 3.14159 1E10 ------ 1.0 * 10^10 浮点数家族包括&#xff1a; float、double、long double 类型 浮点数表示的范围&#xff1a;float.h中定义 3.1 一个例…

C++基本语法【恩培学习笔记(一)】

文章目录 1、C程序结构1.1 C程序的基本组成部分1.2 预处理指令1.3 注释1.4 main() 主函数1.5 命名空间 namespace 2、 C的变量和常量2.1 变量2.2 变量的声明2.3 变量的类型 3、C 数组和容器3.1 数组&#xff08;array&#xff09;3.2 容器&#xff08;vector&#xff09; 4、C …

创建scala项目并增加新的object试运行

一、创建scala项目 依赖配置&#xff1a; scala&#xff0c;jdk&#xff0c;maven 没有maven也可以创建 1.1 直接创建 1.1.1 创建 选择新project 路径、依赖配置、代码调试 1.1.2 项目结构 Scala项目中几个文件&#xff1a; .idea&#xff1a;这个文件夹是用来存储项目的…

Android酒店客房预订系统 后台管理+前端app 包含视频教程

【项目功能介绍】 功能列表: 本系统包含后台管理和前端app双端系统, 本系统包含三个角色: 管理员,员工,app用户。 后台管理员的功能包含: 登录, 退出, ,酒店管理,添加酒店,修改酒店,禁用启用酒店; 酒店客房管理,添加客房,修改客房,启用禁用客房; 订单管理,确定订单,拒绝订单,用…

Android视音频知识

Android视音频知识 视音频完整解码播放流程分析。 视音频完整录制编码流程分析。 为什么要编码&#xff0c;如何编码(编码原理) ?。 为什么要编码&#xff1f; 因为视频文件实在太大了&#xff0c;一部电影 200多个GB&#xff0c;编码&#xff1a;1G 视频是连续的图像序列&a…

【Linux】chmod 命令使用

chmod&#xff08;英文全拼&#xff1a;change mode&#xff09;命令是控制用户对文件的权限的命令。 chmod命令 -Linux手册页 著者 作者&#xff1a;David MacKenzie和Jim Meyering。 语法 chmod [选项] [模式] 文件或目录 Linux/Unix 的文件调用权限分为三级 : 文件所有者…

Spring-AOP-加强

目录 简略介绍 AOP是如何实现的 实现时机 实现原理 简略介绍 AOP(Aspect-Oriented Programming)&#xff0c;即面向切面编程&#xff0c;用人话说就是把公共的逻辑抽出来&#xff0c;让开发者可以更专注于业务逻辑开发和IOC一样&#xff0c;AOP也指的是一种思想AOP思想是OO…

自动化测试框架中如何记录日志更加已读 ?一文介绍使用loguru来管理日志的心得。

只要做代码开发&#xff0c;记录日志必不可少的 &#xff0c;对于像我这样的测试开发同学也是 &#xff0c;你在编写自动化时如何记录日志 &#xff1f;怎么要日志记录更容易已读 &#xff1f;如何备份日志文件 &#xff1f; 这都是我们在编写代码时要考虑的问题 &#xff0c;如…

JNI 的数据类型以及和Java层之间的数据转换

JNI的数据类型和类型签名 数据类型 JNI的数据类型包含两种&#xff1a;基本类型和引用类型。 基本类型主要有jboolean、jchar、jint等&#xff0c;它们和Java中的数据类型的对应关系如下表所示。 JNI中的引用类型主要有类、对象和数组&#xff0c;它们和Java中的引用类型的对…

ICC2:如何抓取“no net“的shape和via

我正在「拾陆楼」和朋友们讨论有趣的话题&#xff0c;你⼀起来吧&#xff1f; 拾陆楼知识星球入口 pr过程中(尤其是eco)会产生一些no net的shape或via&#xff0c;它们会造成drc和lvs问题&#xff0c;但是常规的办法无法把他们抓出来&#xff0c;下面分享可以获取no net的方法…