温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

OpenCV中的图像修复代码分享

发布时间:2021-08-10 20:24:46 来源:亿速云 阅读:245 作者:chen 栏目:开发技术

这篇文章主要讲解了“OpenCV中的图像修复代码分享”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“OpenCV中的图像修复代码分享”吧!

目录
  • 1. 效果图

  • 2. 原理

  • 3. 源码

这篇博客将介绍如何通过OpenCV中图像修复的技术——cv2.inpaint() 去除旧照片中的小噪音、笔划等。并提供一个可交互式的程序,利用OpenCV的快速行进和流体力学俩种修复算法对自己的图片进行修复。

大多数人家里都会有一些旧的老化照片,上面有一些黑点、笔划等。如何复原呢?


在绘制工具中擦除:将简单地用无用的白色结构替换黑色结构,效果并不理想。OpenCV中图像修复的技术——基本思想很简单:用相邻像素替换这些坏标记,使其看起来像邻居。

  • cv2.INPAINT_TELEA(Fast Marching Method 快速行进算法)

  • cv2.INPAINT_NS(Fluid Dynamics Method 流体力学算法)

  • OpenCV未实现的:Content-Aware Fill 内容感知填充算法,这是Adobe Photoshop中使用的一种高级修复技术。

cv2.inpaint() 优点:修复效果更加自然;
缺点:修复时需要提供原图以及mask图(与原图一致只有被污染的像素区域有值);

1. 效果图

官方原始图 VS mask图 VS 快速行进算法修复效果 VS 流体力学修复效果 如下:

OpenCV中的图像修复代码分享

接下来用可交互的例子实现自己的图片修复;

原始图 VS Mask图 VS 快速行进算法修复效果图如下:
原始图随意用鼠标左键移动绘制点、线,右键移动绘制矩形来随机增加一些被污染的区域;
并根据原始图生成mask图,mask图是与原始图具有相同大小,并且只有被污染的区域是白色像素的图。可以看到修复效果还是挺好的~

OpenCV中的图像修复代码分享

原始图 VS Mask图 VS 流体力学算法修复效果图如下:
原始图随意用鼠标左键移动绘制点、线,右键移动绘制矩形来随机增加一些被污染的区域;
mask图是与原始图具有相同大小,并且只有被污染的区域是白色像素的图。可以看到修复效果还是挺好的~

OpenCV中的图像修复代码分享

快速行进算法与流体力学算法修复的效果图差别不太大;

2. 原理

  • cv2.INPAINT_TELEA (Fast Marching Method 快速行进算法),对位于点附近、边界法线附近和边界轮廓上的像素赋予更多权重。一旦一个像素被修复,它将使用快速行进的方法移动到下一个最近的像素。

  • cv2.INPAINT_NS(Fluid Dynamics Method 流体力学算法),使用了流体力学的一些方法,基本原则是启发式的。首先沿着边从已知区域移动到未知区域(因为边是连续的)。它在匹配修复区域边界处的渐变向量的同时,继续等高线(连接具有相同强度的点的线,就像等高线连接具有相同高程的点一样)。

  • OpenCV未实现的:Content-Aware Fill 内容感知填充算法,这是Adobe Photoshop中使用的一种高级修复技术。

3. 源码

# 图像修复交互式案例——通过水流填充算法来修复被破坏的图像区域; # 使用俩种方法进行修复 # cv2.INPAINT_TELEA (Fast Marching Method 快速行进算法),对位于点附近、边界法线附近和边界轮廓上的像素赋予更多权重。一旦一个像素被修复,它将使用快速行进的方法移动到下一个最近的像素。 # cv2.INPAINT_NS 流体力学算法,使用了流体力学的一些方法,基本原则是启发式的,首先沿着边从已知区域移动到未知区域(因为边是连续的)。它在匹配修复区域边界处的渐变向量的同时,继续等高线(连接具有相同强度的点的线,就像等高线连接具有相同高程的点一样)。 # USAGE  # python inpaint.py D:/deepLearning/py-demo/20210808/images/ml.jpg # 按下鼠标左键,添加点、线,按下鼠标右键,添加矩形框,以制作被污染的需要修复图像 # 按下空格键:执行修复功能 # 按下r键:重置待修复的mask # 按下esc键,退出 import cv2 import numpy as np class Sketcher:     def __init__(self, windowname, dests, colors_func):         self.prev_pt = None  # 线起始点         self.drag_start = None  # 矩形起点         self.drag_rect = None  # 矩形(左上角,右下角)坐标         self.windowname = windowname         self.dests = dests         self.colors_func = colors_func         self.dirty = False         self.drawing = False         self.mode = False         self.show()         cv2.setMouseCallback(self.windowname, self.on_mouse)     def show(self):         cv2.imshow(self.windowname, self.dests[0])     def on_mouse(self, event, x, y, flags, param):         pt = (x, y)         if event == cv2.EVENT_LBUTTONDOWN:             self.prev_pt = pt             self.drawing = True         elif event == cv2.EVENT_RBUTTONDOWN:             # 第一次初始化时设定pt,往后保留上一个点作为矩形起点             if self.drag_start == None:                 self.drag_start = pt         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()         if self.drag_start and flags & cv2.EVENT_FLAG_RBUTTON:             xo, yo = self.drag_start             x0, y0 = np.minimum([xo, yo], [x, y])             x1, y1 = np.maximum([xo, yo], [x, y])             self.drag_rect = None             if x1 - x0 > 0 and y1 - y0 > 0:                 self.drag_rect = (x0, y0, x1, y1)                 for dst, color in zip(self.dests, self.colors_func()):                     cv2.rectangle(dst, (x0, y0), (x1, y1), color, -1)                 self.dirty = True                 self.drag_start = None                 self.drag_rect = None                 self.show()             else:                 self.drag_start = pt     @property     def dragging(self):         return self.drag_rect is not None def main():     import sys     try:         fn = sys.argv[1]     except:         fn = 'images/ml_.jpg'     img = cv2.imread(fn)     if img is None:         print('Failed to load image file:', fn)         sys.exit(1)     img_mark = img.copy()     mark = np.zeros(img.shape[:2], np.uint8)     sketch = Sketcher('img', [img_mark, mark], lambda: ((255, 255, 255), 255))     while True:         ch = cv2.waitKey()         if ch == 27:             break         if ch == ord(' '):             cv2.imshow('mask', mark)             fmmres = cv2.inpaint(img_mark, mark, 3, cv2.INPAINT_TELEA)             nsres = cv2.inpaint(img_mark, mark, 3, cv2.INPAINT_NS)             cv2.imshow('inpaint fmm res', fmmres)             cv2.imshow('inpaint ns res', nsres)         if ch == ord('r'):             img_mark[:] = img             mark[:] = 0             sketch.show()     print('Done') if __name__ == '__main__':     main()     cv2.destroyAllWindows()

感谢各位的阅读,以上就是“OpenCV中的图像修复代码分享”的内容了,经过本文的学习后,相信大家对OpenCV中的图像修复代码分享这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI