当前位置: 首页> 教育> 培训 > 信号的图小波变换(Python)

信号的图小波变换(Python)

时间:2025/7/11 7:55:55来源:https://blog.csdn.net/weixin_39402231/article/details/140394038 浏览次数:0次

可以换个空间,从图域的角度进行分析,比如图傅里叶变换,图小波变换等图时频分析方法。图小波阈值降噪的基本思想是通过将时间序列信号转换成路图信号,再利用图小波变换分解成尺度函数系数和一系列对应不同尺度的谱图小波系数,然后设置阈值对图小波系数进行过滤处理,最后对尺度函数系数和滤波后的图小波系数进行图小波逆变换,重构得到降噪信号。

更具体地,图小波变换将路图信号分解成低频分量和高频分量,其中尺度函数系数包含信号的低频近似成分,图小波系数反映信号的高频细节成分。各尺度上的图小波系数在某些特定位置的幅值较大,对应于原始信号的奇变位置和重要信息,而其他大部分位置的幅值较小,对应于噪声干扰成分。噪声对应的图小波系数在每个尺度上的分布较均匀,且幅值随着尺度的减小而逐渐减小。因此,通常的降噪方法是设置一个合适的临界阈值ρ,并结合阈值函数对系数进行滤波。当图小波系数小于阈值ρ时,认为此系数主要由噪声引起,则将其置为零进行消除;当图小波系数大于或等于阈值ρ时,认为此系数主要由信号引起,则予以保留或进行收缩,从而得到估计谱图小波系数。最后,对所有剩余系数进行重构即可获得降噪信号。

import sys
import os
sys.path.append("src")import numpy as np
import networkx as nx
import matplotlib.pyplot as plt
import wavelet_transform as wt
from pygsp import graphs
from time import time
if not os.path.exists("figs"):os.makedirs("figs")
def plot_graph_signal(G,signal,pos = None,vmin = None,vmax = None,ax = None,fig = None,colorbar = True,colorbar_label = "Values",):if ax is None:fig, ax = plt.subplots(figsize = (4, 4))vmin = np.min(signal) if vmin is None else vminvmax = np.max(signal) if vmax is None else vmaxpathcollection = nx.draw_networkx_nodes(G, pos, node_color=signal,cmap=plt.cm.magma, node_size=50,edgecolors="#909090",ax = ax,vmin = vmin,vmax = vmax)nx.draw_networkx_edges(G, pos,edge_color="#909090", ax = ax)ax.axis("off")if colorbar:fig.colorbar(pathcollection, ax = ax, label = colorbar_label)ax.figure.axes[-1].yaxis.label.set_size(14)return ax

Creating Graph

def create_grid_graph(size = 17):g = nx.grid_2d_graph(size, size)nodes = list(g.nodes)pos = {node: node for node in g.nodes}pos = np.array(list(pos.values()))for node in nodes:# get node positionnode_pos = np.array(node)# get all nodes closest than \sqrt 2distances = np.linalg.norm(pos - node_pos, axis = 1)idx_close = (distances < 2) & (distances != 0) & (distances != 1)close_node = np.random.choice(np.where(idx_close)[0])# select a random close noden1 = close_node# add edgeg.add_edge(node, tuple(nodes[n1]))return g
# create 2D grid graph
np.random.seed(1)
g = create_grid_graph(17)adj_matrix = nx.adjacency_matrix(g).todense()# darw nodes by position
pos = {node: node for node in g.nodes}
pos = np.array(list(pos.values()))
# add random noise
#pos = pos + np.random.normal(0, 0.15, pos.shape)
pos = {node: pos[i] for i, node in enumerate(g.nodes)}
nx.draw(g, pos, node_size = 75, node_color = "#034e7b", edgecolors = "black", width = 1)
plt.axis("off")
plt.title("Grid Graph")
plt.savefig("figs/grid_graph.pdf", dpi = 300)

Fourier Transform

G = graphs.Graph(adj_matrix)
G.compute_fourier_basis()
fig, ax = plt.subplots(nrows = 1, ncols = 1, figsize = (6, 4))
ax.hist(G.e, bins = 40)
ax.set_title("Distribution of Eigenvalues", fontsize = 16)
ax.set_xlabel("Eigenvalue", fontsize = 14)
ax.set_ylabel("Frequency", fontsize = 14)
plt.savefig("figs/eigenvalues_dist.svg", dpi = 300)
plt.show()

