OpenCV图像修复实例讲解

19人浏览 / 0人评论 / 添加收藏

OpenCV 提供了两种经典的图像修复算法,可以方便地去除照片中的水印、划痕、日期戳,或者移除不需要的物体。它的核心思想是利用图像中完好的区域,来填充被标记为“损坏”的区域。

🧠 两种内置算法

OpenCV 的 inpaint 函数支持两种算法,通过 flags 参数选择:

 
 
算法 原理简介 特点
cv2.INPAINT_NS 基于 Navier-Stokes 方程,将图像强度看作流体,沿着边缘等照度线方向扩散信息进入待修复区域。 适合平滑连续的边缘,保持结构。
cv2.INPAINT_TELEA 基于 快速行进法 (FMM),从区域边界开始逐步向内填充,优先处理边界像素,利用邻近已知像素加权平均。 计算更快,对纹理较少的区域效果好。

📦 核心函数

dst = cv2.inpaint(src, mask, inpaintRadius, flags)

src:输入图像(8位单/三通道,修复时通常用彩色图)。

mask:修复掩膜,8位单通道,非零像素表示需要修复的区域(通常用 255 表示白)。

inpaintRadius:修复时考虑的邻域半径。值越大,参考范围越广,但也可能更模糊。

flagscv2.INPAINT_TELEAcv2.INPAINT_NS

🛠️ 完整示例(Python)

# 图片修复,要求把一张图片上的测字擦除,代码如下:
import cv2
import numpy as np
from opencv_jupyter_ui import cv2_imshow

img = cv2.imread('./images/inpaint.png')
mask = cv2.imread('./images/inpaint_mask.png', 0)
dst1 = cv2.inpaint(img, mask, 5, cv2.INPAINT_TELEA)
dst2 = cv2.inpaint(img, mask, 5, cv2.INPAINT_NS)

# cv2_imshow('dst', np.hstack((img,mask,dst)))
cv2_imshow('dst', np.hstack((img,dst1,dst2)))
# cv2.imshow('dst', np.hstack((img,mask,dst)))
# cv2.waitKey(0)
# cv2.destroyAllWindows()

图像展示如下:

✨ 实用技巧

掩膜质量决定效果:修复区域必须精准覆盖缺陷,且边界最好稍微多包含几个像素(用膨胀操作),否则会在边缘留下模糊痕迹。

半径选择

细划痕:半径可以小一些(3~5)

大块缺失:半径需要稍大(5~10),但过大会导致明显模糊。

可尝试不同值,观察修复痕迹。

两种算法比较:如果边界清晰、纹理简单,TELEA 够用且快;若希望更好保持边缘连贯性(比如移除线条),NS 有时更自然。

大物体移除:传统 inpaint 对大面积纹理区域效果有限,可能会出现模糊块,此时需要更高级的基于深度学习的修复方法(如 LaMa、Stable Diffusion Inpainting)。

全部评论