基于等照度线和窗口匹配的图像修补算法

简介: 基于等照度线和窗口匹配的图像修补算法

一、关于图像修补

      图像修补的目的是基于已有的图像信息或数据库内信息,对缺失区域进行合理地修复。在诸多领域如电影、摄像、医疗等行业,有广泛的应用。


      传统上,图像修补由专业的修复师进行,修复师凭借自身丰富的工作经验和生活阅历,不仅能基于客观信息对图像缺失进行填充,更能进行主观创作,使得二次修复的图片更加生动形象。


      但在日益智能化的今天,针对数字图像的修补工作逐渐由人工转向了自动化,这不仅节省了大量人工成本,而且计算机凭借优越的算法和庞大的数据库,对图像的修复效果更高效且优质。通过近几个月风风火火的chatGPT,相信大家也看到了AI的魅力,这是未来的大趋势不可逆。


      针对图像修补,本文提出了一种基于等照度线和窗口匹配的图像修补算法,接下来将简单介绍下算法原理和流程,并展示相关的效果图。

二、算法原理和流程

      对图像缺失部分进行填充,首先要确定填充哪些内容,谁优先填充谁最后填充;其次要判断用什么数据来填充,能使得填充后的结果更贴近真实,显得不违和。做到了这两点,图像修补工作基本就完成了。

2.1 优先级计算

      我们先来讨论填充的优先级,如下图所示,图像白色部分是手动绘制的掩膜区域,该区域的真实信息被擦除了,我们现在要对其进行复原。

      在图中红线部分就是等照线,该线的两侧往往有较大的数值差异,因此它也与黑线所示的梯度线呈垂直关系;当等照线与掩膜边界呈垂直时,此时等照线上的像素点特征是非常强烈且明显的,通俗的讲,被填充的点极大可能和它那条等照线上的点类似,沿着这个等照线绘制下去,就可以了。

      那我们怎么判断当前点是不是处于与掩膜边界垂直的等照线上呢?可以通过掩膜边界(黑线)的法线和红色等照度线这两个向量判断。等照线与掩膜边界垂直时,那与掩膜边界的法线自然平行,此时两个向量点乘可以使得值最大,因此该值可以作为填补优先级评判的指标,定义为D(x,y)。

      除此之外,我们还需要用到一个指标,叫可信度,定义为C(x,y),就是被填补像素所在窗口内,源数据的占比,加入窗口为7*7的尺寸,里面有31个源数据,18个代填补数据,那它的可信度也就是31/49。可信度越高的像素,说明窗口内缺失的数据越少,对它们填补更容易且贴实。


      综上,代填补像素的优先级可以定义为P(x,y)=C(x,y)*D(x,y),当然也可以定义为别的,比如乘法变加法等等,大家可以自行发挥。

2.2 数据填充

      确认好代填补像素的优先级后,我们对优先级最高的像素所在窗口进行填充,填充基于窗口匹配实现。

      窗口匹配顾名思义就是从全图中寻找一个最像要填补的窗口的源数据窗口,把它粘过去即可。如下图所示,黑色窗口的实心部分是代填补窗口中的源数据,空心部分是代填补的数据。我们将黑色窗口实心部分和红色窗口实心部分进行三通道数据减法,对差值平方和累加取平均,可以得到一个匹配误差matchError,寻找全图最小的误差作为最小误差minError,此时对应的红色窗口就是匹配好的源数据。

      但是,当出现两个同样的匹配误差后该怎么取舍呢?这时需要用到第二个匹配的指标——最小窗内方差minVarience。即对源数据中空心部分三通道数值求方差,数值减去平均值后平方和累加。方差低则说明数据平稳,不容易出现异常突兀的噪声数据,这样可以让填补的数据更贴实。

2.3 算法流程图

      综上,该算法的流程图可简化为:


三、填补效果图

3.1 干涉条纹图填补视频

      该案例特征是图像黑白色系相对稳定,近似区域多,因此修补效果也是最好的。

1697720696832.png

图像修补算法示例视频1

