Opencv图像修复的基本概念:
大多数人会在家里放一些旧的退化照片,上面有一些黑点,一些笔画等。你有没有想过恢复它?我们不能简单地在绘画工具中擦除它们,因为它将简单地用白色结构替换黑色结构,这是没有用的。在这些情况下,使用称为图像修复的技术。基本思路很简单:用相邻像素替换那些坏标记,使其看起来像邻域。考虑下面显示的图像
Opencv方法介绍:
cv.inpaint(src, inpaintMask, inpaintRadius, flags) -> dst
Parameters
src 输入 8 位、16 位无符号或 32 位浮点 1 通道或 8 位 3 通道图像。inpaintMask 修复蒙版,8 位 1 通道图像。非零像素表示需要上漆的区域。dst 输出与 src 相同大小和类型的图像。inpaintRadius 算法考虑的每个点的圆形邻域的半径。flags 修复方法可以是 cv::INPAINT_NS 或 cv::INPAINT_TELEAsrc:通俗来说就是输入图像,一般用cv2.imread读取
inpaintMask:通俗来说就是要修复图片的地方在哪,通常是用cv2.zeros(原图尺寸),需要修复的地方变为255
inpaintRadius:通俗来说就是根据修复算法后,每个像素点作为一个圆心,该参数作为半径展开进行修复
flags:修复算法,截止到目前只有两种:
第一种算法基于 2004 年由 Alexandru Telea 撰写的“基于快速行进方法的图像修复技术”。它基于快速行进方法。考虑图像中要修复的区域。算法从该区域的边界开始,然后进入区域内,逐渐填充边界中的所有内容。它需要在邻域像素周围的一个小邻域进行修复。该像素由邻域中所有已知像素的归一化加权和代替。选择权重是一个重要的问题。对于靠近该点的那些像素,靠近边界的法线和位于边界轮廓上的那些像素,给予更多的权重。一旦像素被修复,它将使用快速行进方法移动到下一个最近的像素。 FMM 确保首先修复已知像素附近的像素,这样它就像手动启发式操作一样工作。使用标志 cv.INPAINT_TELEA 启用此算法。
第二种算法基于 Bertalmio,Marcelo,Andrea L. Bertozzi 和 Guillermo Sapiro 在 2001 年的论文“Navier-Stokes,流体动力学和图像和视频修补”。该算法基于流体动力学和利用偏微分方程。基本原则是 heurisitic。它首先沿着已知区域的边缘行进到未知区域(因为边缘是连续的)。它继续等照片(连接具有相同强度的点的线,就像轮廓连接具有相同高度的点一样),同时在修复区域的边界处匹配渐变矢量。为此,使用来自流体动力学的一些方法。获得颜色后,填充颜色以减少该区域的最小差异。使用标志 cv.INPAINT_NS 启用此算法。
实验详解:
这一次我们需要自己输入一张图片,通过鼠标在原图画布上通过涂白来提供要修复的点,最后通过使用该函数进行修复,最后与原图进行比较
1.导入需要的库
import numpy as np
import cv2
2. 建立一个画图板
class SKetcher:
def __init__(self, windowname , dests ,colors_func):
self.prev_pt = None
self.windowname = windowname
self.dests = dests#画布
self.colors_func = colors_func#描绘采用什么颜色
self.dirty = False
self.show()
cv2.setMouseCallback(self.windowname,self.on_mouse)#设置鼠标监听事件
def show(self):#展示描绘图和修复图区域
cv2.imshow(self.windowname,self.dests[0])
cv2.imshow(self.windowname+':mask:',self.dests[1])
def on_mouse(self,event,x,y,flags,param):#设置鼠标监听事件,通过点击来进行描线画图
pt = (x,y)
if event == cv2.EVENT_LBUTTONDOWN:#鼠标点击就会记录坐标
self.prev_pt = pt
elif event == cv2.EVENT_LBUTTONUP:
self.prev_pt = None
if self.prev_pt and flags & cv2.EVENT_FLAG_LBUTTON:
for dst, color in zip(self.dests , self.colors_func()):#每画一点就会进行展示,通过cv2.line画线方法
cv2.line(dst,self.prev_pt,pt,color,5)
self.dirty = True
self.prev_pt = pt
self.show()
3.main函数建立
def main():
img = cv2.imread(r'')#填入你所实验的图片,下面是一系列基本操作
img = cv2.resize(img,(512,512))
img_mask = img.copy()
inpaintMask = np.zeros(img.shape[:2],np.uint8)#设置mask
sketch = SKetcher('image',[img_mask,inpaintMask],lambda :((255,255,255),255))#对输入图和mask实时调用
while True:
ch = cv2.waitKey()
if ch == ord('q'):#按键q表示退出
break
if ch == ord('n'):#按键n表示修补展示,使用的修补算法是cv2.INPAINT_NS
res = cv2.inpaint(src = img_mask, inpaintMask = inpaintMask, inpaintRadius=3 , flags=cv2.INPAINT_NS)
cv2.imshow('output', res)
if ch == ord('r'):#按键r表示复原,可再重新画图修补
img_mask[:] = img
inpaintMask[:] = 0
sketch.show()
4.最后调用
if __name__ == '__main__':
main()
cv2.destroyWindow()
实验效果:
最后附上完整代码:
import numpy as np
import cv2
class SKetcher:
def __init__(self, windowname , dests ,colors_func):
self.prev_pt = None
self.windowname = windowname
self.dests = dests
self.colors_func = colors_func
self.dirty = False
self.show()
cv2.setMouseCallback(self.windowname,self.on_mouse)
def show(self):
cv2.imshow(self.windowname,self.dests[0])
cv2.imshow(self.windowname+':mask:',self.dests[1])
def on_mouse(self,event,x,y,flags,param):
pt = (x,y)
if event == cv2.EVENT_LBUTTONDOWN:
self.prev_pt = pt
elif event == cv2.EVENT_LBUTTONUP:
self.prev_pt = None
if self.prev_pt and flags & cv2.EVENT_FLAG_LBUTTON:
for dst, color in zip(self.dests , self.colors_func()):
cv2.line(dst,self.prev_pt,pt,color,5)
self.dirty = True
self.prev_pt = pt
self.show()
def main():
img = cv2.imread(r'')
img = cv2.resize(img,(512,512))
img_mask = img.copy()
inpaintMask = np.zeros(img.shape[:2],np.uint8)
sketch = SKetcher('image',[img_mask,inpaintMask],lambda :((255,255,255),255))
while True:
ch = cv2.waitKey()
if ch == ord('q'):
break
if ch == ord('n'):
res = cv2.inpaint(src = img_mask, inpaintMask = inpaintMask, inpaintRadius=3 , flags=cv2.INPAINT_NS)
cv2.imshow('output', res)
if ch == ord('r'):
img_mask[:] = img
inpaintMask[:] = 0
sketch.show()
if __name__ == '__main__':
main()
cv2.destroyWindow()
本次Opencv实验展示了计算摄影中的图片修复功能,官方文档请看OpenCV: OpenCV Tutorials
如有错误或遗漏,希望小伙伴批评指正!!!!
希望这篇博客对你有帮助!!!