1. 小波变换:为什么说它是信号处理的“瑞士军刀”?

如果你玩过音乐播放器上的频谱分析,或者用过Photoshop里的滤镜,那你其实已经间接接触过信号处理的核心思想了。传统的傅里叶变换就像是一个音乐鉴赏家,他能告诉你一首交响乐里有多少小提琴、多少大提琴,但他说不出来第三分钟那个惊艳的小提琴独奏具体是什么时候开始的。这就是傅里叶变换的“硬伤”:它完美地揭示了信号的频率构成,却彻底丢失了时间信息。后来,工程师们想了个办法,加个固定时间窗口来分析,这就是短时傅里叶变换(STFT)。这就像你通过一扇固定大小的窗户去看一场游行,虽然能知道某一小段时间里发生了什么,但如果游行队伍里既有缓慢移动的花车(低频),又有快速奔跑的舞者(高频),这扇固定大小的窗户就尴尬了:看花车时,窗户太窄,看不清全貌;看舞者时,窗户又太宽,时间定位不够精确。

这时候,小波变换就闪亮登场了。我第一次接触小波变换是在处理一段带有瞬时冲击的振动传感器数据时,傅里叶变换给出的频谱图一团糟,根本找不到冲击发生的确切时刻。小波变换的核心思想非常巧妙,它放弃使用固定窗口的正弦波,而是改用一种可以“伸缩”和“平移”的波形——小波。你可以把它想象成一把可伸缩的放大镜:当分析信号中快速变化的高频部分(比如那个瞬间冲击)时,就用“窄”的放大镜,这样时间定位就非常精准;当分析信号中缓慢变化的低频部分(比如背景振动)时,就用“宽”的放大镜,这样可以看清整体的趋势和轮廓。这种能根据信号频率自动调整分析窗口大小的能力,叫做“多分辨率分析”,正是小波变换最强大的地方。

那么,这个神奇的“小波”长什么样呢?它不是一个特定的函数,而是一族满足两个核心条件的函数。第一,它必须像跷跷板一样,正负面积相等,平均值为零。这意味着小波本身不包含任何直流分量,它天生就对信号的恒定部分不感兴趣,只专注于捕捉变化和波动。第二,它必须有有限的能量,不能无限振荡下去,确保它是“局部的”。最经典、最简单的例子就是Haar小波,它长得像一个台阶:在0到0.5的时间段内是+1,在0.5到1的时间段内是-1,其他地方是0。你可以直观地把它理解为一个“差分算子”,专门用来检测信号在某个区间内的上升或下降跳变。正是这种灵活性和局部性,让小波变换从理论走向了无数实际应用场景,从医学心电图去噪到卫星图像压缩,无处不在。

2. 庖丁解牛:小波变换的数学内核与Python可视化

理解了小波变换的思想,我们再来稍微深入一下它的数学表达,别担心,我会用最直观的方式和代码帮你建立感觉。连续小波变换的公式看起来有点唬人,但其实理解起来很简单:W_f(a, b) = (1/√|a|) ∫ f(t) * ψ*((t-b)/a) dt。这里的 f(t) 是你的原始信号,ψ(t) 就是你选的那个“母小波”。这个公式在做什么呢?它实际上是在做一系列的相关性计算。

参数 a 是尺度因子,它控制小波的“胖瘦”。a 越大,小波被拉伸得越宽,对应分析更低的频率;a 越小,小波被压缩得越窄,对应分析更高的频率。参数 b 是平移因子,它控制小波在时间轴上“滑动”的位置。整个变换的过程,就是让这个可伸缩的小波函数 ψ((t-b)/a) 滑过信号的每一个时间点 b,并计算在每个位置、每种尺度 a 下,信号与小波的“相似度”有多高(即内积)。最终结果 W_f(a, b) 是一个二维矩阵(对于一维信号),横轴是时间 b,纵轴是尺度 a(可以近似理解为频率的倒数),矩阵中的每个值代表了在那个特定时间和尺度上,信号与小波的匹配程度。

光说不练假把式,我们直接用Python来“看见”小波。PyWavelets (pywt) 库是我们进行小波实战的利器。首先,我们来看看不同小波函数到底长什么样,以及它们是如何与信号互动的。

import numpy as np
import pywt
import matplotlib.pyplot as plt

