频域圆形区域划分+可视化

频域圆形区域划分+可视化

一、简单说明

  这是之前写的一部分创新性代码,现在整理讲解一下。
  首先,通过FFT(快速傅里叶变化)进行频域分析是一般性的常规操作,通过频域的频域特征分析图像整体或是图像分块之后的小图像块,计算幅度谱最高值、均值或是标准差,可以去反映振动程度/振动强度/频域特征。
  (这里补一下对于频谱和幅度谱的理解,简单来说,傅里叶变化将空间中的二维坐标点变为频谱中的频点,频点坐标(u,v)分别表示水平和垂直方向的频率,取两者平方根可以得到幅度谱值,取两者之间的夹角表示相位,也有相位表)

术语 数学表达 物理意义
频谱 F(u,v) = R(u,v) + I(u,v)i 复数矩阵,同时包含幅度和相位信息
幅度谱 |F(u,v)|= √(R(u,v)² + I(u,v)²) 反映每个频点对应的能量强度
相位谱 ϕ(u,v) = arctan(I(u,v)/R(u,v)) 反映每个非零频点对应的时移角度,对噪声敏感

  划分环形区域主要是基于能量强度,也就是幅度谱。
  具体的,将直角坐标转换为极坐标,从而划定环形区域。
  下述代码中,环形区域半径是互不重叠的,但是 理论上步长以及半径都可以自己设定。

二、代码部分

运行环境就是Spyder(python3.7)奥

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

def analyze_spectrum(image_path, ring_num=10):
    """
    图像频域分析与环形区域划分(含环形边界可视化)

    参数:
        image_path (str): 输入灰度图像路径
        ring_num (int): 划分的环形区域数量

    返回:
        dict: 包含中间结果的字典(幅度谱、极坐标参数、环形区间及图像尺寸)
    """
    # 步骤1:读取灰度图像并归一化
    img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
    if img is None:
        raise ValueError("无法读取图像文件,请检查路径")
    img = img.astype(np.float32)

    # 获取图像尺寸并计算最大有效半径(新增逻辑)
    rows, cols = img.shape
    max_dim = min(rows, cols)
    max_valid_radius = max_dim // 2  # 保证不超过任意轴的一半

    # 步骤2-4:FFT变换与幅度谱计算(保持不变)
    fft2 = np.fft.fft2(img)
    fft_shift = np.fft.fftshift(fft2)
    magnitude_spectrum = np.log(1 + np.abs(fft_shift))

    # 步骤5:极坐标转换(新增边界保护)
    u = np.linspace(-cols//2, cols//2 - 1, cols)
    v = np.linspace(-rows//2, rows//2 - 1, rows)
    u_grid, v_grid = np.meshgrid(u, v)
    rho = np.sqrt(u_grid**2 + v_grid**2)
    
    # 步骤6:环形划分(核心修改)
    ring_borders = np.linspace(0, max_valid_radius, ring_num + 1)
    ring_borders[-1] = min(ring_borders[-1], max_valid_radius)  # 强制约束最大边界

    return {
        'magnitude_spectrum': magnitude_spectrum,
        'ring_borders': ring_borders,
        'rows': rows,
        'cols': cols
    }

# 可视化部分
if __name__ == "__main__":
    # 示例用法
    image_path = "gray_image.jpg"  # 替换为实际路径
    result = analyze_spectrum(image_path, ring_num=8)

    # 绘制结果
    plt.figure(figsize=(12, 6))

    # 原始图像
    plt.subplot(1, 2, 1)
    plt.imshow(cv2.imread(image_path, cv2.IMREAD_GRAYSCALE), cmap='gray')
    plt.title('Original Image')
    plt.axis('off')

    # 频域幅度谱(含环形标注)
    plt.subplot(1, 2, 2)
    plt.imshow(result['magnitude_spectrum'], cmap='gray')
    plt.title('Magnitude Spectrum with Rings')

    # 获取图像中心坐标
    center = (result['cols'] // 2, result['rows'] // 2)

    # 绘制所有环形边界
    for r in result['ring_borders'][1:]:  # 跳过第一个0半径
        circle = plt.Circle(center, r, color='black', fill=False, linewidth=1)
        plt.gca().add_artist(circle)

    plt.axis('off')
    plt.show()

三、代码可视化

频域圆形区域划分+可视化_第1张图片

你可能感兴趣的:(图像处理)