基于MATLAB的图像去遮挡修复数字图像处理系统

您所在的位置:网站首页 马赛克数字怎么恢复 基于MATLAB的图像去遮挡修复数字图像处理系统

基于MATLAB的图像去遮挡修复数字图像处理系统

2023-09-18 07:16| 来源: 网络整理| 查看: 265

资源下载地址:https://download.csdn.net/download/sheziqiong/85639467

一、总述

本次设计要求将图片前景的黑色栏杆去除,恢复遮挡部分。要求修改的图片有两张,第一张图片的前景栏杆较窄,第二张图片的前景栏杆大部分较窄,有一根栏杆较粗。

​ (原图片一和图片二)

为了去除遮挡部分,首先需要找到遮挡部分的位置,即 mask,这一步使用一系列图像处理的方法来完成。

针对第一张图片,由于遮挡物较窄,我使用了 Fast Marching Method 算法来实现去遮挡,该算法运算较快,对窄遮挡物去除效果较好,但对宽遮挡物(宽度大于 15 像素)进行修复时会出现模糊现象(Telea, 2004)。因此,针对第二张图片的宽栏杆部分,我使用了 criminisi 算法来进行修复,该算法运算较慢,但对宽遮挡物修复效果极佳(Criminisi, Perez, &Toyama, 2003)。

此外,我对 criminisi 算法做了一点改动,大大提高了它的运算速度,同时保证修复质量。

为了便于可执行文件的使用,我制作简单的 UI 界面。

去遮挡算法难以用矩阵运算实现,只能使用 for 循环,因此运算速度整体较慢。为了减少运算时间,我缩小了图片尺寸。

二、提取遮挡物

为了去遮挡,首先需要得到遮挡物的位置,即 mask。为此我进行了一系列图像处理的操作。这一部分的算法可拓展性较差,只适用于这次作业的两张图片,且参数之间的依赖性较强。两张图片中的栏杆都是以直线的形式呈现,所以这一部分算法的基本思路是利用直线检测提取位置。

2.1 图片一中栏杆位置的提取

对应代码:get_mask/get_mask_1.m

首先将图片二值化并去除图片下方的黑色部分,避免对直线检测结果造成干扰。

​ (图片一二值化)

接下来,对二值化后的图片使用 Hough 变换,Hough 变换是把图像空域中的点转化到 ρ—θ 空间,使用如下公式:

ρ = xcosθ + ysinθ

其中 ρ 和 θ 表示极坐标中直线到原点的距离以及距离垂线的角度。因此,图像中的一个点对应 Hough 空间中的一条正弦曲线,而图像中的一条直线对应 Hough 空间中多条正弦曲线的交点。

使用 Hough 变换检测直线的另一个好处是可以知道直线的起止点,这对本例是十分有用的。Hough 变换检测到的直线如下图所示。

​ (Hough 变换检测直线)

Hough 变换得到的曲线中,有一些冗余的检测结果,也有一条直线没有检测到,因此我们需要做一些进一步的处理。

在 get_mask/lines_integrate.m 函数中,我首先将 ρ—θ 直线转换成 k—b 斜率截距型,方便后面的计算。再将重复的直线去掉,判断标准是两直线角度差以及距离。

处理之后,将直线按从上到下的顺序排列,并利用上下两条直线间的距离找到遗漏直线的位置,补上遗漏的直线。下面是补上遗漏直线后的处理结果:

​ (去掉重复直线并补上遗漏直线)

找到所有直线的位置后,下面就需要用这些直线填补出栏杆的 mask,这个 mask 是和原图一样大小的矩阵,在有栏杆的地方矩阵值为 1(或 255),在没有栏杆的地方矩阵值为 0.

get_mask/maskFromlines.m 函数是这一算法的实现,基本思路是遍历直线上每一列的像素点(竖线是遍历每一行),寻找这一点附近灰度值的局部最小值点,将这一最小值点附近一部分点(具体多少点由超参决定,其实就是栏杆的宽度)的 mask 设为 1。下面是得到的图片一中栏杆的 mask。

​ (图片一中栏杆的 mask)

2.2 图片二中栏杆位置的提取

对应代码:get_mask_2.m

图片二的处理比图片一的处理更复杂,但大体思路相同。

图片二中间有一条栏杆宽度很大,需要先将这根栏杆的位置找到并除去,方便后面直线检测的顺利进行。

首先依然是将图片二值化,去除下方的黑色干扰部分。

