这个东西是个非常古老的算法了,大概是2008年的东西,参考资料也有很多,不过基本上都是重复的。最近受一个朋友的需求,前后大概用了二十多天时间去研究,也有所成果,在这里简单的予以记录。

   图像修复这个东西目前流行的基本都是用深度学习来弄了,而且深度学习的效果还是非常不错的(大部分情况下优于传统算法)。

   PatchMatch本身并不是图像修复的算法,他只是描述了一套流程用于快速在两幅图之间找到近似的相似的块,主要包括随机初始化,然后传播,再随机搜索三个步骤,关于这部分描述可以直接看论文或者在百度上搜索PatchMatch,有一大堆相关的解释,我这里不想过多描述。

  关于这个论文,大家可以搜索文章: PatchMatch: A Randomized Correspondence Algorithm for Structural Image Editing

  而图像修复本身的过程除了PatchMatch外,还有很多其他的东西。一般情况下,这种应用场景都是客户手工指定一个区域,我们需要把这个区域的东西去掉并填充(不管原来这里是什么样子的,区域内部原有的信息完全不考虑),填充后的结果要和周边的环境自然的融为一体。关于这方面的步骤,论文里本身描述的不多,但是相关的代码可以在github上找到很多,我这里提供几个链接供大家参考:

  https://github.com/vacancy/PyPatchMatch

  https://github.com/liqing7/Inpaint/tree/master/Inpaint

  github里一堆这样的代码,但是翻来翻去其实都是一个娘生的,里面的实现方式大同小异,而且基本上都是基于opencv实现的,里面的代码呢也是绕来绕去,重实现,不重流程和效率。我的工程也是参考了这些东西,并且使用C++脱离opencv独立予以实现,因此工作量大了很多。

  我这里就我在提取并稍作优化这个算法的一些过程予以记录和描述,免得时间久了后自己都不太记得是怎么回事了。

  一、Inpaint的基本流程。

  1、用户标记的区域视为孔洞,里面没有任何的信息了,那要从现有的周边像素填充这个孔洞,采用的办法是,建立图像金字塔,在金字塔下采样的过程中,图像变小,孔洞也在变小,下采样就涉及到领域,当领域覆盖了孔洞边缘时,也必然有部分领域涉及到了孔洞周边的有效像素区域,此时以有效像素区域的信息加权填充缩小后的孔洞,这样不断的侵蚀,直到所有的孔洞在金字塔图像中都消失了,这个金字塔的层数就足够了(不管孔洞有多大,当金字塔在变为大小2像素、1像素的过程中孔洞肯定会消失)。

  2、由最小的金字塔层开始,目标和源都设置为相同值,然后随机初始化PatchMatch里的NNF场,接着使用传播和随机扩散最小化NNF的误差,这个时候就可以利用这个NNF来初步构建目标图像(是个迭代过程,叫做EM迭代)。

  3、在迭代的最后一步,做个上采样,并且做点精细化的工作(权重累加),然后到金字塔的上一层,在这一层时,初始的NNF就不要随机化了,而是可以有下一层的NNF通过最近邻插值获取,这样获取的数据比随机初始化的要更为接近理论的结果,就要就可以减少这一层的传播和随机扩散的迭代次数。

  4、就这样一层一层的往上处理,得到最终的结果。

  二、参考代码中一些细节

  1、删除不必要的过程

   我们贴一下论文里的一些描述先:

  In this section, we discuss some of the novel interactive editing tools enabled by our algorithm. First, however, we must revisit the bidirectional similarity synthesis approach [Simakov et al. 2008]. This method is based on a bidirectional distance measure between pairs of images - the source (input) image S and a target (output) image T. The measure consists of two terms: (1) The completeness term ensures that the output image contains as much