fig, axs = plt.subplots(nrows = 1, ncols = 3, figsize = (14, 4))
for i, idx in enumerate([4, 9, 14]):plot_graph_signal(g, G.U[:, idx], pos = pos, ax = axs[i],vmin = -0.15,vmax = 0.10,fig=fig)axs[i].set_title(f"{idx+1}-th Eigenvector", fontsize = 14)plt.suptitle("Eigenvectors of Graph", fontsize = 16)
plt.tight_layout()
plt.savefig("figs/eigenvectors.svg", dpi = 300)
plt.show()

simple_signal = np.zeros((2, 17, 17))for i in range(17):for j in range(17):simple_signal[0, i, j] = (i + j)**2 / (34)**2simple_signal[1, i, j] = np.sin(i + j)fig, axs = plt.subplots(nrows = 1, ncols = 2, figsize = (10, 4))
plot_graph_signal(g, simple_signal[0].flatten(), pos = pos, ax = axs[0],vmin = -1,vmax = 1,fig=fig
)plot_graph_signal(g, simple_signal[1].flatten(), pos = pos, ax = axs[1],vmin = -1,vmax = 1,fig=fig,colorbar_label="Signal Value"
)axs[0].set_title("Simple Signal 1", fontsize = 14)
axs[1].set_title("Simple Signal 2", fontsize = 14)plt.suptitle("Fourier Transform of Two Signals", fontsize = 16)
plt.tight_layout()
plt.savefig("figs/simple_signals.svg", dpi = 300)

transformed_signal = [G.gft(signal.flatten()) for signal in simple_signal]fig, axs = plt.subplots(nrows = 1, ncols = 2, figsize = (10, 4))for i in range(2):axs[i].plot(G.e, transformed_signal[i])axs[i].set_ylabel("$\hat f(\lambda)$", fontsize = 14)axs[i].set_xlabel("$\lambda$", fontsize = 14)axs[i].set_title(f"Signal {i+1} Fourier Transform", fontsize = 14)
#plt.suptitle("Graph Fourier Transform of Signals")
plt.tight_layout()
plt.savefig("figs/fourier_transform.svg", dpi = 300)
plt.show()

Graph Wavelet Transform

signal = np.random.normal(0, 0.25, (17, 17)) + 3for i in range(17):for j in range(17):if (i - 8)**2 + (j - 8)**2 <= 25:signal[i, j] += 3signal = signal.flatten()adj_matrix = np.array(nx.adjacency_matrix(g).todense())
wav = wt.WaveletTransform(adj_matrix = adj_matrix,n_timestamps=1,method = "exact_fast",scaling_function=False,n_filters=4
)
coeffs = wav.transform(signal.reshape(-1, 1))
coeffs_ = coeffs.reshape(17, 17, 4)
selected_nodes = [[11, 11],[12, 12],[15, 15],
]
selected_nodes_idx = [ x + y * 17 for (x, y) in selected_nodes]
fig = plt.figure(figsize = (6, 4))
pathcollection = nx.draw_networkx_nodes(g, pos, node_color=signal, cmap=plt.cm.magma, node_size=[100 if i in selected_nodes_idx else 50 for i in range(len(pos))],edgecolors=["#e7298a" if i in selected_nodes_idx else "#909090" for i in range(len(pos))],#vmin = 1
)
nx.draw_networkx_edges(g, pos, edge_color="#909090")
plt.colorbar(pathcollection, label = "Signal")
plt.title("Graph with Signal")
plt.axis("off")
plt.savefig("figs/graph_with_signal.svg", dpi = 300)
plt.show()fig, axs = plt.subplots(nrows = 1, ncols = 3, figsize =(6, 2), sharex = True, sharey = True)for i in range(3):c = np.abs(coeffs_[selected_nodes[i][0], selected_nodes[i][1], :])axs[i].bar(range(4), c, color = "#8da0cb")axs[i].set_xticks(range(4), labels = ["" for _ in range(4)])#axs[i].set_yticks([])axs[i].set_xlabel("Frenquencies")axs[i].set_ylabel("Coefficients")plt.tight_layout()
plt.savefig("figs/coefs.svg", dpi = 300)
plt.show()

