手撕重采样,考虑C的实现方式

一、参考文章:

重采样、上采样、下采样 - 知乎 (zhihu.com)

先直接给结论,正常重采样过程如下:

1、对于原采样率fs,需要重采样到fs1,一般fs和fs1都是整数哈,则先找fs和fs1的最小公倍数,设为m,设m/fs=M,m/fs1 = L。则信号先要做M倍的插值,即上采样,再做1/L倍的抽取,即下采样;

2、因为插值和抽取,信号的频带都会变,也就是信号会引入噪声,所以需要滤波处理;

3、具体来说,插值,频谱变窄,即信号频带压缩了,如果不做处理,信号会包含带宽以外的噪声,所以需要做低通只滤出变窄的信号频带,去掉噪声。抽取,之后的频谱会变宽,即最终和原信号频谱对不上,所以又需要低通滤波,将信号滤到和原信号一样的频带。

4、具体来说,第一个低通的通带(归一化)是0~1/M,第二个低通的通带是0~1/L。找到满足性能的滤波器,还是比较有考验的。

回到程序,上文中第一段,涉及到滤波器,改用0相位滤波,即调用matlab的filtfilt。滤波时考虑使用原程序中的滤波器幅值归一化。且,加入抽取、滤波,即实现重采样完整流程,最后,还对比matlab自己的resample函数结果。如下:

clc;
close all;
clear all;
%%%%%%%%%%%%%%%%%程序说明
% 1、使用'zero stuffing'和'low pass filter'实现内插/上采样

N = 4; % 上采样率
h_t = ones(1, N);
h_t_lp = sinc(-pi:2*pi/20:pi);
% h_t_lp = h_t_lp ./ sum(h_t_lp); % 归一化LPF


A = 1.5;
B = 1;
f1 = 50;
f2 = 100;
Fs = 1000;
t = 0:1/Fs:1;
sig = A * cos(2 * pi *f1 * t) + B * sin(2 * pi *f2 * t); % 原始数据

% 插值:插入0
sig_zerostuff = zeros(1, length(sig) * N);
sig_zerostuff(1 : N : length(sig_zerostuff)) = sig;
sig_zerostuff_lp = conv(sig_zerostuff, h_t_lp);
% 采样保持:使得插入的数值与原数据的数值一致
sig_sample_hold = conv(sig_zerostuff, h_t);
% 将采样保持的信号经过LPF
h_t_lp = h_t_lp ./ sum(h_t_lp); % 归一化LPF
% sig_sample_hold_lp = conv(sig_sample_hold, h_t_lp);
sig_sample_hold_lp = filtfilt(h_t_lp,1,sig_sample_hold);

subplot(5,1,1);
stem(sig,'MarkerFaceColor',[0 0 1]);xlim([1 25]);
title('原始数据');

subplot(5,1,2);
stem(sig_zerostuff,'MarkerFaceColor',[1 0 0]);xlim([1 25*N]);
title('插值后的数据');

subplot(5,1,3);
stem(sig_zerostuff_lp,'MarkerFaceColor',[1 0 0]);xlim([1 25*N]);
title('插值后的数据通过LPF');

subplot(5,1,4);
stem(sig_sample_hold,'MarkerFaceColor',[1 0 0]);xlim([1 25*N]);
title('插值保持后的数据');

subplot(5,1,5);
stem(sig_sample_hold_lp,'MarkerFaceColor',[1 0 0]);xlim([1 25*N]);
title('采样保持的数据通过LPF');

% 抽取,1/3
sig_sample_hold_lp_downsample = sig_sample_hold_lp(1:3:end);
% sig_sample_hold_lp_downsample_lp = conv(sig_sample_hold_lp_downsample, h_t_lp);
sig_sample_hold_lp_downsample_lp = filtfilt(h_t_lp,1,sig_sample_hold_lp_downsample);
sig_resample = resample(sig, 4, 3);

figure
subplot(4,1,1);
stem(sig,'MarkerFaceColor',[0 0 1]);xlim([1 120]);
title('原始数据');
subplot(4,1,2);
stem(sig_sample_hold_lp_downsample,'MarkerFaceColor',[0 1 0]);xlim([1 120]);
title('抽取数据');
subplot(4,1,3);
stem(sig_sample_hold_lp_downsample_lp,'MarkerFaceColor',[1 0 0]);xlim([1 120]);
title('抽取数据通过LPF');
subplot(4,1,4);
stem(sig_resample,'MarkerFaceColor',[0 0 0]);xlim([1 120]);
title('resample重采样数据');
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

结果:

还是文章一,插值可以用另一种方法,即,不是插0值或者保持,而是用其他插值法,matlab有interp函数,可以设置参数用不同插值法。典型的线性插值,应该比较好找C代码。

先看看文章的效果:

效果还是可以的。

关于线性插值C代码,时间关系暂未验证哈:

线性插值_c语言实现_线性插值c语言程序-CSDN博客

标准C语言插值函数 - 百度文库 (baidu.com)

二、一种自创的简单、近似算法

应该有很多这样使用的,只是介绍的少,属于私下处理算法。

简单来说,思路是:

考查原始信号时间点和重采样后信号的时间点,一般来说,重采样信号的一个时间点,是处在原始信号的两个信号点之间(若重合,则直接不用计算),根据此时间点到原信号两个信号点的距离,用原信号这两个信号点插值得到重采样信号此点的信号幅值。

所以很明显,这种方法的优点是,不用考虑抽取、插值、滤波这些麻烦事,只考虑插值即可。

但是,缺点也有,就是不能统一处理,必须每个点都分别处理。

时间关系,后续,可以再测试下。

三、查到一个专利,但是算法还是有问题,未程序实现:

CN202010258902一种数字信号的任意重采样方法及系统

无法添加附件,是个问题。

主要步骤有:

简单说是用sinc函数实现。但是还有较多看不懂的。感觉不理解0052到0058的用意是啥。但是貌似,可以不管其他,直接用最后一个公式算就行了......

后续试试程序仿真...

有关sinc函数(也较辛格函数):20211003:数字滤波器前置知识,sinc函数与Sa函数_sinc函数与sa函数区别-CSDN博客

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

1、【vue篇】vue框架快速上手

注意事项&#xff1a; methods必须要加s 导入vue&#xff1a;<script src"https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>导入Axios:<script src"https://unpkg.com/axios/dist/axios.min.js"></script> 简单Vue程序…

k8s的图形化工具---rancher

声明式&#xff1a;yaml文件 陈述式&#xff1a;命令行 k8s的图形化工具---rancher racher是一个开源的企业级多集群的k8s关联平台。 rancher和k8s区别&#xff1a; 都是为了容器的调度和编排系统&#xff0c;但是rancher不仅能调度&#xff0c;还能管理k8s集群&#xff0…

(菜鸟自学)漏洞利用——MS11-080

&#xff08;菜鸟自学&#xff09;漏洞利用——MS11-080 漏洞简介利用漏洞对系统进行提权查看漏洞利用代码和工具将py脚本转换为exe程序渗透攻击验证 漏洞简介 MS11-080 是指微软于 2011 年发布的一个安全公告&#xff08;MS11-080&#xff09;&#xff0c;其中包含了关于 Win…

【DG 特长生2019】模拟赛赛后总结(2024.1.24)

打了330pt,订正后350pt T1 签到 T2 dfs剪枝&#xff08;虽然我写挂了&#xff09; T3 NOIP原题 T4 floyd 主要是想分享一下T4。 写了一种基于floyd的做法。 感觉好像和大部分人的写法不太一样。 因为看到大小关系&#xff0c;我就想到了传递性。 floyd是可以维护传递…

端口隔离技术

概念 端口隔离可实现同一VLAN内端口之间的隔离&#xff0c;为用户提供了更安全、更灵活的组网方案。 为了实现报文之间的二层隔离&#xff0c;用户可以将不同的端口加入不同的VLAN&#xff0c;但这样会浪费有限的VLAN资源。采用端口隔离功能&#xff0c;可以实现同一VLAN内端口…

探索 XMLHttpRequest:网页与服务器的异步通信之道(下)

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

HarmonyOS鸿蒙学习基础篇 - Text文本组件

该组件从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 Text文本组件是可以显示一段文本的组件。该组件从API Version 7开始支持&#xff0c;从API version 9开始&#xff0c;该接口支持在ArkTS卡片中使用。 子组件 可…

ChromeDriver谷歌驱动最新版安装120/121/122

chromeDriver最新版本下载 最新驱动 https://googlechromelabs.github.io/chrome-for-testing/参考&#xff1a; https://blog.csdn.net/m0_57382185/article/details/134007615

Transfomer相关最新研究

文章目录 iTransformerContiFormerBasisFormerMTSTMultiResFormerFPPformerDOzerfomerCSformerMASTERPCA former **PDFPathformerVQ-TR iTransformer ContiFormer BasisFormer MTST MultiResFormer FPPformer DOzerfomer CSformer MASTER PCA former ** PDF Pathformer VQ-TR…

VG-4231CE压控晶体振荡器