visual information from the input as possible and therefore is a good summary. (2) The coherence term ensures that the output is coherent w.r.t. the input and that new visual structures (artifacts) are penalized. Formally, the distance measure is defined simply as the sum of the average distance of all patches in S to their most similar (nearest-neighbor) patches in T and vice versa:

  

  where the distance D is the SSD (sum of squared differences) of patch pixel values in L*a*b* color space. For image retargeting, we wish to solve for the image T that minimizes dBDS under the constraints of the desired output dimensions. Given an initial guess for the output image, T0, this distance is iteratively minimized by an EM-like algorithm. In the E step of each iteration i, the NN- fields are computed from S and Ti and “patch-voting” is performed to accumulate the pixel colors of each overlapping neighbor patch. In the M step, all the color “votes” are averaged to generate a new image Ti+1. To avoid getting stuck in bad local minima, a multi-scale “gradual scaling” process is employed: T is initialized to a low-resolution copy of S and is gradually resized by a small factor, followed by a few EM iterations after each scaling, until the final dimensions are obtained. Then, both T and S are gradually upsampled to finer resolutions, followed by more EM iterations, until the final fine resolution is obtained.
  In addition to image retargeting, Simakov et al. [2008] showed that this method can be used for other synthesis tasks such as image collages, reshuffling, automatic cropping and the analogies of these in video. Furthermore, if we define a missing region (a “hole”) in an image as T and the rest of the image as S, and omit the completeness term, we end up with exactly the image and video completion algorithm of Wexler et al. [2007]. Importance weight maps can be used both in the input (e.g., for emphasizing an important region), and in the output (e.g., for guiding the completion process from the hole boundaries inwards).
  这里面就讲到了关于使用PatchMatch进行一些图像编辑(inpaint, reshuffling\cropping )等等的过程,也包括对EM迭代的一个讲解,不过我们注意到上面标红加粗的部分的描述,他讲的意思时如果进行图像的修复,就只需要关注前面的公式5中的coherent部分就可以了。
  不过我们仔细的观察所有的github上给出的代码,就可以看到都使用 m_source2target 和m_target2source 两个NNF,我们尝试了把m_source2target 这个NNF相关的所有内容都删除掉,完全不影响结果的,这样速度基本上可以提高一半的。
  当然,github上这些代码都是一个模板出来的,最开始的作者应该时考虑了其他reshuffling等等其他的操作吧,因为这些操作确实需要双向的数据。
  2、有问题的部分代码
   a、在代码中有一个init_kDistance2Similarity函数,其内容如下:
    void init_kDistance2Similarity() {
double base[11] = {1.0, 0.99, 0.96, 0.83, 0.38, 0.11, 0.02, 0.005, 0.0006, 0.0001, 0};
int length = (PatchDistanceMetric::kDistanceScale + 1);
kDistance2Similarity.resize(length);
for (int i = 0; i < length; ++i)
{
double t = (double) i / length;
int j = (int) (100 * t);
int k = j + 1;
double vj = (j < 11) ? base[j] : 0;
double vk = (k < 11) ? base[k] : 0;
kDistance2Similarity[i] = 1;// vj + (100 * t - j) * (vk - vj);
}
}

  这个函数的目的是根据两个块之间的距离来计算一个在[0,1]之间的相似权重。但是这个函数设计的不是很好,代码里块之间的距离是一个介于0和65535之间的数,这个权重也是个65536的表,但是问题是,这个表在后段大部分的值全为0,就表示他们毫无贡献了,这个可能造成的一个问题时图像出现莫名其妙的内容,而且如果遇到加权时的像素点权重都是0,这个点的计算就无效了。因此,需要适当的修改这个函数。

  b、在NNF的minimize过程中,特别是随机扩散的代码里,上面我给出的链接里用了两种不同的方法,

  其中一种是:

        

  另外一个是:  

  两者的不同是,一个在随机搜索的时候的中心点是经过传播后得到更优的点,一个就是原始的中心点, 我这边测试呢使用原始的中心点得到的图形的清晰度更高,不知道这个是个什么道理。

  3、一些其他的细节的理解

  a、在参考代码里,对于距离的计算,除了常规的欧式距离外,有些版本还加入了对于边缘的权重的考量,比如下面的代码:

   mptry[j] = (ptry1[j] / 2 - ptry2[j] / 2) + 128;
