• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    OpenCV图像修复cv2.inpaint()的使用

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

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


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

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

    1. 效果图

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


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

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

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

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

    2. 原理

    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()
    

    参考 https://docs.opencv.org/3.0-beta/doc/py_tutorials/py_photo/py_inpainting/py_inpainting.html#inpainting

    到此这篇关于OpenCV图像修复cv2.inpaint()的使用的文章就介绍到这了,更多相关OpenCV图像修复cv2.inpaint()内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

    您可能感兴趣的文章:
    • python 用opencv实现图像修复和图像金字塔
    • OpenCV中图像通道操作的深入讲解
    • Python深度学习pytorch实现图像分类数据集
    • Python实现对照片中的人脸进行颜值预测
    • Python实现老照片修复之上色小技巧
    上一篇:python用dataframe将csv中的0值数据转化为nan缺失值字样
    下一篇:教你使用Python建立任意层数的深度神经网络
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    OpenCV图像修复cv2.inpaint()的使用 OpenCV,图像,修复,cv2.inpaint,