3.2 地图填补视频

      该案例特征是图像分为极大区域,如海洋、雪山、陆地、森林,色系复杂,图像细节多且杂。对其修补效果也是相对好的,因为本身糅杂的颜色系统中适当混入一些不和谐因素,凭借肉眼较难准确识别。

1697720653579.png

图像修补算法示例视频2

3.3 花卉修补

     该案例特征是图像色彩相对单调,花瓣区域纹理明显。这类图像色彩简单又不简单,颜色相近又各有区分,修补难度极大。经过图像修补后,可以发现花的边缘修补较成功,但是肉眼还是能看出内部区间存在一定的修补痕迹。

3.4 房屋修补

     该案例特征是房屋颜色与天空接近,此时填补区域如果是屋顶瓦砖,便补的很好,因为纹理缘故,匹配的数据也是瓦砖。


      但如果填补区域是屋顶侧面,则易出问题,若天空是蓝色还好,但恰巧天空也是棕黄色系,所以填补痕迹就突出了。


      该案例也是很不好找,特地找出来做评估。感兴趣的伙伴可以优化窗口匹配函数,比如全局和局部结合匹配等等。

四、代码分享

main.cpp

#include "Inpaint.h"
// 全局变量
int thickness = 5;
cv::Point sPoint(-1, -1);
cv::Mat image, mask;
// 鼠标事件
static void onMouse(int event, int x, int y, int flags, void*){
  if (event == cv::EVENT_LBUTTONUP || !(flags & cv::EVENT_FLAG_LBUTTON))
    sPoint = cv::Point(-1, -1);
  else if (event == cv::EVENT_LBUTTONDOWN)
    sPoint = cv::Point(x, y);
    else if( event == cv::EVENT_MOUSEMOVE && (flags & cv::EVENT_FLAG_LBUTTON)){
        cv::Point ePoint(x,y);
        if( sPoint.x < 0 )
            sPoint = ePoint;
        cv::line( mask, sPoint, ePoint, cv::Scalar::all(255), thickness);
        cv::line( image, sPoint, ePoint, cv::Scalar::all(255), thickness);
        sPoint = ePoint;
    cv::imshow("image", image);
    }
}
// 主函数
int main(){
  cv::Mat originalImage = cv::imread("6.jpg", 1);
  // 无输入图像
    if(!originalImage.data){
    cout << "Error unable to open input image" << endl;
        return 0;
    }
  // 拷贝图像
    image=originalImage.clone();
  mask = cv::Mat::zeros(image.size(), CV_8U);
  // 设置鼠标事件
  cv::namedWindow("image", 1);
  cv::imshow("image", image);
  cv::setMouseCallback("image", onMouse, 0);
  // 循环处理
  while(true){
    // 键盘事件
    char key = (char)cv::waitKey();
    // 按'b'跳出循环,结束程序
    if (key == 'b')
      break;
    // 按'r'恢复原始图像
    if (key == 'r'){
      mask = cv::Scalar::all(0);
      image = originalImage.clone();
      cv::imshow("image", image);
    }
    // 按'空格'执行算法
    if (key == ' '){
      int r = 3;
      InpaintAlgorithm *m_algorithm = new InpaintAlgorithm(image, mask, 2 * r + 1, TEMPLATE_MATCHING);
      m_algorithm->executeInpaint();
      cv::namedWindow("result");
      cv::imshow("result", m_algorithm->m_outputImage);
    }
    // 按'w'增加画笔厚度
    if (key == 'w') {
      thickness++;
      if (thickness > 20)
        thickness = 20;
      cout << "Thickness = " << thickness << endl;
    }
    // 按's'减少画笔厚度
    if (key == 's') {
      thickness--;
      if (thickness < 1)
        thickness = 1;
      cout << "Thickness = " << thickness << endl;
    }
  }
    return 0;
}

Inpaint.h

#ifndef INPAINT_H
#define INPAINT_H
#include <iostream>
#include "opencv2/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/photo/photo.hpp"
using namespace std;
using namespace cv;
// 填补策略
enum INPAINT_METHOD {
  TEMPLATE_MATCHING,                              // 模板匹配
};
// 错误类型
enum ERROR_TYPE {
  ERROR_TYPE_OK,                                  // OK
  ERROR_TYPE_INPUT,               // 输入图像异常
  ERROR_TYPE_MASK,                // 掩膜异常
  ERROR_TYPE_WINDOWSIZE,              // 窗尺寸异常
};
// 定义图像填补接口
class Inpaint
{
public:
  // 构造函数
  Inpaint(cv::Mat inputImage, cv::Mat mask, int windowSize);
  // 检查异常
  void checkError();
  // 执行
  virtual void execute() = 0;
public:
  ERROR_TYPE errorType;                           // 错误码
  int m_windowSize = 9;                           // 窗尺寸
  cv::Mat m_inputImage;             // 输入图像
  cv::Mat m_mask;                 // 掩膜
  cv::Mat m_outputImage;              // 输出图像
};
// 实现具体策略-模板匹配
class TemplateMatching :public Inpaint
{
public:
  // 构造函数
  TemplateMatching(cv::Mat inputImage, cv::Mat mask, int windowSize);
  // 执行
  virtual void execute();
private:
  // 初始化
  void init();
  // 检查是否存在未填补信息
  bool checkUnfilled();
  // 寻找目标位置集合
  void findTargetPoints();
  // 计算可信度
  void calcConfidence();
  // 获取优先级
  void getPriority();
  // 寻找最佳匹配
  void findBestMatch();
  // 更新图像
  void updateImage();
private:
  int targetIndex;                 // 目标点序号
  cv::Point2i m_bestMatchUL;             // 最佳匹配点左上角位置
  cv::Mat m_updatedImage;                        // 更新中的图像
  cv::Mat m_updatedMask;               // 更新中的掩膜
  cv::Mat m_confidence;              // 可信度
  cv::Mat m_oriSourceRegion;             // 原始源位置
  cv::Mat m_sourceRegion;              // 源位置
  cv::Mat m_targetRegion;              // 目标位置
  cv::Mat m_gradientX;               // 梯度X
  cv::Mat m_gradientY;               // 梯度Y
  vector<cv::Point2i> targetPoints;        // 目标位置点集合
  vector<pair<float, float>> normals;            // 法线集合
};
// 应用类-图像修补算法调用
class InpaintAlgorithm
{
public:
  // 构造函数
  InpaintAlgorithm(cv::Mat inputImage, cv::Mat mask, int windowSize, INPAINT_METHOD method);
  // 析构函数
  ~InpaintAlgorithm();
  // 设置修补策略
  void setInpaintAlgorithm(INPAINT_METHOD method);
  // 执行图像修补
  void executeInpaint();
public:
  int m_windowSize;                // 窗尺寸
  cv::Mat m_inputImage;              // 输入图像
  cv::Mat m_mask;                  // 掩膜
  cv::Mat m_outputImage;                         // 输出图像
private:
  Inpaint* m_inpaint;                // 图像填补类实例
};
#endif

      C++完整代码不免费分享,有意获取者可以私我。算法不是魔法,不能解决一切问题。该算法的核心逻辑可用于工程开发,但仍有许多需要结合实际完善的地方,不建议直接拷贝使用。

      注意:当缺失的面积过大或者没有近似的窗口源数据时,填补效果会相对失真,这也是合理的。