mptrx[j] = (ptrx1[j] / 2 - ptrx2[j] / 2) + 128;

  这是简单的计算水平和垂直方向的梯度,而且这个公式的设计让他们的值自然的位于0和255之间,这样就能起到和像素的RGB在同一个有效的值范围和空间内,使得他们的权重自然就相同了。

  b、对于块的大小,感觉大部分情况半径为2就比较合适,也就是计算5*5的领域,一般就能满足范围。

  c、在下采样时,这个函数还是比较关键,不太能用向双线性插值这种只涉及到2*2领域的算法,参考代码给出的时一个6*6的领域,为什么用偶数领域,这个是基于什么考虑呢(其实常用的图像缩放算法都是偶数范围内领域,双向性是2*2, 三次立方是4*4),我采用的是5*5的领域,感觉这样比较集中。

  d、参考代码里的下采样图的大小都是 SrcW / 2这种的,这种如果原图是51像素,则下一层就只有25个像素了,我个人感觉还是不合理,而是应该采用(SrcW + 1) / 2这种方式处理,而且我测试呢,如果采用SrcW / 2方式,对于图像宽度和高度是偶数的图,出来的结果就是模糊一些(这个东西和很多因素有关,但是我测试的环境确实有这个现象)。
  e、虽然作者说patchmatch很快就会收敛,但是毕竟他只是近似算法,不是完全的准确,因此,每次执行后的结果都不他一样,所以实用的还是需要多点几次看那次结果更为合适)。

  f、早期的photoshop里有一个智能填充,其实现方式和patchmatch也是类似的。

  三、实测的效果

  经过多个版本迭代,目前已经实现了一个简单的测试DEMO,这里选几个效果比较明显的看一下:

  对于没有强烈边界的区域,可以看出整体还是不错的,不够目前的效果还是有些模糊,当然也有一些不太成功的案例。

  目前我在美图秀秀和Photoshop中都有看到类似这样的功能,美图秀秀里有个智能抠图,应该是使用AI做的,大部分情况下都不错,不过对于刚才那个油菜花的图就有点失效了,如下图所示:

  不晓得是他的模型问题,还是这个AI本身就做不太好。

    我提供一个测试DMEO,有兴趣的朋友可以弄着玩:https://files.cnblogs.com/files/Imageshop/PatchMatch.rar?t=1724314207&download=true

  

  如果想时刻关注本人的最新文章,也可关注公众号:

翻译

搜索

复制

【工程应用十一】基于PatchMatch算法的图像修复研究(inpaint)。的更多相关文章

  1. 基于Otsu算法的图像自适应阈值切割

    在图像处理实践中,将灰度图转化为二值图是非经常见的一种预处理手段. 在Matlab中,能够使用函数BW = im2bw(I, level)来将一幅灰度图 I.转化为二值图. 当中.參数level是一个 ...

  2. 基于Bilateral Attention和Pyramid Filling Block的图像修复方法

    One-Stage Inpainting with Bilateral Attention and Pyramid Filling Block 论文链接:https://arxiv.org/abs/1 ...

  3. 基于Criminisi算法的栅格影像数据敏感地物隐藏

    栅格影像数据敏感地物伪装是指通过计算机智能识别与计算,将影像数据中的敏感地物进行识别与提取,将敏感地物智能替换成公共地物,如草地.森林.湖泊.公园等.但目前该技术并不成熟,同时栅格影像数据敏感地物伪装 ...

  4. 深度学习与计算机视觉(12)_tensorflow实现基于深度学习的图像补全

    深度学习与计算机视觉(12)_tensorflow实现基于深度学习的图像补全 原文地址:Image Completion with Deep Learning in TensorFlow by Bra ...

  5. 结构感知图像修复:ICCV2019论文解析

    结构感知图像修复:ICCV2019论文解析 StructureFlow: Image Inpainting via Structure-aware Appearance Flow 论文链接: http ...

  6. [OpenCV实战]34 使用OpenCV进行图像修复

    目录 1 什么是图像修复 1.1 INPAINT_NS : Navier-Stokes based Inpainting 1.2 INPAINT_TELEA : Fast Marching Metho ...

  7. 基于SURF特征的图像与视频拼接技术的研究和实现(一)

    基于SURF特征的图像与视频拼接技术的研究和实现(一)      一直有计划研究实时图像拼接,但是直到最近拜读西电2013年张亚娟的<基于SURF特征的图像与视频拼接技术的研究和实现>,条 ...

  8. 陕西中际现代:基于自适应算法的PLC滴灌控制系统

    基于自适应算法的PLC滴灌控制系统 陕西中际现代包装科技有限公司滴灌部 1.介绍 水资源正在成为一种珍贵的资源.城镇的市民使用成千上万立方的水来浇灌花园和绿地.他们依赖于使用固定灌溉计划的控制器.而这 ...

  9. OpenCV探索之路(十):图像修复技术

    在实际应用中,我们的图像常常会被噪声腐蚀,这些噪声或是镜头上的灰尘或水滴,或是旧照片的划痕,或者是图像遭到人为的涂画(比如马赛克)或者图像的部分本身已经损坏.如果我们想让这些受到破坏的额图片尽可能恢复 ...

  10. OpenCV学习2-----使用inpaint函数进行图像修复

    安装opencv时,在opencv的安装路径下, sources\samples\cpp\  路径里面提供了好多经典的例子,很值得学习. 这次的例子是利用inpaint函数进行图像修复. CV_EXP ...

随机推荐

  1. FEDORA34 安装CUDA11.3

    FEDORA34 安装CUDA11.3 首先确保能装上最新的显卡驱动.  FEDORA显卡驱动安装 然后去官网下fedora对应的.run安装文件.运行安装, 但不要选装驱动. 完成后加环境变量: # ...

  2. 全国产!全志A40i+Logos FPGA核心板(4核ARM Cortex-A7)硬件说明

    硬件资源 SOM-TLA40iF核心板板载ARM.FPGA.ROM.RAM.晶振.电源.LED等硬件资源,并通过B2B连接方式引出IO.核心板所有器件(包括B2B连接器)均采用国产工业级方案,国产化率 ...

  3. url编码方式

    url编码在线工具: http://tool.chinaz.com/tools/urlencode.aspx url编码:风景->%e9%a3%8e%e6%99%af 附HTTP请求过程: ht ...

  4. PaddleNLP UIE -- 药品说明书信息抽取(名称、规格、用法、用量)

    目录 创建项目 环境配置 上传代码 训练定制 代码结构 数据标注 准备语料库 数据标注 导出数据 数据转换 doccano Label Studio 模型微调 模型评估 定制模型--预测 效果 Pad ...

  5. ffmpeg -使用总结

    ffmpeg 使用总结,不定期更新 ---------------------------------------- 1. 将截图合成影片: ffmpeg -i ./shot/%d.tiff -thr ...

  6. yb课堂之个人信息接口开发 《十三》

    根据token从查询个人信息接口开发 直接解密token,获取个人信息 通过token解密查询数据库获取个人信息 UserController.java package net.ybclass.onl ...

  7. C# 语言笔记

    1. C# 初识 因为先前已经学过 C++ 了,所以在C# 的学习中,大多只记录和 C++ 不同的点,在学习的过程中,感谢刘铁猛老师的教程,您是我C# 入门的领路人. 1.1 使用 .net cli ...

  8. 解决方案 | vba批量冻结首行,所有sheet一次性设置

    Sub FreezeTopRowAllSheets() Dim ws As Worksheet ' 遍历所有工作表 For Each ws In ThisWorkbook.Worksheets ' 激 ...

  9. 解决阿里云redis监听6379,配置规则也将6379端口开放,但是外网仍无法连接6379的问题

    首先确保阿里云配置规则和服务器防火墙已开发6379端口 阿里云linux安装完成redis,并且已经运行,检测6379端口,显示redis-server正在监听,如图 修改redis.conf配置 将 ...

  10. Webpack3.x升级至 4.x 小记

    近期项目部署遇到点问题,需要升级webpack版本,特此整理一小记,记录升级过程中的依赖包及报错处理. 本次升级的依赖包及对应版本对照表: npm 包 当前版本 升级版本 S/D vue ^2.5.1 ...