寻找宽栏杆时要利用宽栏杆中点附近黑点更多的特点,找到宽栏杆中若干点。具体操作时,我在图片中间隔相等的四行进行扫描,对每一个点,计算它附近一定大小的领域中黑点的数量,每一行中领域黑点数量最多的那个点应该就在宽栏杆内部。找到的宽栏杆内部四个点纵向均匀分布,从这个四个点分别向左向右出发,找到宽栏杆共八个边界点。

找到的四个内部点(红点)和八个边界点(黄点)如下图所示。

​ (宽栏杆边界点、内部点和边界线)

宽栏杆八个边界点中左右各有四个边界点,利用这些边界点可以拟合出宽栏杆的边界线,如上图绿线所示。

得到宽栏杆左右边界线后,就可以得到其左边区域和右边区域,并去除宽栏杆。

图片二中的直线有很多断裂部分,如果直接使用直线检测效果不佳,因此我先对其进行膨胀处理。如下图,直线的连接度高了许多。

​ (图片二的二值化、去除宽栏杆、膨胀处理结果)

之后就能使用图片一中类似的步骤来检测直线了,但是,由于图片二中宽栏杆左右部分直线的斜率不同,位置不同,所以需要分别进行处理。直线检测结果如下图所示。

​ (图片二中扁栏杆位置检测)

​ (图片二中的扁栏杆 mask 在原灰度图上的位置)

​ (图片二中的宽栏杆 mask 在原灰度图上的位置)

三、FFM 算法修复图片一

代码:FFM_inpaint 文件夹中 inpaint_FMM.m, nearest_interp.m, myMinheap.m, solve_T.m, compute_outside.m

Fast Marching Method 算法其实是一种插值方法,其特殊之处在于插值权重的确定以及最佳修复点的快速查找。

考虑下面图中的情况:区域 Ω 是图片需要修复的区域,Ω 是 Ω 的边缘.现在需要修复 p 点的像素值,我们用已知像素区域中 p 的一小片圆形领域( )中的像素做插值:

下面我们来介绍怎样计算权重w(p,q ),怎样快速找到最佳修复点以及算法流程。

算法实现中用到了F(i,j )和T(i,j)两个关键的矩阵,T(i,j)表示点(i,j) 到待修补区域边缘的距离。F(i,j )表示点(i,j)的性质,待修补区域中的点值为 2(内部点,未知点),待修补区域边界点值为 1,已知像素区域的点值为 0。这两个矩阵都会在代码运行过程中动态更新。

3.1 权重的计算

权重的计算综合考虑了各个方面,具体地,w(p,q ) = |dir(p,q)*𝑑𝑠𝑡(𝑝, 𝑞) ∗ 𝑙𝑒𝑣(𝑝, 𝑞)|。p 是需要修复的点,q 是其已知像素领域𝐵(𝜀)中的一个点。

其中,dir(p,q)保证沿着 N§向量方向的点有更大的权重,𝑁(𝑝) = ∇𝑇(𝑝𝑖 , 𝑝𝑗),即 T 矩阵在 p 处的梯度,实际表示 δΩ 在 p 点处指向 Ω 内部的垂线。p-q 表示 q 指向 p 的向量。

𝑑𝑠𝑡(𝑝, 𝑞)保证距离 p 近的点有更大的权重,||𝑝 − 𝑞||^2表示 p 到 q 距离的平方,d0 一般取 1。

𝑙𝑒𝑣(𝑝, 𝑞)保证距离待修复区域边缘(δΩ)近的点有更大的权重

3.2 快速查找最佳修复点

FFM 算法很重要的一个特点是快速查找最佳修复点,因为在修复图片的过程中,我们可以随意挑选一个边缘点,然后对它旁边的未知点进行修复,但这样的修复效果很差。例如修复下方左图中的中间白色区域,按中间图黑线所示的顺序进行修复效果差,因为内层的点原本是未知区域,其像素值是计算出来的,可信度差。但如果按右边图黑线所示顺序修复效果相对较好。

上述两种修复方式的区别在于,边缘点的选择方式,如果我们优先选择 T 矩阵值更小的边缘点,则能保证选择的边缘点可信度更高。

为了快速找到 T 矩阵值最小的边缘点,我们可以维护一个最小堆,提高运算速度。

T矩阵的计算其实是一个方程的解,我们下面会提到。

3.3 算法流程