# 1. 看看几个常用的小波函数长什么样
wavelets = ['haar', 'db2', 'sym5', 'coif3'] # Daubechies, Symlets, Coiflets 家族
fig, axes = plt.subplots(2, 2, figsize=(10, 6))
axes = axes.ravel()

for i, wname in enumerate(wavelets):
    # 获取小波函数
    phi, psi, x = pywt.Wavelet(wname).wavefun(level=5)
    axes[i].plot(x, psi, label=f'Wavelet: {wname}')
    axes[i].set_title(f'{wname} Wavelet')
    axes[i].grid(True, alpha=0.3)
    axes[i].legend()

plt.tight_layout()
plt.show()

# 2. 模拟一个包含不同频率成分的合成信号
t = np.linspace(0, 1, 400, endpoint=False)
# 信号包含:一个低频正弦波 + 一个中频正弦波 + 一个时间点上的瞬时脉冲
signal = np.sin(2 * np.pi * 5 * t) + 0.5 * np.sin(2 * np.pi * 20 * t)
signal[200:210] += 2.0  # 在第200-210个采样点加入一个脉冲

fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 6))
ax1.plot(t, signal)
ax1.set_title('Original Signal (5Hz + 20Hz + Impulse)')
ax1.set_xlabel('Time')
ax1.set_ylabel('Amplitude')
ax1.grid(True, alpha=0.3)

# 3. 进行连续小波变换(CWT)可视化
scales = np.arange(1, 64)  # 定义一系列尺度
coefficients, frequencies = pywt.cwt(signal, scales, 'morl')  # 使用墨西哥帽小波

# 绘制小波尺度图
im = ax2.imshow(np.abs(coefficients), extent=[0, 1, 1, 64], cmap='PRGn', aspect='auto',
                vmax=abs(coefficients).max(), vmin=-abs(coefficients).max())
ax2.set_title('Continuous Wavelet Transform (CWT) Scalogram')
ax2.set_xlabel('Time')
ax2.set_ylabel('Scale (近似频率倒数)')
plt.colorbar(im, ax=ax2, label='Coefficient Magnitude')
plt.tight_layout()
plt.show()

运行这段代码,你会看到两幅图。第一幅图展示了不同小波函数的形状,haar是方波,db2sym5就光滑复杂多了。第二幅图的上半部分是我们的合成信号,下半部分就是它的连续小波变换尺度图。在这张尺度图上,你能清晰地看到:在尺度较大(图上方,对应低频)的区域,有两条贯穿始终的亮带,那就是我们的5Hz和20Hz正弦波;而在时间0.5附近(对应信号索引200),所有尺度上都出现了一条垂直的亮线,这正是那个瞬时脉冲!它被所有尺度的小波同时“捕捉”到了,而且时间定位极其精确。这张图完美诠释了小波变换的时频局部化能力:既能知道有什么频率成分,又能知道它们什么时候发生。

3. 实战一:用Python给信号和图像“降噪美颜”

噪声是信号处理中永恒的敌人,无论是音频里的嘶嘶声、图像上的颗粒感,还是传感器读数中的随机抖动。传统低通滤波器像一把大砍刀,会把高频信号(包括噪声和有用的边缘细节)一起切掉,结果就是信号变模糊了。小波去噪则聪明得多,它基于一个观察:真实的信号通常在小波域有少量大的系数(集中在重要的特征上),而噪声的能量则分散在大量的小系数中。因此,去噪就变成了一个“阈值筛选”游戏。

我来带你一步步实现一个更鲁棒的小波去噪流程,这里会涉及到软阈值和硬阈值的区别,这也是一个容易踩坑的点。

import numpy as np
import matplotlib.pyplot as plt
import pywt
from scipy import signal

# 1. 生成一个带噪声的仿真信号(模拟ECG心电片段)
np.random.seed(42)
t = np.linspace(0, 1, 1000)
# 模拟心电信号:一个基础心率 + 一个更尖锐的QRS波
clean_signal = np.sin(2 * np.pi * 2 * t)  # 基础心率约2Hz
# 在特定位置添加更尖锐的波模拟心跳
for pos in [0.2, 0.5, 0.8]:
    idx = int(pos * len(t))
    clean_signal[idx:idx+30] += 1.5 * signal.gaussian(30, std=5)

# 添加高斯白噪声
noise = np.random.normal(0, 0.5, clean_signal.shape)
noisy_signal = clean_signal + noise