Fast Computation

graph_sizes = [5, 10, 15, 20, 25, 30]
exact_time = []
cheb_time = []
cheb_error = []for n_g in graph_sizes:signal = np.random.random((n_g**2, 20))g = create_grid_graph(n_g)adj_matrix = nx.adjacency_matrix(g).todense()times_ = []for _ in range(10):start = time()wav = wt.WaveletTransform(adj_matrix = adj_matrix,n_timestamps=20,method = "exact_low_memory",scaling_function=False,n_filters=4)coeffs_exact = wav.transform(signal)end = time()times_.append(end - start)exact_time.append(np.mean(times_))times_ = []for _ in range(10):start = time()wav = wt.WaveletTransform(adj_matrix = adj_matrix,n_timestamps=20,method = "chebyshev",scaling_function=False,n_filters=4)coeffs_cheb = wav.transform(signal)end = time()times_.append(end - start)cheb_time.append(np.mean(times_))cheb_error.append(np.mean(np.abs(coeffs_exact - coeffs_cheb) / np.abs(coeffs_exact)))
fig, axs = plt.subplots(nrows = 1, ncols = 2, figsize = (7, 2.5))
axs[0].plot(graph_sizes, exact_time, label = "Exact")
axs[0].plot(graph_sizes, cheb_time, label = "Chebyshev")axs[1].plot(graph_sizes, cheb_error, label = "Chebyshev")
for i in range(2):axs[i].set_xlabel("Graph Size")axs[i].set_xticks(graph_sizes, labels = [int(x*x*20) for x in graph_sizes])
axs[0].set_ylabel("Time (s)")
axs[0].legend()
axs[1].set_ylabel("Mean Absolute\nPercentage Error")
plt.suptitle("Time and Error of Exact and Chebyshev Methods")
plt.tight_layout()
plt.savefig("figs/time_error.pdf", dpi = 300)
plt.show()

n_order = [10, 20, 30, 40, 50]
cheb_time = []
cheb_error = []g = create_grid_graph(17)
adj_matrix = nx.adjacency_matrix(g).todense()
signal = np.random.random((17**2, 20))
wav = wt.WaveletTransform(adj_matrix = adj_matrix,n_timestamps=20,method = "exact_low_memory",scaling_function=False,n_filters=4
)
coeffs_exact = wav.transform(signal)for order in n_order:times_ = []for i in range(10):start = time()wav = wt.WaveletTransform(adj_matrix = adj_matrix,n_timestamps=20,method = "chebyshev",scaling_function=False,n_filters=4,order_chebyshev=order,)coeffs_cheb = wav.transform(signal)end = time()times_.append(end - start)cheb_time.append(np.mean(times_))# append MAPEcheb_error.append(np.mean(np.abs(coeffs_exact - coeffs_cheb) / np.abs(coeffs_exact)))
fig, axs = plt.subplots(nrows = 1, ncols = 2, figsize = (7, 2.5))axs[0].plot(n_order, cheb_time, label = "Chebyshev")
axs[1].plot(n_order, cheb_error, label = "Chebyshev")for i in range(2):axs[i].set_xlabel("Chebyshev Order")axs[i].set_xticks(n_order)
axs[0].set_ylabel("Time (s)")
axs[1].set_ylabel("Mean Absolute\nPercentage Error")
axs[1].set_yscale("log")
plt.suptitle("Time and Error of Chebyshev Method")
plt.tight_layout()
plt.savefig("figs/time_error_cheb_order.pdf", dpi = 300)
plt.show()

 
擅长领域:现代信号处理,机器学习,深度学习,数字孪生,时间序列分析,设备缺陷检测、设备异常检测、设备智能故障诊断与健康管理PHM等。
知乎学术咨询:https://www.zhihu.com/consult/people/792359672131756032?isMe=1
擅长领域:现代信号处理,机器学习,深度学习,数字孪生,时间序列分析,设备缺陷检测、设备异常检测、设备智能故障诊断与健康管理PHM等。

擅长领域:现代信号处理,机器学习,深度学习,数字孪生,时间序列分析,设备缺陷检测、设备异常检测、设备智能故障诊断与健康管理PHM等。

关键字:信号的图小波变换(Python)

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: