You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Python的图像FFT峰值自动检测与抑制技术问询

图像划痕抑制:FFT峰值自动识别与置零实现方案

整体思路

图像中的直线/周期性划痕在频域会表现为高亮的峰值簇(亮线),通过FFT变换将图像转到频域,自动定位这些峰值并置零,再通过逆FFT还原即可消除划痕噪声。核心流程:图像加载→FFT变换→频域峰值检测→峰值置零→逆FFT还原。


1. 依赖库导入

先准备好需要的工具库:

import numpy as np
import cv2
from scipy.ndimage import maximum_filter
import matplotlib.pyplot as plt

2. 图像加载与FFT变换

先把图像转为灰度图(彩色图需转灰度再处理),再做FFT并将频域中心移到图像中心:

# 加载图像并转为灰度格式
img = cv2.imread('your_scratch_image.jpg', 0)
rows, cols = img.shape

# FFT变换+移频到中心
f = np.fft.fft2(img)
f_shift = np.fft.fftshift(f)

# 生成幅度谱(仅用于可视化,实际处理可跳过)
magnitude_spectrum = 20 * np.log(np.abs(f_shift))

3. 自动识别频域峰值

这里提供两种实用的峰值检测方案,根据你的划痕类型选择:

方案一:阈值筛选+连通域分析(适合明显的长条划痕)

针对划痕在频域形成的连续亮线,用二值化+形态学处理过滤噪点,再提取连通域中心作为峰值坐标:

# 取幅度谱前0.5%的亮区作为峰值候选(阈值可根据图像调整)
threshold = np.percentile(magnitude_spectrum, 99.5)
binary = (magnitude_spectrum > threshold).astype(np.uint8)

# 形态学开运算+膨胀:去除小噪点,保留连续的峰值线
kernel = np.ones((3,3), np.uint8)
binary_clean = cv2.morphologyEx(binary, cv2.MORPH_OPEN, kernel)
binary_clean = cv2.morphologyEx(binary_clean, cv2.MORPH_DILATE, kernel)

# 提取连通域中心坐标
contours, _ = cv2.findContours(binary_clean, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
peak_coords = []
for cnt in contours:
    M = cv2.moments(cnt)
    if M["m00"] != 0:
        cX = int(M["m10"] / M["m00"])
        cY = int(M["m01"] / M["m00"])
        peak_coords.append((cX, cY))

方案二:局部最大值检测(适合分散的小点状峰值)

用局部最大值过滤器定位峰值,再结合阈值筛选有效点:

# 用5x5窗口找局部最大值(窗口大小根据峰值尺寸调整)
local_max = maximum_filter(magnitude_spectrum, size=5) == magnitude_spectrum
# 结合阈值筛选有效峰值
peaks = local_max & (magnitude_spectrum > threshold)
# 提取所有峰值坐标
peak_coords = np.argwhere(peaks)

4. 峰值置零与逆FFT还原

注意:频域是共轭对称的,必须同时置零对称位置的峰值,否则会引入伪影

# 获取频域中心坐标
crow, ccol = rows // 2, cols // 2

# 遍历所有峰值,置零当前位置+对称位置
for (x, y) in peak_coords:
    f_shift[x, y] = 0
    # 计算对称位置坐标
    sym_x = 2 * crow - x
    sym_y = 2 * ccol - y
    f_shift[sym_x, sym_y] = 0

# 逆移频+逆FFT还原图像
f_ishift = np.fft.ifftshift(f_shift)
img_restored = np.fft.ifft2(f_ishift)
# 取实部并转为8位图像(消除计算产生的微小虚部)
img_restored = np.abs(img_restored).astype(np.uint8)

5. 结果可视化(可选)

可以对比原始图、频域谱、处理后的频域谱和还原图:

plt.figure(figsize=(12,8))
plt.subplot(221), plt.imshow(img, cmap='gray')
plt.title('Original Image'), plt.xticks([]), plt.yticks([])
plt.subplot(222), plt.imshow(magnitude_spectrum, cmap='gray')
plt.title('FFT Magnitude Spectrum'), plt.xticks([]), plt.yticks([])
plt.subplot(223), plt.imshow(20*np.log(np.abs(f_shift)), cmap='gray')
plt.title('FFT After Peak Zeroing'), plt.xticks([]), plt.yticks([])
plt.subplot(224), plt.imshow(img_restored, cmap='gray')
plt.title('Restored Image'), plt.xticks([]), plt.yticks([])
plt.show()

关键调参提示

  • 阈值调整:百分位数阈值(如99.5)可根据图像划痕的明显程度修改,避免误删有效频域信息
  • 窗口大小:局部最大值的窗口尺寸要匹配划痕频域线的宽度,过大漏峰,过小会多检噪点
  • 对称置零:必须处理共轭对称点,否则逆FFT会产生严重伪影

内容的提问来源于stack exchange,提问作者coldaf_876

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 20:10:11