# 2. 小波分解
# 选择一个小波基,'db4'(Daubechies 4)在生物信号处理中很常用
wavelet = 'db4'
level = 5  # 分解层数
coeffs = pywt.wavedec(noisy_signal, wavelet, level=level)

# 3. 阈值估计与处理 - 这是核心!
# 通用阈值(VisuShrink):sigma * sqrt(2*log(N)),其中sigma用最细尺度系数的中位数估计
sigma = np.median(np.abs(coeffs[-1])) / 0.6745  # 估计噪声标准差
N = len(noisy_signal)
universal_threshold = sigma * np.sqrt(2 * np.log(N))

# 定义阈值函数
def soft_threshold(data, threshold):
    """软阈值:将绝对值小于阈值的系数收缩到0,大于的向零收缩。"""
    return np.sign(data) * np.maximum(np.abs(data) - threshold, 0)

def hard_threshold(data, threshold):
    """硬阈值:简单的保留或置零。"""
    return data * (np.abs(data) > threshold)

# 对细节系数(高频部分)应用阈值,保留近似系数(低频趋势)
new_coeffs = coeffs.copy()
for i in range(1, len(coeffs)):  # 从第1个开始,第0个是近似系数
    new_coeffs[i] = soft_threshold(coeffs[i], universal_threshold)
    # 也可以试试硬阈值:new_coeffs[i] = hard_threshold(coeffs[i], universal_threshold)

# 4. 小波重构
denoised_signal = pywt.waverec(new_coeffs, wavelet)

# 5. 可视化对比
fig, axes = plt.subplots(3, 1, figsize=(12, 8), sharex=True)
axes[0].plot(t, clean_signal, 'b', linewidth=1.5, label='Clean Signal')
axes[0].set_title('Original Clean Signal (Simulated ECG)')
axes[0].legend()
axes[0].grid(True, alpha=0.3)

axes[1].plot(t, noisy_signal, 'r', alpha=0.7, linewidth=1, label='Noisy Signal')
axes[1].plot(t, clean_signal, 'b:', linewidth=1, label='Clean (Reference)')
axes[1].set_title('Noisy Signal (SNR={:.2f} dB)'.format(10*np.log10(np.var(clean_signal)/np.var(noise))))
axes[1].legend()
axes[1].grid(True, alpha=0.3)

axes[2].plot(t, denoised_signal, 'g', linewidth=1.5, label='Wavelet-Denoised')
axes[2].plot(t, clean_signal, 'b:', linewidth=1, label='Clean (Reference)')
axes[2].set_title('After Wavelet Denoising (Soft Thresholding)')
axes[2].set_xlabel('Time')
axes[2].legend()
axes[2].grid(True, alpha=0.3)

plt.tight_layout()
plt.show()

# 计算并打印去噪效果指标
mse = np.mean((clean_signal - denoised_signal)**2)
psnr = 10 * np.log10(np.max(clean_signal)**2 / mse)
print(f'去噪效果评估:')
print(f'  均方误差 (MSE): {mse:.4f}')
print(f'  峰值信噪比 (PSNR): {psnr:.2f} dB')

在这个例子中,我们模拟了一段带噪声的心电信号。小波去噪的关键步骤是阈值的选择和处理。软阈值函数会产生更平滑的结果,因为它是连续收缩的;而硬阈值函数能更好地保留信号的突变边缘,但在阈值处不连续,有时会引入人为振荡。实际应用中,软阈值更常用。运行代码后,你会看到噪声被有效地抑制了,而代表心跳的尖锐QRS波特征却被很好地保留了下来,这正是小波变换多分辨率分析的优势体现:在去除高频噪声的同时,保留了属于信号本身的高频特征。

4. 实战二:理解小波图像压缩与“能量集中”魔法

为什么JPEG2000标准要选用小波变换取代经典的DCT(离散余弦变换)?核心秘密在于“能量集中”特性。对于大多数自然图像,其能量(信息)在经过小波变换后,会高度集中在少数几个大的系数上,而大量系数都接近于零。图像压缩的本质就是“丢弃不重要的信息,保留最重要的信息”。小波变换天然地为我们做好了这份“重要性排序”。

我们来动手实现一个可调节压缩率的小波图像压缩器,并直观感受压缩带来的影响。

import numpy as np
import matplotlib.pyplot as plt
import pywt
import pywt.data
from skimage.metrics import peak_signal_noise_ratio as psnr
from skimage.metrics import structural_similarity as ssim

# 1. 加载图像并转换为灰度图(如果是彩色图,可对每个通道分别处理)
original = pywt.data.camera().astype(np.float32)
print(f"原始图像尺寸: {original.shape}, 数据类型: {original.dtype}")

# 2. 执行多级二维小波分解
# 使用‘bior2.2’双正交小波,它在图像压缩中平衡了平滑性和对称性,效果很好
wavelet = 'bior2.2'
level = 4  # 分解4层
coeffs = pywt.wavedec2(original, wavelet, level=level)
# coeffs 是一个列表:[cA_n, (cH_n, cV_n, cD_n), ..., (cH_1, cV_1, cD_1)]
# cA: 近似系数(低频), cH:水平细节, cV:垂直细节, cD:对角线细节

# 3. 将系数数组扁平化,以便全局排序和阈值处理
coeff_arr, coeff_slices = pywt.coeffs_to_array(coeffs)
print(f"小波系数总数: {coeff_arr.size}")
print(f"系数绝对值范围: [{np.abs(coeff_arr).min():.2e}, {np.abs(coeff_arr).max():.2e}]")

# 4. 定义不同的压缩率(保留能量百分比)
compression_ratios = [0.5, 0.1, 0.05, 0.02]  # 保留前50%, 10%, 5%, 2%的系数
fig, axes = plt.subplots(2, len(compression_ratios)+1, figsize=(16, 8))

# 显示原图
axes[0, 0].imshow(original, cmap='gray')
axes[0, 0].set_title(f'Original\n100% Coefficients')
axes[0, 0].axis('off')
axes[1, 0].axis('off') # 第二行第一列留空或用于其他信息

results = []
for idx, ratio in enumerate(compression_ratios):
    # 计算阈值:只保留绝对值最大的前 ratio*100% 的系数
    threshold = np.percentile(np.abs(coeff_arr), (1 - ratio) * 100)
    # 应用硬阈值:小于阈值的系数置零
    coeff_arr_compressed = coeff_arr * (np.abs(coeff_arr) > threshold)

    # 统计压缩情况
    num_retained = np.sum(np.abs(coeff_arr_compressed) > 0)
    actual_ratio = num_retained / coeff_arr.size
    print(f"设定保留比例 {ratio:.0%} -> 实际保留系数 {num_retained} 个,占 {actual_ratio:.2%}")

    # 5. 从小波系数数组重构回系数列表结构
    coeffs_compressed = pywt.array_to_coeffs(coeff_arr_compressed, coeff_slices, output_format='wavedec2')

    # 6. 小波重构
    reconstructed = pywt.waverec2(coeffs_compressed, wavelet)
    # 确保重构图像尺寸与原图一致(由于边界处理,有时会差1个像素)
    reconstructed = reconstructed[:original.shape[0], :original.shape[1]]

    # 计算图像质量指标
    psnr_val = psnr(original, reconstructed, data_range=original.max()-original.min())
    ssim_val = ssim(original, reconstructed, data_range=original.max()-original.min())
    results.append((reconstructed, psnr_val, ssim_val, actual_ratio))

    # 可视化
    col = idx + 1
    axes[0, col].imshow(reconstructed, cmap='gray')
    axes[0, col].set_title(f'Retain {actual_ratio:.1%}\nPSNR={psnr_val:.1f}dB')
    axes[0, col].axis('off')

    # 显示被丢弃的系数(即误差)
    error = np.abs(original - reconstructed)
    im_error = axes[1, col].imshow(error, cmap='hot', vmin=0, vmax=50)
    axes[1, col].set_title(f'Error Map\nSSIM={ssim_val:.3f}')
    axes[1, col].axis('off')
    plt.colorbar(im_error, ax=axes[1, col], fraction=0.046, pad=0.04)

plt.suptitle('Wavelet Image Compression at Different Ratios', fontsize=16)
plt.tight_layout()
plt.show()

# 打印压缩比与文件大小估算(假设每个系数用float32存储)
original_size = original.nbytes / 1024  # KB
print(f"\n--- 压缩性能估算 ---")
print(f"原始图像大小: {original_size:.1f} KB (未压缩)")
for i, (_, psnr_val, ssim_val, act_ratio) in enumerate(results):
    compressed_size_estimate = original_size * act_ratio  # 简化估算,忽略编码开销
    compression_ratio = original_size / compressed_size_estimate
    print(f"保留{act_ratio:.2%}系数: 估算大小{compressed_size_estimate:.1f}KB, 压缩比~{compression_ratio:.1f}:1, PSNR={psnr_val:.1f}dB")

运行这段代码,你会看到一个非常直观的对比。第一行是不同压缩率下的重构图像,第二行是对应的误差热图。当只保留2%的系数时,图像虽然有些模糊,但主要轮廓和特征依然清晰可辨,而文件大小理论上可以压缩到原来的2%左右。小波压缩的优势在于,它丢弃的是高频细节系数(对应图像的纹理和噪声),而保留了代表图像大体轮廓和结构的低频近似系数。这种按照“重要性”分层处理的方式,比JPEG的块状DCT变换更能避免在低码率下产生令人讨厌的“方块效应”。在实际项目中,你还可以通过选择不同的小波基(如‘db8’, ‘sym8’)、调整分解层数、或者对保留的系数进行更高效的熵编码(如EZW, SPIHT算法),来进一步优化压缩效果。

5. 实战三:小波在边缘检测与特征提取中的独特视角

边缘检测是计算机视觉的基石。Sobel、Canny等经典算子大家都很熟悉,它们本质上是基于图像局部梯度的计算。而小波变换提供了一个不同的视角:图像的边缘和纹理信息,正好对应着小波分解后得到的高频细节分量。具体来说,二维图像经过一层小波分解后,会得到四个子图:LL(低频近似,即缩略图)、LH(水平细节,捕捉垂直边缘)、HL(垂直细节,捕捉水平边缘)、HH(对角线细节)。我们可以直接利用这些高频分量来构造边缘图像。

更妙的是,小波的多尺度特性让我们可以分析不同“粗细”程度的边缘。大尺度下的边缘对应图像中大的物体轮廓,小尺度下的边缘则对应更精细的纹理和细节。我们来做一个多尺度边缘检测的实验。

import numpy as np
import matplotlib.pyplot as plt
import pywt
import cv2  # 用于对比传统Canny算子

# 1. 加载图像并预处理
image = pywt.data.camera().astype(np.float32)
# 为了更清晰展示,我们也可以使用一个合成图像
synth_img = np.zeros((256, 256))
synth_img[64:192, 64:192] = 128  # 一个灰色方块
synth_img[100:156, 100:156] = 200 # 方块中心一个更亮的方块
# 添加一些噪声
np.random.seed(0)
image_noisy = image + np.random.normal(0, 15, image.shape)

# 2. 单尺度小波边缘检测 (使用Haar小波,因其边缘响应类似差分)
def wavelet_edge_detection(img, wavelet='haar'):
    """使用单层小波分解的高频系数进行边缘检测"""
    coeffs2 = pywt.dwt2(img, wavelet)
    LL, (LH, HL, HH) = coeffs2
    # 常见的边缘强度计算方式:将三个方向的高频细节绝对值相加
    edges = np.abs(LH) + np.abs(HL) + np.abs(HH)
    # 也可以尝试其他组合,如求平方和的开方: edges = np.sqrt(LH**2 + HL**2 + HH**2)
    # 归一化到0-255以便显示
    edges_norm = cv2.normalize(edges, None, 0, 255, cv2.NORM_MINMAX).astype(np.uint8)
    return edges_norm, (LH, HL, HH)

# 3. 多尺度小波边缘检测
def multiscale_wavelet_edges(img, wavelet='db2', max_level=3):
    """进行多层小波分解,并融合各层的边缘信息"""
    # 进行多级分解
    coeffs = pywt.wavedec2(img, wavelet, level=max_level)
    # coeffs[0]是第max_level层的LL,coeffs[1]是第max_level层的(LH,HL,HH), ... coeffs[-1]是第1层的
    all_edges = np.zeros_like(img)
    for i in range(1, len(coeffs)):
        LH, HL, HH = coeffs[i]
        # 计算当前尺度的边缘强度
        level_edges = np.abs(LH) + np.abs(HL) + np.abs(HH)
        # 将当前尺度的边缘图上采样到原始图像尺寸并累加
        level_edges_full = pywt.upcoef2('a', level_edges, wavelet, level=i, take=0)[:img.shape[0], :img.shape[1]]
        all_edges += level_edges_full
    # 归一化
    all_edges_norm = cv2.normalize(all_edges, None, 0, 255, cv2.NORM_MINMAX).astype(np.uint8)
    return all_edges_norm

