赞
踩
汉宁窗口(Hanning Window)的起源:
汉宁窗口是一种在信号处理和频谱分析中常用的窗口函数。它的名字来自于发明者之一的Julius von Hann(也写作Hanning)。Hann是奥地利的物理学家,他于1928年发表了一篇题为《Über die Verwendung von Fensterfunktionen bei der Fourier-Analyse von Zeitabhängigen Messungen》(关于在傅里叶分析中使用窗口函数进行时间相关测量的论文)的文章,介绍了这个窗口函数的概念。
汉宁窗口(Hanning Window)的计算公式如下:
其中:
这个公式描述了汉宁窗口函数在离散样本点上的取值。窗口的特点是在两端有较小的幅度,中心区域的振幅相对较高。这有助于减小截断信号产生的频谱泄漏,提高频谱分析的准确性。
汉宁窗口的应用场景:
在信号处理中,窗口函数用于限制从无穷信号中选择的有限片段,以便在频域中进行傅里叶变换。窗口函数有助于减小截断信号产生的频谱泄漏(spectral leakage)现象,提高频谱分析的准确性。
汉宁窗口的主要特点是在窗口内信号的两端降低幅度,以减小边界效应,同时保持中心区域的振幅不变。
用C++计算汉宁窗口数组并用OpenCV展示曲线:
下面是一个使用C++和OpenCV的简单示例代码,计算汉宁窗口数组并绘制其曲线:
- #include <iostream>
- #include <cmath>
- #include <opencv2/opencv.hpp>
-
- int main() {
- // 设置窗口大小
- int windowSize = 100;
-
- // 计算汉宁窗口数组
- cv::Mat hanningWindow = cv::Mat::zeros(1, windowSize, CV_64F);
- for (int i = 0; i < windowSize; ++i) {
- hanningWindow.at<double>(0, i) = 0.5 * (1 - std::cos(2 * CV_PI * i / (windowSize - 1)));
- }
-
- // 设置窗口背景颜色
- cv::Scalar backgroundColor(255, 255, 255); // 白色背景
-
- // 显示汉宁窗口曲线
- cv::Mat plot = cv::Mat::ones(400, windowSize, CV_8UC3) * 255;
- plot.setTo(backgroundColor);
- for (int i = 0; i < windowSize - 1; ++i) {
- cv::line(plot, cv::Point(i, 200 - hanningWindow.at<double>(0, i) * 200),
- cv::Point(i + 1, 200 - hanningWindow.at<double>(0, i + 1) * 200),
- cv::Scalar(0, 0, 0), 2, cv::LINE_AA);
- }
-
- // 显示图像
- cv::imshow("Hanning Window", plot);
- cv::waitKey(0);
-
- return 0;
- }
这个程序首先计算了汉宁窗口数组,然后使用OpenCV绘制了窗口函数的曲线。通过调整windowSize
可以改变窗口的大小。在绘制过程中,窗口函数的值被映射到图像的纵轴上,形成了窗口函数的曲线。
scipy中直接调用
win = scipy.signal.windows.hann(N_win, sym=False)
C++代码具体实现
- bool len_guards(int M) {
- if (M < 0) {
- throw std::invalid_argument("Window length M must be a non-negative integer");
- }
- return M <= 1;
- }
-
- std::pair<int, bool> extend(int M, bool sym) {
- if (!sym) {
- return std::make_pair(M + 1, true);
- } else {
- return std::make_pair(M, false);
- }
- }
-
- std::vector<double> truncate(std::vector<double>& w, bool needed) {
- if (needed) {
- w.pop_back();
- }
- return w;
- }
-
- std::vector<double> general_cosine(int M, std::vector<double> alpha, bool sym) {
- if (len_guards(M)) {
- return std::vector<double>(M, 1.0);
- }
- auto [M_ext, needs_trunc] = extend(M, sym);
-
- double pi = std::acos(-1);
- std::vector<double> fac(M_ext);
- for (int i = 0; i < M_ext; ++i) {
- fac[i] = -pi + 2.0 * pi * i / (M_ext - 1);
- }
-
- std::vector<double> w(M_ext, 0.0);
- for (int k = 0; k < alpha.size(); ++k) {
- for (int i = 0; i < M_ext; ++i) {
- w[i] += alpha[k] * std::cos(k * fac[i]);
- }
- }
-
- return truncate(w, needs_trunc);
- }
-
- std::vector<double> general_hamming(int M, double alpha, bool sym=true) {
- return general_cosine(M, {alpha, 1.0 - alpha}, sym);
- }
-
- std::vector<double> hann(int M, bool sym=true) {
- return general_hamming(M, 0.5, sym);
- }
-
- std::vector<double> sqrtHann(int M, bool sym=true){
- auto arr = general_hamming(M, 0.5, sym);
- for(auto& a : arr){
- a = std::sqrt(a);
- }
- return arr;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。