前面我们学完非局部均值去噪,可以解决图片颗粒噪点、压缩噪点。
但在实际项目中,图片往往存在划痕、污渍、霉斑、水印、遮挡、小面积破损。
这类属于像素缺失、结构损坏,普通滤波、模糊降噪完全无能为力。
想要智能填充破损区域、还原自然画面,就要用到 OpenCV 的高阶修复技术:Inpainting 图像修补。
它的核心能力:根据周边纹理,智能推算缺失区域,实现无痕修复。
今天带大家彻底吃透 Inpainting 两大算法原理、区别、参数调优、两套可落地实战代码,从零学会图片瑕疵修复!
一、什么是图像修补(Inpainting)?
通俗理解:机器看图“脑补”缺失部分。
Inpainting 是一种基于邻域纹理扩散的图像修复技术:
只要你告诉算法「哪里坏了」,算法就会根据周围像素的颜色、梯度、纹理结构,自动填充破损区域,让画面过渡自然、看不出修补痕迹。
修复必备条件:Mask掩码
想要修复图片,必须先制作掩码:
•黑色(0):保留原图区域
•白色(255):需要修补、擦除、填充的区域
简单说:白的修、黑的留。
二、OpenCV 两种 Inpainting 算法详解
OpenCV 内置两套工业级修复算法,场景完全不同,千万别乱用!
1、INPAINT_TELEA(快速行进法)
原理:从破损边缘开始,由外向内匀速扩散填充像素。
优点:速度极快、轻量化、适合实时处理
适合场景:细划痕、细线污渍、小点霉斑、轻微破损
2、INPAINT_NS(流体动力学修复)
原理:模拟流体扩散模型,更大范围搜索纹理、拟合梯度变化。
优点:大面积缺损修复更自然、纹理保留更好、过渡更平滑
缺点:速度较慢
适合场景:老照片大面积破损、水印去除、块状污渍、复杂缺损
一句话选型:小瑕疵用 TELEA,大破损用 NS。
三、inpaint 函数参数全解
pythoncv2.inpaint(src, mask, inpaintRadius, flags) |
•src:原始图像(彩色/灰度均可)
•mask:单通道掩码图,白色代表待修复区域
•inpaintRadius:修复半径(3~5最佳)
•flags:修复算法 TELEA / NS
四、实战一:固定掩码修复(标准工程写法)
适合批量处理、老照片修复、瑕疵统一修复场景。
pythonimport cv2import numpy as np# 读取破损图片img = cv2.imread("damage.jpg")# 读取掩码(必须单通道)mask = cv2.imread("mask.png", 0)# 两种算法同时修复res_telea = cv2.inpaint(img, mask, 3, cv2.INPAINT_TELEA)res_ns = cv2.inpaint(img, mask, 3, cv2.INPAINT_NS)# 展示效果cv2.imshow("Original", img)cv2.imshow("Mask", mask)cv2.imshow("TELEA修复", res_telea)cv2.imshow("NS精细修复", res_ns)# 保存结果cv2.imwrite("result_telea.jpg", res_telea)cv2.imwrite("result_ns.jpg", res_ns)cv2.waitKey(0)cv2.destroyAllWindows() |
五、实战二:鼠标交互式涂抹修复(超级实用)
无需PS、无需绘图工具,代码直接鼠标涂抹瑕疵,一键修复,日常修图神器!
pythonimport cv2import numpy as npimg = cv2.imread("old.jpg")mask = np.zeros(img.shape[:2], np.uint8)drawing = False# 鼠标绘制回调def draw_mask(event, x, y, flags, param):global drawingif event == cv2.EVENT_LBUTTONDOWN:drawing = Trueelif event == cv2.EVENT_MOUSEMOVE and drawing:cv2.circle(mask, (x, y), 6, 255, -1)elif event == cv2.EVENT_LBUTTONUP:drawing = Falsecv2.namedWindow("Paint to repair")cv2.setMouseCallback("Paint to repair", draw_mask)while True:temp = img.copy()cv2.imshow("Paint to repair", temp)key = cv2.waitKey(1) & 0xFF# 按下s开始修复if key == ord("s"):result = cv2.inpaint(img, mask, 5, cv2.INPAINT_NS)cv2.imshow("Repair Result", result)cv2.imwrite("repair_result.jpg", result)# 按下ESC退出elif key == 27:breakcv2.destroyAllWindows() |
六、两种算法效果对比总结
TELEA
•速度快、适合实时视频修复
•细线、划痕修复干净利落
•大面积修复容易模糊
NS算法
•纹理还原更强、过渡更自然
•适合水印、大块破损、老照片修复
•耗时略高,但画质最佳
七、工程高频避坑指南
•坑1:掩码是三通道图掩码必须单通道灰度图,否则修复失效
•坑2:修复半径过大radius>6 容易造成画面大面积糊化、失真
•坑3:掩码标记不精准白色多画一点会误删原图纹理,少画修复不干净
•坑4:大面积空白强行修复完全无纹理参考的区域,Inpainting无法凭空生成细节
八、全文总结
去噪解决“脏”,修补解决“破”。
Inpainting 是传统OpenCV中最实用、最惊艳的画质修复技术之一:
可以搞定:老照片翻新、划痕去除、文字遮挡擦除、简单水印消除、工业瑕疵修复。
只要破损区域周围有完整纹理,算法就能完美“脑补还原”。
搭配前面学的滤波、形态学操作、色域处理,你已经拥有完整的传统图像画质修复流水线!
❤️ 点赞+在看,后台回复关键词【图像修补】获取:完整工程代码+测试素材+批量修复工具!
关注【AI与计算机视觉】,持续更新全套 OpenCV 从入门到工业落地实战教程!
评论区打卡:Inpainting图像修补