# 4. 与传统Canny算子对比
edges_wavelet_single, _ = wavelet_edge_detection(image)
edges_wavelet_multi = multiscale_wavelet_edges(image, max_level=3)

# 使用Canny算子 (需要先将图像转换为8位)
image_uint8 = cv2.normalize(image, None, 0, 255, cv2.NORM_MINMAX).astype(np.uint8)
edges_canny = cv2.Canny(image_uint8, threshold1=50, threshold2=150)

# 5. 在有噪声图像上测试小波方法的鲁棒性
edges_wavelet_noisy, _ = wavelet_edge_detection(image_noisy)
# 小波去噪后再检测
coeffs_n = pywt.wavedec2(image_noisy, 'db4', level=3)
# 简单阈值去噪
coeffs_thresh = [coeffs_n[0]] + [tuple(pywt.threshold(c, value=30, mode='soft') for c in detail) for detail in coeffs_n[1:]]
image_denoised = pywt.waverec2(coeffs_thresh, 'db4')
edges_wavelet_denoised, _ = wavelet_edge_detection(image_denoised)

# 6. 可视化
fig, axes = plt.subplots(3, 4, figsize=(16, 12))
titles = ['Original', 'Noisy Image', 'Wavelet Edges (Single Scale)', 'Canny Edges',
          'Wavelet Edges (Multi-Scale)', 'LH (Horiz. Detail)', 'HL (Vert. Detail)', 'HH (Diag. Detail)',
          'Denoised Image', 'Edges on Noisy Img', 'Edges after Denoising', 'Multi-scale Components']

images_to_show = [image, image_noisy, edges_wavelet_single, edges_canny,
                  edges_wavelet_multi, None, None, None,
                  image_denoised, edges_wavelet_noisy, edges_wavelet_denoised, None]

# 填充LH, HL, HH子图
_, (LH, HL, HH) = pywt.dwt2(image, 'haar')
images_to_show[5] = np.abs(LH)
images_to_show[6] = np.abs(HL)
images_to_show[7] = np.abs(HH)
# 最后一格展示多尺度分解的示意图(用文字或简单图示)
axes[2, 3].text(0.5, 0.5, 'Level 3: Coarse\nLevel 2: Medium\nLevel 1: Fine\nCombined = Multi-scale Edges',
                 ha='center', va='center', fontsize=12, transform=axes[2, 3].transAxes)
axes[2, 3].axis('off')

for i, ax in enumerate(axes.flat):
    if i == 11:
        continue  # 最后一格已处理
    ax.imshow(images_to_show[i], cmap='gray')
    ax.set_title(titles[i])
    ax.axis('off')

plt.suptitle('Wavelet-Based Edge Detection vs. Traditional Methods', fontsize=16, y=1.02)
plt.tight_layout()
plt.show()

print("解读:")
print("1. 单尺度小波边缘:直接利用一层分解的高频系数,能快速检测边缘,但对噪声敏感。")
print("2. 多尺度小波边缘:融合了粗、中、细多个尺度的边缘信息,能同时捕捉大轮廓和细纹理,更全面。")
print("3. 与传统Canny对比:小波方法无需手动调节双阈值,且其多尺度特性更符合人眼视觉。")
print("4. 鲁棒性:在噪声图像上,直接检测效果差;先小波去噪再检测,效果显著提升,体现了小波框架的统一性。")

通过这个对比实验,你可以清晰地看到小波边缘检测的特点。单尺度检测速度快,但噪声干扰大。多尺度检测通过融合不同分辨率的边缘信息,得到了更丰富、层次更分明的边缘图,既包含了相机外壳的大轮廓,也包含了人物衣服的纹理。更重要的是,小波变换将“去噪”和“特征提取”统一在了同一个数学框架下。我们可以先对图像进行小波阈值去噪,然后再用同样的工具进行边缘检测,整个流程非常自然和高效。在实际的故障诊断、医学影像分析中,这种多尺度分析能力对于区分不同大小的缺陷或病灶至关重要。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