欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

通过OpenCV库实现基于FMM的图像修复概述

程序员文章站 2022-05-28 14:23:14
...

概述

​ OpenCV库中的cv2.inpaint()中第一种Alexandru Telea的基于快速行进方法(Fast Marching Method, FMM)的图像修复技术(标志 cv.INPAINT_TELEA)是传统(早期)图像修复方法中,基于结构的图像修复中的基于插值的修复方法
通过OpenCV库实现基于FMM的图像修复概述


算法解析

​ FMM是计算水平集(level set)函数的快速数值算法

​ 它将修复区域边界不断动态更新,往内推进,推进的同时修复各个边界上的离散像素点,直至修复整个区域位置,即根据到边界距离的远近以此修复。

​ 已知像素点A,四相邻像素点B,C,E,F,修复其中的内部像素点后标记为边界Band

通过OpenCV库实现基于FMM的图像修复概述

参考文献
肖志云,张文霞,姜玉莉.基于快速行进法的快速图像修复算法[J].计算机应用,2007(S2):60-61+65.


修复效果

通过OpenCV库实现基于FMM的图像修复概述
通过OpenCV库实现基于FMM的图像修复概述

通过实际操作我们知道,以FMM(快速行进法)为例,对于早期图像修复算法而言,对于小范围的、像素差异较小的、语义不丰富的图像缺失区域修复效果较好,但对于大面积的、像素差异大的、语言丰富的图像缺失区域,尤其是建筑、人脸等,修复效果十分欠缺。


函数作用

cv2.inRange()

图像二值化( Image Binarization)

numpy.ones()

返回一个指定形状和数据类型的新数组,并且数组中的值都为1。

cv2.dilate()

膨胀待修复区域(白色区域)

cv2.inpaint()

提供两种算法进行图像修补

第一种算法基于Alexandru Telea在2004年发表的论文“基于快速行进方法(FMM)的图像修补技术”。它基于快速行进方法。考虑图像中要修复的区域。算法从该区域的边界开始,并进入该区域内部,首先逐渐填充边界中的所有内容。在要修复的邻域上的像素周围需要一个小的邻域。该像素被附近所有已知像素的归一化加权总和所代替。权重的选择很重要。那些位于该点附近,边界法线附近的像素和那些位于边界轮廓线上的像素将获得更大的权重。修复像素后,将使用快速行进方法将其移动到下一个最近的像素。FMM确保首先修复已知像素附近的那些像素,以便像手动启发式操作一样工作。通过使用标志cv.INPAINT_TELEA启用此算法。

第二种算法基于Bertalmio,Marcelo,Andrea L. Bertozzi和Guillermo Sapiro在2001年发表的论文“ Navier-Stokes,流体动力学以及图像和视频修补”。该算法基于流体动力学并利用了 偏微分方程。基本原理是启发式的。它首先沿着边缘从已知区域移动到未知区域(因为边缘是连续的)。它延续了等距线(线连接具有相同强度的点,就像轮廓线连接具有相同高程的点一样),同时在修复区域的边界匹配梯度矢量。为此,使用了一些流体动力学方法。获得它们后,将填充颜色以减少该区域的最小差异。通过使用标志cv.INPAINT_NS启用此算法。

cv2.waitKey()

无限地等待一个按键产生的事件

详情可查阅OpenCV中文官方文档 http://www.woshicver.com/


代码

基于Python,需要NumPy和OpenCV库

#coding=utf-8
#图片修复

import cv2
import numpy as np

path = "C:/Users/48383/desktop/test.jpg"

img = cv2.imread(path)
hight, width, depth = img.shape[0:3]

#图片二值化处理,把[240, 240, 240]~[255, 255, 255]以外的颜色变成0
thresh = cv2.inRange(img, np.array([240, 240, 240]), np.array([255, 255, 255]))

#创建形状和尺寸的结构元素
#kernel为一个5x5的,元素均为1,类型为uint8的矩阵
kernel = np.ones((5, 5), np.uint8)

#扩张待修复区域
hi_mask = cv2.dilate(thresh, kernel, iterations=1)
specular = cv2.inpaint(img, hi_mask, 5, flags=cv2.INPAINT_TELEA)

cv2.namedWindow("Image", 0)
cv2.resizeWindow("Image", int(width), int(hight))
cv2.imshow("Image", img)

cv2.namedWindow("thresh", 0)
cv2.resizeWindow("thresh", int(width), int(hight))
cv2.imshow("thresh", thresh)

cv2.namedWindow("mask", 0)
cv2.resizeWindow("mask", int(width), int(hight))
cv2.imshow("mask", hi_mask)

cv2.namedWindow("newImage", 0)
cv2.resizeWindow("newImage", int(width), int(hight))
cv2.imshow("newImage", specular)

cv2.waitKey(0)
cv2.destroyAllWindows()

代码来源
https://www.cnblogs.com/vipstone/p/9130688.html