相关文章
|
2月前
|
机器学习/深度学习 人工智能 自然语言处理
【MM2024】阿里云 PAI 团队图像编辑算法论文入选 MM2024
阿里云人工智能平台 PAI 团队发表的图像编辑算法论文在 MM2024 上正式亮相发表。ACM MM(ACM国际多媒体会议)是国际多媒体领域的顶级会议,旨在为研究人员、工程师和行业专家提供一个交流平台,以展示在多媒体领域的最新研究成果、技术进展和应用案例。其主题涵盖了图像处理、视频分析、音频处理、社交媒体和多媒体系统等广泛领域。此次入选标志着阿里云人工智能平台 PAI 在图像编辑算法方面的研究获得了学术界的充分认可。
【MM2024】阿里云 PAI 团队图像编辑算法论文入选 MM2024
|
2月前
|
机器学习/深度学习 人工智能 算法
【MM2024】面向 StableDiffusion 的多目标图像编辑算法 VICTORIA
阿里云人工智能平台 PAI 团队与华南理工大学合作在国际多媒体顶级会议 ACM MM2024 上发表 VICTORIA 算法,这是一种面向 StableDiffusion 的多目标图像编辑算法。VICTORIA 通过文本依存关系来修正图像编辑过程中的交叉注意力图,从而确保关系对象的一致性,支持用户通过修改描述性提示一次性编辑多个目标。
|
2月前
|
算法 数据安全/隐私保护
织物图像的配准和拼接算法的MATLAB仿真,对比SIFT,SURF以及KAZE
本项目展示了织物瑕疵检测中的图像拼接技术,使用SIFT、SURF和KAZE三种算法。通过MATLAB2022a实现图像匹配、配准和拼接,最终检测并分类织物瑕疵。SIFT算法在不同尺度和旋转下保持不变性;SURF算法提高速度并保持鲁棒性;KAZE算法使用非线性扩散滤波器构建尺度空间,提供更先进的特征描述。展示视频无水印,代码含注释及操作步骤。
|
3月前
|
算法 数据可视化 数据安全/隐私保护
基于LK光流提取算法的图像序列晃动程度计算matlab仿真
该算法基于Lucas-Kanade光流方法,用于计算图像序列的晃动程度。通过计算相邻帧间的光流场并定义晃动程度指标(如RMS),可量化图像晃动。此版本适用于Matlab 2022a,提供详细中文注释与操作视频。完整代码无水印。
|
5月前
|
机器学习/深度学习 编解码 监控
算法金 | 深度学习图像增强方法总结
**图像增强技术概括** 图像增强聚焦于提升视觉效果和细节,广泛应用于医学、遥感等领域。空间域增强包括直方图均衡化(增强对比度)、对比度拉伸、灰度变换、平滑滤波(均值、中值)和锐化滤波(拉普拉斯、高通)。频率域增强利用傅里叶变换、小波变换,通过高频和低频滤波增强图像特征。现代方法涉及超分辨率重建、深度学习去噪(如CNN、Autoencoder)、图像修复(如GAN)和GANs驱动的多种图像处理任务。
174 14
算法金 | 深度学习图像增强方法总结
|
5月前
|
机器学习/深度学习 人工智能 自然语言处理
|
5月前
|
算法
基于粒子群优化的图像融合算法matlab仿真
这是一个基于粒子群优化(PSO)的图像融合算法,旨在将彩色模糊图像与清晰灰度图像融合成彩色清晰图像。在MATLAB2022a中测试,算法通过PSO求解最优融合权值参数,经过多次迭代更新粒子速度和位置,以优化融合效果。核心代码展示了PSO的迭代过程及融合策略。最终,使用加权平均法融合图像,其中权重由PSO计算得出。该算法体现了PSO在图像融合领域的高效性和融合质量。
|
4月前
|
算法 前端开发 计算机视觉
基于均值坐标(Mean-Value Coordinates)的图像融合算法的优化实现
基于均值坐标(Mean-Value Coordinates)的图像融合算法的优化实现
48 0
|
4月前
|
自然语言处理 并行计算 算法
基于均值坐标(Mean-Value Coordinates)的图像融合算法的具体实现
基于均值坐标(Mean-Value Coordinates)的图像融合算法的具体实现
48 0
|
6月前
|
机器学习/深度学习 人工智能 算法
【CVPR2024】面向StableDiffusion的编辑算法FreePromptEditing,提升图像编辑效果
近日,阿里云人工智能平台PAI与华南理工大学贾奎教授团队合作在深度学习顶级会议 CVPR2024 上发表 FPE(Free-Prompt-Editing) 算法,这是一种面向StableDiffusion的图像编辑算法。在这篇论文中,StableDiffusion可用于实现图像编辑的本质被挖掘,解释证明了基于StableDiffusion编辑的算法本质,并基于此设计了新的图像编辑算法,大幅度提升了图像编辑的效率。