算法的输入是一张 rgb 图片、mask 矩阵(需要修复的区域值大于0,以及修复半径,即圆形领域B(𝜀)的半径。

首先求出初始 F 矩阵,具体做法是将 mask 矩阵用进行膨胀得到 F’,将 F’大于 0 的部分置为 1, F_temp=F’-F 表示边缘点,则 F=2F’-F_temp,这样得到的 F 满足:待修补区域中的点值为 2(内部点,未知点),待修补区域边界点值为 1,已知像素区域的点值为 0。

然后初始化 T 矩阵,具体做法是先将内部点的 T 值置为很大的一个值(1e6),边缘点值为 0,然后计算部分外部点的 T 值。只计算部分外部点的 T 值的原因是修复过程中只用到待修复区域周围的一部分外部点。计算外部点的 T 值其实是将 F 中的 0 和 2 替换(即内部点和外部点替换),再用我们下面要介绍的流程进行。

T矩阵与 F 矩阵初始化成功后,我们先找到边缘点坐标以及它们的F矩阵值,放进最小堆 heap 里,就可以开始修复循环了。

下面是修复循环在论文中的伪代码,其中,NarrowBand 指待修复区域边缘点,简单来说就是每一轮从最小堆 heap 里提取出 T 值最小的边缘点 p,找到 p 上下左右的点中待修复的点,插值计算这个点的像素值,T 矩阵值,在 F 矩阵中将它设为边缘点,并把它放入最小堆 heap 中,循环直到没有边缘点为止。

​ (FFM 算法循环部分的伪代码)

3.4 修复结果

下面是图片一的修复结果,可以看出结果基本看不到栏杆的痕迹,且图片比较自然,看不出修复痕迹,而且图片其他部分不会受影响。

​ (用 FFM 算法修复图片一)

下面是使用 FFM 算法修复图片二的结果,可以看到中间的宽栏杆有一定程度的模糊,其他部分效果较好。

​ (用 FFM 算法修复图片二)

四、criminisi 算法修复图片二

criminisi 算法的本质是查找已知像素区域中的小方块补到未知部分,如下图所示,Ω 是待修复区域,φ是已知像素区域。修补 p 附件小块 Ψ 时,找到与之匹配度最高的小块 Ψq’,并将它补到 Ψp的位置。算法的关键是找到最高优先级的 p,再找到与之领域正方形小块 Ψp 匹配度最高的Ψq′。

4.1 修复优先级

我们在三.2 中已经阐述了修复顺序的重要性,criminisi 算法中也是如此, 考虑下图中的情况

定义边缘点 p 的优先级 P§,

P ( p ) = C ( p ) ∗ D ( p ) P(p) = C(p)*D(p) P(p)=C(p)∗D(p)

C§表示 p 点附近已知像素区域部分的比重,D§表示 p 点图片像素值梯度的垂线与待修复区域边缘线单位垂线 n p n_p np​的内积大小。α一般取255。

计算出所有边缘点的优先级后,挑出优先级最高的边缘点进行修复。

4.2 寻找最佳匹配

挑出优先级最高的边缘点 p 后,要对 p 的正方形领域 Ψp 进行修复,需要在全图范围内找到与之匹配度最高的小块 Ψq′,具体方法是求出图片中每个正方形块 Ψq 与 Ψp 的已知部分的像素值差的平方和,二者相差最小的块即为 Ψq′。

注意这里的像素值差是指在 LAP 空间中的像素值差,因为 LAP 空间更能体现图片的纹理结构。因此,需要在初始化时将 rgb 图片转换得到LAP 图片。

4.3 算法流程

算法的输入是一张 rgb 图片、mask 矩阵(需要修复的区域值大于0),以及修复块半径,即正方形修补块的边长。

算法的具体流程也很清楚:

先求出图片像素值梯度的垂线(这里的像素值指在 rgb 空间中的值),做一些初始化。

进入算法循环,先根据当前的 mask 求出边缘点,再循环求出每个边缘点的 C 值,求出所有边缘点的 D 值,用 C 和 D 数组求出优先级 P,挑出优先级最高的边缘点 p。找到边缘点 p 领域 Ψp 的最佳匹配 Ψq′,复制 Ψq′的 rgb 值、lap 值;更新 C(使 Ψp 中未知像素点的 C 值都等于 p 点 C 值);更新 mask(Ψp 中点的 mask 都设为 0,即已知点)。

循环(2)中流程,直到没有未知点为止。

4.4 结果

下图是用 criminisi 算法修复图片二的结果,为了减少运算时间,图片缩的比较小,可以看出宽栏杆部分的修复效果比用 FFM 算法修复的效果好一些,没有出现模糊,但还是有待改进。

​ (用 criminisi 算法修复图片二)

具体运行算法过程中,其实是先用 FFM 算法进行修复,再用 criminisi 算修复宽栏杆部分。

UI 界面

资源下载地址:https://download.csdn.net/download/sheziqiong/85639467



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3