使用c++实现一维信号的连续小波变换,将长度625的一维信号变成二维图片的代码
时间: 2024-05-11 10:19:56 浏览: 5
以下是使用C++实现一维信号的连续小波变换,并将长度为625的一维信号变成二维图片的代码:
```cpp
#include <iostream>
#include <cmath>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
#define PI 3.14159265358979323846
// Haar小波函数
double haar(int n)
{
if (n < 0 || n >= 2) return 0;
if (n == 0) return 1 / sqrt(2.0);
return (-1) / sqrt(2.0);
}
// Daubechies-4小波函数
double db4(int n)
{
if (n < 0 || n >= 8) return 0;
switch (n)
{
case 0: return (1 + sqrt(3)) / (4 * sqrt(2));
case 1: return (3 + sqrt(3)) / (4 * sqrt(2));
case 2: return (3 - sqrt(3)) / (4 * sqrt(2));
case 3: return (1 - sqrt(3)) / (4 * sqrt(2));
case 4: return -(1 - sqrt(3)) / (4 * sqrt(2));
case 5: return (3 - sqrt(3)) / (4 * sqrt(2));
case 6: return (3 + sqrt(3)) / (4 * sqrt(2));
case 7: return -(1 + sqrt(3)) / (4 * sqrt(2));
}
}
// 连续小波变换
void cwt(double* sig, int n, double* w, int len_w, double* scales, int len_scales, double* cwt_result)
{
for (int i = 0; i < len_scales; i++)
{
double scale = scales[i];
for (int j = 0; j < len_w; j++)
{
int mid = len_w / 2;
double sum_real = 0.0, sum_imag = 0.0;
for (int k = 0; k < n; k++)
{
double t = (double)k / scale;
int idx = (int)floor(t + 0.5);
double y = t - idx;
double real = sig[min(max(idx - mid + j, 0), n - 1)] * w[(2 - y) * mid] +
sig[min(max(idx - mid + j + 1, 0), n - 1)] * w[(1 - y) * mid] +
sig[min(max(idx - mid + j + 2, 0), n - 1)] * w[(0 - y) * mid] +
sig[min(max(idx - mid + j + 3, 0), n - 1)] * w[(y + 1) * mid];
double imag = sig[min(max(idx - mid + j, 0), n - 1)] * w[(2 - y) * mid + 1] +
sig[min(max(idx - mid + j + 1, 0), n - 1)] * w[(1 - y) * mid + 1] +
sig[min(max(idx - mid + j + 2, 0), n - 1)] * w[(0 - y) * mid + 1] +
sig[min(max(idx - mid + j + 3, 0), n - 1)] * w[(y + 1) * mid + 1];
sum_real += real;
sum_imag += imag;
}
cwt_result[i * len_w + j] = sqrt(sum_real * sum_real + sum_imag * sum_imag);
}
}
}
// 将一维信号转为二维图像
Mat reshape_to_image(double* data, int rows, int cols)
{
Mat img(rows, cols, CV_64FC1);
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
img.at<double>(i, j) = data[i * cols + j];
}
}
return img;
}
int main()
{
// 生成长度为625的一维信号
double sig[625];
for (int i = 0; i < 625; i++)
{
sig[i] = sin(2 * PI * i / 25) + sin(2 * PI * i / 50);
}
// 定义小波函数和尺度数组
int len_w = 256; // 小波函数长度
double w[len_w];
for (int i = 0; i < len_w; i++)
{
w[i] = db4(2 * i - len_w + 1);
}
int len_scales = 64; // 尺度数量
double scales[len_scales];
double q = 2.0;
for (int i = 0; i < len_scales; i++)
{
scales[i] = pow(q, i);
}
// 进行连续小波变换
double cwt_result[len_scales * len_w];
cwt(sig, 625, w, len_w, scales, len_scales, cwt_result);
// 将一维信号转为二维图像
Mat img = reshape_to_image(cwt_result, len_scales, len_w);
// 显示图像
normalize(img, img, 0, 255, NORM_MINMAX);
Mat img_show;
img.convertTo(img_show, CV_8UC1);
imshow("CWT result", img_show);
waitKey();
return 0;
}
```
该代码使用Daubechies-4小波函数进行连续小波变换,并将结果转换为二维图像,最终显示出来。其中,使用了OpenCV库来显示图像,如果没有安装该库,需要先安装。