如何用Python提取图像中模糊重复的图案?
提取图像中模糊重复图案的Python实现方案
针对提取模糊重复图案并去除其他特征的需求,可通过频域分析(傅里叶变换)或模板匹配+形态学优化两种思路实现,以下是具体步骤和代码示例:
方法一:傅里叶变换检测重复图案周期
重复图案在频域会呈现规律性峰值,通过过滤噪声、保留周期信号后逆变换回空域,即可提取目标图案。
步骤说明
- 将图像转为灰度图简化处理
- 执行傅里叶变换得到频域图像
- 构建掩码保留周期信号、过滤无关噪声
- 逆傅里叶变换还原空域图像
- 阈值化得到清晰的提取结果
代码示例
import cv2 import numpy as np import matplotlib.pyplot as plt # 读取图像并转为灰度图 img = cv2.imread("ONKc3.png") gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 傅里叶变换 f = np.fft.fft2(gray) fshift = np.fft.fftshift(f) magnitude = 20 * np.log(np.abs(fshift)) # 构建频域掩码:保留重复图案对应的周期信号(可根据图像调整范围) rows, cols = gray.shape crow, ccol = rows // 2, cols // 2 mask = np.zeros((rows, cols), np.uint8) mask[crow-30:crow+30, ccol-30:ccol+30] = 0 # 屏蔽中心低频噪声 mask[crow-100:crow+100, ccol-100:ccol+100] = 1 # 保留周期信号区域 # 应用掩码并逆变换 fshift_filtered = fshift * mask f_ishift = np.fft.ifftshift(fshift_filtered) img_back = np.fft.ifft2(f_ishift) img_back = np.abs(img_back) # 阈值化提取清晰图案 _, result = cv2.threshold(img_back.astype(np.uint8), 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) # 展示结果 plt.subplot(131), plt.imshow(gray, cmap='gray') plt.title('原始灰度图'), plt.xticks([]), plt.yticks([]) plt.subplot(132), plt.imshow(magnitude, cmap='gray') plt.title('频域图'), plt.xticks([]), plt.yticks([]) plt.subplot(133), plt.imshow(result, cmap='gray') plt.title('提取的重复图案'), plt.xticks([]), plt.yticks([]) plt.show()
方法二:模板匹配+形态学处理
若能手动截取单个重复图案作为模板,可通过多尺度匹配定位所有实例,再用形态学操作优化结果。
步骤说明
- 从原图截取清晰的单个重复图案作为模板
- 多尺度模板匹配定位所有目标区域
- 用形态学闭运算合并零散匹配结果
- 通过掩码提取最终的重复图案
代码示例
import cv2 import numpy as np # 读取图像和手动截取的模板 img = cv2.imread("ONKc3.png") gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) template = cv2.imread("template.png", 0) w, h = template.shape[::-1] # 多尺度模板匹配,覆盖图案可能的缩放差异 result_mask = np.zeros_like(gray) scale_range = np.linspace(0.8, 1.2, 10) for scale in scale_range: resized_template = cv2.resize(template, (int(w*scale), int(h*scale))) res = cv2.matchTemplate(gray, resized_template, cv2.TM_CCOEFF_NORMED) threshold = 0.6 # 匹配阈值,需根据实际调整 loc = np.where(res >= threshold) # 标记所有匹配区域 for pt in zip(*loc[::-1]): cv2.rectangle(result_mask, pt, (pt[0] + int(w*scale), pt[1] + int(h*scale)), 255, -1) # 形态学优化:合并相邻的匹配区域 kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5)) result_mask = cv2.morphologyEx(result_mask, cv2.MORPH_CLOSE, kernel) # 提取最终图案 extracted_img = cv2.bitwise_and(img, img, mask=result_mask) # 展示结果 cv2.imshow("原始图像", img) cv2.imshow("提取的重复图案", extracted_img) cv2.waitKey(0) cv2.destroyAllWindows()
关键提示
- 傅里叶变换适合重复图案周期规律的场景,无需手动制作模板
- 模板匹配更灵活,可适配图案轻微变形的情况,但需手动截取模板
- 可结合你之前尝试的HSV/YCrCb颜色空间转换,先增强图案与背景的对比度,再用上述方法处理
内容的提问来源于stack exchange,提问作者BFAOZ
相关产品推荐
相关产品推荐