随着科技的飞速发展&#xff0c;各类电子设备对于稳定且精确的信号需求越来越高。VG-4231CE压控晶体振荡器&#xff08;VCXO&#xff09;&#xff0c;它能提供稳定的工作环境和高精度信号&#xff0c;助您轻松应对各种高难度信号处理任务。3MHz至50MHz的频率范围&#xff0c;输…

云卷云舒:PostgreSQL的事儿你听说了吗?

最近&#xff0c;PostgreSQL公布了全球贡献者名单。 以上是全球贡献者主要成员&#xff0c;可以看出都是外国人&#xff0c;除了一名台湾省贡献者外&#xff0c;几乎再看不到中国贡献者的身影。 那么偌大的中国&#xff0c;为什么在PostgreSQL的全球贡献者名单里面就看不到人呢…

linux 安装 grafana

Ubuntu 和 Debian(64 位)SHA256&#xff1a; e551434e9e3e585633f7b56a33d8f49cda138d92ad69c2c29dcec2c3ede84607 sudo apt-get install -y adduser libfontconfig1 muslwget https://dl.grafana.com/enterprise/release/grafana-enterprise_10.2.3_amd64.debsudo dpkg -i gra…

4.Hive表更新字段信息,一次讲明白

Hive表更新字段信息 一、更新表字段语句1、修改字段名称2、修改字段类型3、修改字段备注 二、总结 一、更新表字段语句 ALTER TABLE table_name [PARTITION partition_spec] CHANGE [COLUMN] col_old_name col_new_name column_type[COMMENT col_comment] [FIRST|AFTER column…

深度学习(5)--Keras实战

目录 一.Keras基础概念 二.如何跑通Keras项目 2.1.在cmd上跑通 2.2.在PyCharm上跑通 一.Keras基础概念 Keras是深度学习中的一个神经网络框架&#xff0c;是一个高级神经网络API&#xff0c;用Python编写&#xff0c;可以在TensorFlow&#xff0c;CNTK或Theano之上运行。 …

SpringCloud Alibaba Sentinel 与 SpringCloud Gateway 的限流有什么差别?(三种限流算法原理分析)

目录 一、Sentinel 与 Gateway 的限流有什么差别&#xff1f; 1.1、前置知识 - 四种常见的限流算法 1.1.1、Tips 1.1.2、计数器算法 1&#xff09;固定窗口计数器算法 2&#xff09;滑动窗口计数器算法 1.1.3、令牌桶算法 1.1.4、漏桶算法 1.2、解决问题 一、Sentinel…

如何通过 Nginx 反向代理提高网站安全性和性能?

如何通过 Nginx 反向代理提高网站安全性和性能&#xff1f; 引言Nginx 反向代理的基本原理什么是反向代理&#xff1f;反向代理的工作方式反向代理的好处 配置 Nginx 反向代理的基本步骤1. 安装 Nginx2. 编辑 Nginx 配置文件3. 设置反向代理配置4. 测试并重启 Nginx 提高安全性…

NineData支持制定安全、可靠的SQL开发规范

在和数据库打交道中&#xff0c;不管是数据库管理员&#xff08;DBA&#xff09;还是开发人员&#xff0c;经常会做一些CURD操作。因为每个人对数据库的了解程度不一样&#xff0c;所以在项目上线时&#xff0c;往往还需要专职人员对数据库的CURD操作进行审核&#xff0c;确保C…

第21课 在Android Native开发中架起java与c++互通的桥梁

在开始本节课&#xff0c;我尝试把项目拷贝到另一台电脑上以便继续工作&#xff0c;但出现了大量的“could not be resolved”问题&#xff0c;尝试包含新的include路径也无法解决该问题&#xff0c;最后删除了项目的Native Support&#xff0c;然后重新添加Native Support才解…

1.19号网络

超时检测 概念 1> 在网络通信中&#xff0c;有很多函数是阻塞函数&#xff0c;会导致进程的阻塞&#xff0c;例如&#xff1a;accept、recv、recvfrom、等等 2> 为了避免进程在阻塞函数处&#xff0c;无休止的等待&#xff0c;我们可以设置一个超时时间&#xff0c;当…

unity学习笔记----游戏练习05

一、阳光的收集和搜集动画开发 1.收集阳光的思路&#xff1a;当鼠标点击到阳光的时候&#xff0c;就可以进行收集了。可以通过为添加一个碰撞器来检测Circle Collider 2D 编写脚本&#xff1a; 在SunManager中写一个增加阳光的方法 //增加阳光 public void AddSubSun(in…